This is a migrated thread and some comments may be shown as answers.

TreeView in ComboBox - looking up either object without ID

1 Answer 58 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
Stefan
Top achievements
Rank 1
Stefan asked on 07 Feb 2011, 07:59 PM
I'm working on an ASP.NET custom control that uses RadTreeView inside RadComboBox (largely following the example on the demo site). It's entirely client side and does not postback on its own, so all event handling is done using clientside JavaScript.

The control will be used in several places on a page and I would like to simplify the JavaScript that needs to be deployed to the client (since there's quite a bit). Right now, though, the "control" is just an ASP.NET WebForm.

In general, I am able to do a lot of DOM walking in order to find objects by their relative position, but this is falling apart when I try to locate the ComboBox from a TreeNode.

For instance, I'd like to do this (not working):
function GetRadComboBoxFromRadTreeViewElement(treeViewElement) {
    var htmlRoot = $(treeViewElement).closest('div.MyCustomControl'); // walk up to control container
    var comboBoxDiv = $(htmlRoot).find('div.SearchableTreeCombo'); // find ComboBox container
    return $find($(comboBoxDiv).attr('id')); // look up ComboBox object from containing div id
}

The idea is that I pass some element from a TreeNode event handler to this function and it traverses the DOM and returns the RadComboBox client object.

This is failing for me because the HTML generated looks like this (severely trimmed down):

<html>
  <body>
    <form>
      <div class="rcbSlide">
        <div id="RadComboBox1_DropDown" class="RadComboBoxDropDown" ></div>
      </div>
 
      <div class="MyCustomControl">
        <label for="RadComboBox1" id="treeListLabel">Field Label: </label>
        <div id="RadComboBox1" class="RadComboBox RadComboBox_Default SearchableTreeCombo">
          <input id="RadComboBox1_ClientState" name="RadComboBox1_ClientState" type="hidden">
        </div>
      </div>
    </form>
  </body>
</html>

The actual TreeView contents are rendered in the 'rcbSlide' div, which is added as the first element on the form. The remainder of my control logic resides inside the 'MyCustomControl' div. That makes DOM walking impossible (or does it?) when I have multiple instances of the control on one form. I don't have access to ASP.NET IDs (e.g. <%= RadComboBox1.ClientID => because the controls are generated dynamically and not statically declared in any markup).

I'm hoping there is actually a way I can find the TreeView from the ComboBox and vice versa using JavaScript that is generic and reusable. If I can't, I think the only method I can follow is to add a copy of all of the JavaScript for each control on the form, and customize each block of script for each instance of a control.

That's not particularly disastrous, but it means that a LOT of redundant JavaScript is being sent to a client. Right now my JS (unminified, mind you) is 26KB to support one instance of the control. Some users will have up to 10 of these on a form and I hate to add so much bloat to my pages when the differences between the script blocks is so minimal.


Can anyone suggest anything? Thanks!

1 Answer, 1 is accepted

Sort by
0
Stefan
Top achievements
Rank 1
answered on 09 Feb 2011, 10:50 AM
I worked out a way to do this, thankfully.

The RadComboBox client API provides a function called get_dropDownElement() that provides a one-directional connection between both objects. That's all we need.

If anyone has a similar need in the future, I created 2 functions to look up in either direction. Looking up the ComboBox from the TreeView is messy but works and is relatively easy to follow:

// given an HTML element somewhere inside the TreeView, gets the RadComboBox object
function GetRadComboBoxFromRadTreeViewElement(treeViewElement) {
    var treeViewBaseElement = $(treeViewElement).closest('div.SearchableTreeView'); // this is the container div for the RadTreeView
    var comboBox;
    $('div.MyControl div.SearchableTreeCombo').each(
    function () {
        var someComboBox = $find($(this).attr('id'));
        var someTreeViewContainer = $(someComboBox.get_dropDownElement()).find('div.SearchableTreeView');
 
        if ($(treeViewBaseElement).attr('id') == $(someTreeViewContainer).attr('id')) {
            comboBox = someComboBox;
            return false;
        }
    }
    );
    return comboBox;
}
 
// given an HTML element inside a combobox, gets the treeview associated with it
function GetRadTreeViewFromRadComboBox(comboBox) {
    var treeViewElement = $(comboBox.get_dropDownElement()).find('div.SearchableTreeView');
    return $find($(treeViewElement).attr('id'));
}


The ComboBox lookup function iterates over a jQuery selector of all comboboxes on the page. My selector specifically looks for a div within a div that matches where my comboboxes live in the DOM. Once that is matched, it gets the dropDownElement for each combobox and compares the element's ID to that of the RadTreeView we were given.
Note that in my case it accepts an HTML element 'somewhere inside the TreeView'. I'm doing this because throughout my event handlers I may be passed a TreeNode, the TreeView, or a DOM element somewhere in there. In other cases this shouldn't be necessary and you could get away with passing the actual RadTreeView object to the function.
Tags
ComboBox
Asked by
Stefan
Top achievements
Rank 1
Answers by
Stefan
Top achievements
Rank 1
Share this question
or