Page view counter

Getting TreeView to postback when node is checked/unchecked

Last post 09-24-2008 1:54 PM by jpa7227. 11 replies.

Sort Posts:

  • Getting TreeView to postback when node is checked/unchecked

    07-22-2004, 4:21 PM
    • Loading...
    • sentha
    • Joined on 07-22-2004, 4:15 PM
    • Posts 6
    • Points 30
    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
    • Loading...
    • Fredrik N
    • Joined on 06-22-2002, 5:03 AM
    • Sweden
    • Posts 5,333
    • Points 29,632
    • 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

    Microsoft MVP, MCSD, MCAD, MCT

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

    07-23-2004, 11:04 AM
    • Loading...
    • jdixon
    • Joined on 06-24-2002, 8:41 AM
    • Redmond
    • Posts 438
    • Points 2,210
    • 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
    • Loading...
    • Fredrik N
    • Joined on 06-22-2002, 5:03 AM
    • Sweden
    • Posts 5,333
    • Points 29,632
    • 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

    Microsoft MVP, MCSD, MCAD, MCT

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

    07-23-2004, 12:04 PM
    • Loading...
    • jdixon
    • Joined on 06-24-2002, 8:41 AM
    • Redmond
    • Posts 438
    • Points 2,210
    • 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
    • Loading...
    • sentha
    • Joined on 07-22-2004, 4:15 PM
    • Posts 6
    • Points 30
    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
    • Loading...
    • sentha
    • Joined on 07-22-2004, 4:15 PM
    • Posts 6
    • Points 30
    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
    • Loading...
    • jdixon
    • Joined on 06-24-2002, 8:41 AM
    • Redmond
    • Posts 438
    • Points 2,210
    • 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
    • Loading...
    • davecoates
    • Joined on 11-22-2007, 10:05 AM
    • South Africa
    • Posts 5
    • Points 4

    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
    • Loading...
    • atconway
    • Joined on 09-24-2007, 9:20 PM
    • Florida U.S.A
    • Posts 426
    • Points 899

    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,

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

    09-24-2008, 1:54 PM
    • Loading...
    • jpa7227
    • Joined on 11-09-2006, 9:33 AM
    • Rochester, NY
    • Posts 58
    • Points 165

    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.
Page 1 of 1 (12 items)