DSC00003

DevExpress ASPxTreeList – Single node selection via client side JavaScript.

Using the DevExpress ASPxTreeList control recently I came across the problem of how to only allow one node checkbox to be selected at once.

There are examples on the DevExpress support site of implementing this using server side code and postbacks, however this isn’t so desirable, as incurring a postback for every time a node is clicked is fairly expensive.

I had a look into how to implement this using the ASPxClientTreeList functionality available to deselect nodes when other nodes are selected. The solution I worked out works reasonably well, with one caveat which is covered at the end.

Before I go further, its worth noting that this functionality was coded against v11.2.7 of the DevExpress ASPx libraries. In future versions it may not work, the limitations might be fixed, or there may even be a built in way to do the clientside filtering automatically.

I implemented the following javascript. It handles the ClientSideEvents.SelectionChanged event:

//Cater for client side single click in DevExpress AspxTreeList
var globalTreeClickHandler = new function() {

    /*
    Applies single click functionality on the client side.
    For details of the functions used, see http://documentation.devexpress.com/#AspNet/clsDevExpressWebASPxTreeListScriptsASPxClientTreeListtopic
    */

    var self = this;
    this.debug = false;

    //Define the persistence of last selected nodes
    this.lastSelectedNodeKeys = new Object;

    this.singleClickHandler = function(s, e) {

        if (self.debug) alert("single click handler: " + s.name);

        //If more than one selected
        if (s.GetVisibleSelectedNodeKeys().length > 1) {

            //Deselect the last selected node key.
            if (self.debug) alert("Last Selected Key: " + self.lastSelectedNodeKeys[s.name]);
            if (self.lastSelectedNodeKeys[s.name] != undefined) {
                s.SelectNode(self.lastSelectedNodeKeys[s.name], false);
            }

        }

        //Save the currently selected key for next time
        var selectedKeys = s.GetVisibleSelectedNodeKeys();
        if (self.debug) alert("Selected Key: " + selectedKeys[0]);
        self.lastSelectedNodeKeys[s.name] = selectedKeys[0];

    }

}

To get your instance of ASPxTreeList to call the code, set the following line in your ASPxTreeList control setup code:

treeList.ClientSideEvents.SelectionChanged = "globalTreeClickHandler.singleClickHandler";

or in the markup:

<ClientSideEvents
    SelectionChanged="globalTreeClickHandler.singleClickHandler"
/>

Features:

  • The previously selected node is held in a object (effectively a dictionary) using the name of the AspxClientTreeList instance as the key. This allows the code to handle multiple ASPxTreeList controls at once.
  • Setting this.debug = true; will cause the code to output debugging message to aid understanding if there are problems

Known Limitations:

  • The GetVisibleSelectedNodeKeys and SelectNode methods only work on visible nodes. So, if a user selects a node, hides it (by collapsing a parent node), and then selects another, the first node will not be deslected. I think this is because the tree only actually contains the nodes that are displayed – expanding and collapsing causes a DevExpress callback, which regenerates the nodes. For this reason it is still necessary to validate that only one node has been selected on the server side after the form is submitted.

One thought on “DevExpress ASPxTreeList – Single node selection via client side JavaScript.”

Leave a Reply

Your email address will not be published.

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax