Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
392
How to make web tree checkboxes have radio behavior.
posted

Ive been playing with this for a while and all of the solutions posted so far (including my previous one) have the problems with large trees.  Any recusrsion becomes VERY slow on client scripts, making recursive tree operations a bad idea on the client.

Another way to do it is that you can keep track of the last selected nodeId in a hidden form field and then set it on the server.  Then your javascript can look in that hidden field to see what it needs to unselect. This works if you are using plain old HTML and not controls in an asp:container.  ASP decorates all contained IDs in a way that isnot easily dealt with when passing ids between the server and client.  Its a major pain.  Even if you use plain old HTML then it has a problem where the radio action does not cleanly survive a postback.  Just after a postback it is possible to select two nodes. 

The solution is non-obvious but it works.  The web tree already has a radio action mechanism in place... node selection.  The trick is to hijack node selection so that it also checks the checkbox and make NodeChecked alse select the node.  This way the radio action is ensured by the selection mechanism and the checked node will always be the selected node.  This works because there is a client method on WebTree to get the selected node. 

The gotcha is that it requires you to script both NodeChecked and BeforeNodeSelectionChange so that they would each produce events that trigger each other, resulting in an infinite loop.  The script needs to block this as shown below.

First you'll need to make sure that the tree is selectable and has checkboxes.  Then set these:

tree.ClientSideEvents.NodeChecked = "NodeChecked_RadioAction";

tree.ClientSideEvents.BeforeNodeSelectionChange = "BeforeNodeSelectionChange_RadioAction";

 

Then, in your .js use this:


// Call from: <ClientSideEvents NodeChecked="NodeChecked_RadioAction"/>
var stopInfiniteLoop = false;
function NodeChecked_RadioAction(treeId, id, bChecked)
{
    if( stopInfiniteLoop == true )
        return;
    else
        stopInfiniteLoop = true;
   
   
    var tree = igtree_getTreeById(treeId);
      var thisNode = igtree_getNodeById(id);
     
      if( !bChecked )
    {
        if( thisNode != null )
            thisNode.setSelected(false);
    }
    else
    {
        if( tree != null )
        {
          var selectedNode = tree.getSelectedNode();
            if( selectedNode != null )
                selectedNode.setChecked(false);
           
            if( tree != null && thisNode != null )
                tree.setSelectedNode( thisNode );
          }
      }
     
     
      stopInfiniteLoop = false;
}


// Call from: <ClientSideEvents BeforeNodeSelectionChange="BeforeNodeSelectionChange_RadioAction"/>
function BeforeNodeSelectionChange_RadioAction(treeId, oldId, newId )
{
    if( stopInfiniteLoop == true )
        return;
    else
        stopInfiniteLoop = true;
   
   
    var tree = igtree_getTreeById(treeId);
      if( tree != null )
      {
          var oldNode = igtree_getNodeById(oldId);
          if( oldNode != null )
              oldNode.setChecked(false);
             
          var newNode = igtree_getNodeById(newId);
          if( newNode != null )
              newNode.setChecked(true);
      }
     
     
      stopInfiniteLoop = false;
}

 

That should do it.  If you dont want it to look like the node is selected then you can use CSS to make the selected nodes look exactly like the unselected node and no one will know the difference.  Of course, all this wouldnt be necessary if Infragistics provided real radio buttons on the tree control (hint).

Clark