Getting TreeView to postback when node is checked/unchecked

Last post 09-25-2009 1:10 PM by phammk. 13 replies.

Sort Posts:

  • Getting TreeView to postback when node is checked/unchecked

    07-22-2004, 4:21 PM
    • Member
      30 point Member
    • sentha
    • Member since 07-22-2004, 4:15 PM
    • Posts 6
    Hi,

    How can I get TreeView to postback whenever a node with a checkbox is checked/unchecked?
    With the IE webcontrols, I could do this with the AutoPostBack property. With the Whidbey TreeView, I don't see a similar property.

    Thanks,
    Sentha Sivabalan
  • Re: Getting TreeView to postback when node is checked/unchecked

    07-22-2004, 5:58 PM
    • All-Star
      29,644 point All-Star
    • Fredrik N
    • Member since 06-22-2002, 5:03 AM
    • Sweden
    • Posts 5,334
    • TrustedFriends-MVPs
    You can't do that. It's the TreeNode class that will create the Checkbox (It's the TreeNode's Render method that will create it), the TreeNode will not add an OnClick event on the checkbox. The TreeView will internally create a TreeNode class for each node that should be added. The TreeNode class represents the node in a TreeView.
    /Fredrik Normén - fredrikn @ twitter

    ASPInsider

    Microsoft MVP, MCSD, MCAD, MCT

    ASPInsiders
    My Blog
  • Re: Getting TreeView to postback when node is checked/unchecked

    07-23-2004, 11:04 AM
    • Contributor
      2,210 point Contributor
    • jdixon
    • Member since 06-24-2002, 8:41 AM
    • Redmond
    • Posts 438
    • AspNetTeam
    Actually you can:


    <%@ Page Language="C#" %>
    <script>
    function foo()
    {
    var o = window.event.srcElement;
    if (o.tagName == "INPUT" && o.type == "checkbox")
    {
    __doPostBack("","");
    }
    }
    </script>

    <html>
    <head runat="server">

    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    <asp:TreeView onclick="foo()" ID="TreeView1" Runat="server" ExpandDepth="0" EnableClientScript="False">
    <Nodes>
    <asp:TreeNode ShowCheckBox="True" Value="New Node" Text="New Node">
    <asp:TreeNode Value="New Node" Text="New Node">
    </asp:TreeNode>
    </asp:TreeNode>
    </Nodes>
    </asp:TreeView>
    </div>
    </form>
    </body>
    </html>

    This posting is provided "AS IS" with no warranties, and confers no rights.
    We Are Hiring
  • Re: Getting TreeView to postback when node is checked/unchecked

    07-23-2004, 11:22 AM
    • All-Star
      29,644 point All-Star
    • Fredrik N
    • Member since 06-22-2002, 5:03 AM
    • Sweden
    • Posts 5,334
    • TrustedFriends-MVPs
    That was an ugly solution ;) , but it would work as long as you don't have several checkboxes. If we do have more checkboxes we need to use more checks to only do the postback when the CheckBoxes in the tree is checked or not.


    /Fredrik Normén - fredrikn @ twitter

    ASPInsider

    Microsoft MVP, MCSD, MCAD, MCT

    ASPInsiders
    My Blog
  • Re: Getting TreeView to postback when node is checked/unchecked

    07-23-2004, 12:04 PM
    • Contributor
      2,210 point Contributor
    • jdixon
    • Member since 06-24-2002, 8:41 AM
    • Redmond
    • Posts 438
    • AspNetTeam
    I never claimed it was pretty :-P

    I found this was useful for recursive checking of child checkboxes of a parent node that was checked, only way I could figure out how to do it - very hacky as you mention...
    This posting is provided "AS IS" with no warranties, and confers no rights.
    We Are Hiring
  • Re: Getting TreeView to postback when node is checked/unchecked

    07-23-2004, 2:37 PM
    • Member
      30 point Member
    • sentha
    • Member since 07-22-2004, 4:15 PM
    • Posts 6
    Thank you both for the suggestions!

    This would be useful if I can figure out how to do this programmatically from a server control.

    I have a server control inheriting from TreeView. I want to enable postbacks on it when checked. I can render the javascript function, etc., but I can't figure out a way to set the "onclick" event to the javascript function.

    I'd appreciate any suggestions.

    Thanks,
    Sentha
  • Re: Getting TreeView to postback when node is checked/unchecked

    07-23-2004, 4:46 PM
    • Member
      30 point Member
    • sentha
    • Member since 07-22-2004, 4:15 PM
    • Posts 6
    This works!! Thanks!!!

    I'm writing a control that inherits from TreeView. I can set the "onclick" attribute of the control to the name of a javascript function that I render like this:
    Attributes["onclick"] = "javascript:postbackOnCheck(event)";

    My javascript function reads like this for netscape interoperability:
    function postbackOnCheck(e)
    {
    var isNav = (window.navigator.appName.toLowerCase().indexOf("netscape")>=0);
    var o;
    if (isNav && e != null)
    o = e.target;
    else
    o = window.event.srcElement;
    if (o.tagName == 'INPUT' && o.type == 'checkbox'
    && o.name != null && o.name.indexOf('CheckBox') > -1)
    __doPostBack("","");
    }
  • Re: Getting TreeView to postback when node is checked/unchecked

    01-04-2006, 2:14 PM

    What I want to do is almost identical to sentha's but I want only non-leaf node to have the onclick call to __doPostBack.

    First of all what do I have to do to add the onclick attribute to the TreeNode/TreeView class(show the code) so my nodes have correct event hooked to the javascript function? What I want to do is to add an action to add the onclick to all non-leaf node once the tree is going to render, which event do I need to modify (it should be a very quick iteration)? The last question is how do I find out if a node is a leaf other than checking for children count (is there a property)?

    I found an example (that is incomplete)

    http://www.codeproject.com/script/comments/user_reply.asp?select=1319722&main=/aspnet/ClientSideTreeView.asp&df=100&forumid=191281

    It says that it will click children's checkbox except when he tries to get the check status on the server side it always returns false. The first problem with this solution is that I don't know how he used DOM to get the treenode since it's represented using table with checkbox, images, and links in HTML(GetSelectedNode has no source in his post hence I can't figure out how he did it). The idea sounds good.

     

  • Re: Getting TreeView to postback when node is checked/unchecked

    01-05-2006, 12:59 PM
    • Contributor
      2,210 point Contributor
    • jdixon
    • Member since 06-24-2002, 8:41 AM
    • Redmond
    • Posts 438
    • AspNetTeam

    The client side object model is not really a feature of the tree. That said it should be consistent enough to play with. Here is a solution - again this is not pretty (as stated earlier in the thread), but gets the job done.

     

    HTH


    JD

    <%@ Page Language="C#" %>

    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            
    if (IsPostBack)
            {
                Response.Write(
    "f");
            }
        }
    </script>

    <
    script>
        function foo() {
            
    var o = window.event.srcElement;
            
    var s  = event.srcElement.id;        
            s = s.replace(
    "TreeView1t", "TreeView1n");
            
    // take the checkbox val off so as to be able to check if the node has an
            // image href - if it does then the node has children    
            s = s.replace("CheckBox","");    
            
    var ch = document.getElementById(s);
            
    if (ch != null && o.tagName == "INPUT" && o.type == "checkbox") {            
                __doPostBack(
    "","");
            }                    
        }
    </script>

    <
    html>
    <
    head id="Head1" runat="server">
    </
    head>
    <
    body>
        <form id="form1" runat="server">
            <div>
                <asp:TreeView ID="TreeView1" runat="server" ExpandDepth="1">
                    <Nodes>
                        <asp:TreeNode ShowCheckBox="True" Value="New Node1" Text="New Node1">
                            <asp:TreeNode ShowCheckBox="True" Value="New Node2" Text="New Node2"></asp:TreeNode>
                        </asp:TreeNode>
                    </Nodes>
                </asp:TreeView>
            </div>
        </form>

        <script type="text/javascript">
            if (document.all) {    
                document.getElementById(
    'TreeView1').onclick = foo;    
            }
        
    </script>
    </
    body>
    </
    html>
    This posting is provided "AS IS" with no warranties, and confers no rights.
    We Are Hiring
  • Re: Getting TreeView to postback when node is checked/unchecked

    02-13-2008, 11:06 AM
    • Member
      4 point Member
    • davecoates
    • Member since 11-22-2007, 10:05 AM
    • South Africa
    • Posts 5

    It ain't pretty, but I've been struggling all day to find this! So I'm happy for now. Thanks!

     

    Dave 

    Port Elizabeth .NET - Community Blog
  • Re: Getting TreeView to postback when node is checked/unchecked

    07-24-2008, 4:36 PM
    • Contributor
      5,295 point Contributor
    • atconway
    • Member since 09-24-2007, 5:20 PM
    • Florida U.S.A
    • Posts 1,136

    This JavaScript works perfectly for me as far as forcing a postback when a treeview's checkbox is checked, but I am having one small issue.  The postback is causing validation and my AJAX contol validator extenders are poping up on unrelated controls.  I did not see any 'CausesValidation' property on the Treeview control.

    Is there a way to still force the postback when checking the checkbox in the tree, but preventing page validation? 

    Thank you,   >[Blog]<

    "The best thing about a boolean is even if you are wrong, you are only off by a bit." :D
    -anonymous

  • Re: Getting TreeView to postback when node is checked/unchecked

    09-24-2008, 1:54 PM
    • Member
      165 point Member
    • jpa7227
    • Member since 11-09-2006, 2:33 PM
    • Rochester, NY
    • Posts 58

    atconway:

    This JavaScript works perfectly for me as far as forcing a postback when a treeview's checkbox is checked, but I am having one small issue.  The postback is causing validation and my AJAX contol validator extenders are poping up on unrelated controls.  I did not see any 'CausesValidation' property on the Treeview control.

    Is there a way to still force the postback when checking the checkbox in the tree, but preventing page validation? 

     

    I've been experimenting with the TreeView and UpdatePanel, I added a Button to the page to see if I could reproduce your situation, but I can't.  However, here is my code:

    function TreeNodeCheckChanged(event, control) {
    // Valid for IE and Firefox/Safari/Chrome.
    var obj = window.event ? window.event.srcElement : event.target;
    var source = window.event ? window.event.srcElement.id : event.target.id;
    source = source.replace(control.id + "t", control.id + "n");
    source = source.replace("CheckBox", "");
    var checkbox = document.getElementById(source);
    if (checkbox != null &&
    obj.tagName == "INPUT" &&
    obj.type == "checkbox") {
    __doPostBack(checkbox.id, "");
    }
    }
    I ended up changing the JavaScript posted above a little bit. First, to add some cross-browser compatibility, this is why the event gets passed. If someone has a cleaner method, please let me know. I suck at JavaScript for the most part. Second, I also pass the control so it is a bit more extensible. Finally, I added the CheckBox's ID to the __doPostBack() call as per the following link:
    http://weblogs.asp.net/jeffreyzhao/archive/2008/04/26/refresh-the-updatepanel-using-javascript-code.aspx 

    FWIW, I didn't need to do anything to the ScriptManager in my little demo. Here is the rest of my HTML:

        <asp:ScriptManager ID="ScriptManager" runat="server" />
    <div>
    <asp:UpdatePanel id="UpdatePanel" runat="server">
    <ContentTemplate>
    <asp:TextBox ID="TextBox1" runat="server" />
    <asp:RequiredFieldValidator ID="rfvTextBox1" runat="server" ControlToValidate="TextBox1" ErrorMessage="Please enter some text."/><br />
    <asp:TreeView ID="treeTest" runat="server"
    NodeStyle-Font-Names="Consolas"
    NodeStyle-Font-Size="12px"
    ShowCheckBoxes="All"
    ShowExpandCollapse="true"
    EnableClientScript="true"
    OnSelectedNodeChanged="OnSelectedNodeChanged"
    OnTreeNodeCheckChanged="OnTreeNodeCheckChanged"
    OnAdaptedTreeNodeCheckChanged="OnTreeNodeCheckChanged">
    </asp:TreeView>
    <br /><br />
    </ContentTemplate>
    </asp:UpdatePanel>
    <asp:Button ID="btnTest" runat="server" Text="Click" />
       And here is my code-behind:
            protected void Page_Load(object sender, EventArgs e)
    {
    if (!IsPostBack)
    LoadTreeView();
    }

    /// <summary>
    /// Populates the TreeView control.
    /// </summary>

    private void LoadTreeView()
    {
    NorthwindDataContext db = new NorthwindDataContext();

    // Query a list of Products and their Categories, excluding Products with no Category.
    var products = from p in db.Products
    where p.Category.CategoryName != string.Empty
    orderby p.Category.CategoryName
    select new
    {
    p.Category.CategoryName,
    p.ProductName
    };

    string currentCategory = string.Empty;
    int catNum = 0;

    // Add nodes to the tree.
    foreach (var cat in products)
    {
    if (!currentCategory.Equals(cat.CategoryName))
    {
    // Add Category TreeNode.
    currentCategory = cat.CategoryName;
    treeTest.Nodes.Add(new TreeNode(currentCategory));
    treeTest.Nodes[catNum].Collapse();

    // Add Product TreeNodes under each Category.
    foreach (var prod in products)
    {
    if (prod.CategoryName.Equals(currentCategory))
    {
    treeTest.Nodes[catNum].ChildNodes.Add(new TreeNode(prod.ProductName));
    }
    }

    catNum++;
    }
    }

    // Add the onclick event handler so checking a parent node fires the OnTreeNodeCheckChanged event.
    treeTest.Attributes.Add("onclick", "TreeNodeCheckChanged(event, this)");
    }

    /// <summary>
    /// Expands/Collapses a node when clicked.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>

    protected void OnSelectedNodeChanged(object sender, EventArgs e)
    {
    if (((TreeView)sender).SelectedNode.ChildNodes.Count > 0)
    {
    if ((bool)((TreeView)sender).SelectedNode.Expanded)
    {
    ((TreeView)sender).SelectedNode.Collapse();
    }
    else
    {
    ((TreeView)sender).SelectedNode.Expand();
    }
    }

    // Deselects the SelectedNode so it can be toggled without clicking on another node first.
    ((TreeView)sender).SelectedNode.Selected = false;
    }

    /// <summary>
    /// Checks or unchecks child nodes when a parent node is checked or unchecked.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>

    protected void OnTreeNodeCheckChanged(object sender, TreeNodeEventArgs e)
    {
    // Determine if checked Node is a root node.
    if (e.Node.ChildNodes.Count > 0)
    {
    // Check or uncheck all of the child nodes based on status of parent node.
    if (e.Node.Checked)
    ChangeChecked(e.Node, true);
    else
    ChangeChecked(e.Node, false);
    }
    }

    /// <summary>
    /// Recursively checks or unchecks all child nodes for a given TreeNode.
    /// </summary>
    /// <param name="node">TreeNode to check or uncheck.</param>
    /// <param name="check">Desired value of TreeNode.Checked.</param>
    private void ChangeChecked(TreeNode node, bool check)
    {
    // "Queue" up child nodes to be checked or unchecked.
    if (node.ChildNodes.Count > 0)
    {
    for (int i = 0; i < node.ChildNodes.Count; i++)
    ChangeChecked(node.ChildNodes[i], check);
    }

    node.Checked = check;
    }
     So, that kinda works for me.  Let me know if I am missing something.  BTW, if anyone has any suggestions to improve my LINQ section (or anything else), please let me know.  My loop feels kinda inefficient.
  • Re: Getting TreeView to postback when node is checked/unchecked

    07-17-2009, 6:35 AM
    • Member
      2 point Member
    • shenchley
    • Member since 07-17-2009, 9:43 AM
    • Posts 1

    Hi all,

    Just thought I'd add my two-pennies worth here. Thanks for all the above posts that got me to a point I could finally work with. My problem with the java code above was that it wouldn't fire correctly when attempting to check if the sender object was indeed the checkbox. This could have been down to a couple of things, mainly that Firefox/IE threw an error if it couldn't collect the required objects. I'm unsure if anybody else has had this same problem but below is my (very vague and messy) solution. I allow the java to do the postback and then deal with the checked boxes / nodes in asp.net code behind in a 'OnTreeNodeCheckChanged' event. Here goes, hope this may help some folks out.

    Default.aspx


    <script>
            function CheckboxClicked(chkevent)
            {
                // Tested on IE7 and Firefox 3
                var obj;
                try
                {
                    obj = window.event.srcElement;
                }
                catch (Error)
                {
                  //Using a browser that cannot retrieve srcElement i.e. Firefox 3
                  //obj will not have been set, obj = null
                }
                    
                if (obj != null)
                {
                  //obj is not null, probably using IE
                    if (obj.tagName == "INPUT" &&
            obj.type == "checkbox")
            {
                        __doPostBack("", "");
                    }
                }
                else
                {
                  //obj is null, probably using Firefox
                    if (chkevent != null)
                    {
                        if (chkevent.target.toString() == "[object HTMLInputElement]")
                        {
                            __doPostBack("", "");
                        }
                    }
                }
        }
        </script>


        <asp:TreeView ID="tvGroups" runat="server"
                   OnTreeNodeCheckChanged="tvGroups_OnTreeNodeCheckChanged" EnableClientScript="false">
         </asp:TreeView>


    Default.aspx.cs

    protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)

            {
                tvGroups.Attributes.Add("onclick", "CheckboxClicked(event)");
            }
        }


    protected void tvGroups_OnTreeNodeCheckChanged(object sender, TreeNodeEventArgs e)
        {

            //Insert function to check/un-check all of the child nodes beneath the one clicked
            CheckChildNodes(e.Node, e.Node.Checked);
        }


    That should do you. In brief, the Page_Load adds the "onclick" event to the TreeView and tells it to fire the Javascript "CheckboxClicked" code. This function uses rudimentary code to retrieve what kind of object within the TreeView was clicked i.e. Image, DIVElement, Checkox etc. If it is determined to be a CheckBox then a blank postback is fired, else any other postback is passed through (like expansion of a tree node postback). When the page reloads, the OnTreeNodeCheckChange event is fired and a custom procedure runs which checks/unchecks any child nodes. You can replace this with whatever code you like.

    Hope this helps anyone having simiilar problems


  • Re: Getting TreeView to postback when node is checked/unchecked

    09-25-2009, 1:10 PM
    • Member
      2 point Member
    • phammk
    • Member since 09-25-2009, 1:06 PM
    • California
    • Posts 1

    This code works great, but i got a problem.

    In the server side postback, the e.treenode always show 'checked=true', even when i unchecked. It's like the postback is returning the treeview state 'before' the click ?

    Has anyone experience this problem ?

    Filed under:
Page 1 of 1 (14 items)