Ian (Fluxtah) Warwick's blog RSS 2.0
# Thursday, November 06, 2008

At work I was implementing a search form that required a 3 tier drop down, so I thought the CascadingDropDown would be perfect for this.

It turns out that the CascadingDropDown was not quite right for the requirements, the last drop down in the 3 tiers had to be enabled and items had to be selectable but also had to filter the other 2 upper tiers.

After some thought, the only way to achieve this was having the ability to programatically add my own values to be passed to the knownCategoryValues argument of the web service method for a CascadingDropDown behavior.

To do this, I had to redefine a method on the CascadingDropDown behavior, I could then invoke this method to force the ajax callback for any CascadingDropDown of my choice. Here is that method.

AjaxControlToolkit.CascadingDropDownBehavior.prototype._onParentChange2 = function(evt, inInit, moreKnownCatValues) {
     /// <summary>
     /// Handler for the parent drop down's change event
     /// </summary>
     /// <param name="evt" type="Object">
     /// Set by the browser when called as an event handler (unused here)
     /// </param>
     /// <param name="inInit" type="Boolean">
     /// Whether this is being called from the initialize method
     /// </param>
     /// <returns />

     var e = this.get_element();

     // Create the known category/value pairs string for sending to the helper web service
     // Follow parent pointers so that the complete state can be sent
     // Format: 'name1:value1;name2:value2;...'
     var knownCategoryValues = '';
     var parentControlID = this._parentControlID;
     while (parentControlID) {
         var parentElement = $get(parentControlID);
         if (parentElement && (-1 != parentElement.selectedIndex)) {
             var selectedValue = parentElement.options[parentElement.selectedIndex].value;

             if (selectedValue && selectedValue != "") {
                 knownCategoryValues = parentElement.CascadingDropDownCategory + ':' + selectedValue + ';' + knownCategoryValues;
                 parentControlID = parentElement.CascadingDropDownParentControlID;
                 continue;
             }
         }
         break;
     }

     if (knownCategoryValues != '' && this._lastParentValues == knownCategoryValues) {
         return;
     }

     this._lastParentValues = knownCategoryValues;

     // we have a parent but it doesn't have a valid value
     //
     if (knownCategoryValues == '' && this._parentControlID) {
         this._setOptions(null, inInit);
         return;
     }

     // Show the loading text (if any)
     this._setOptions(null, inInit, true);

     if (this._servicePath && this._serviceMethod) {
         // Raise the populating event and optionally cancel the web service invocation
         var eventArgs = new Sys.CancelEventArgs();
         this.raisePopulating(eventArgs);
         if (eventArgs.get_cancel()) {
             return;
         }
         if (moreKnownCatValues) {
             knownCategoryValues += ";" + moreKnownCatValues;
         }
         // Create the service parameters and optionally add the context parameter
         // (thereby determining which method signature we're expecting...)
         var params = { knownCategoryValues: knownCategoryValues, category: this._category };
         if (this._useContextKey) {
             params.contextKey = this._contextKey;
         }

         // Call the helper web service
         Sys.Net.WebServiceProxy.invoke(this._servicePath, this._serviceMethod, false, params,
            Function.createDelegate(this, this._onMethodComplete), Function.createDelegate(this, this._onMethodError));
         $common.updateFormToRefreshATDeviceBuffer();
     }
 }

The method above is just a copy of _onParentChange method of the CascadingDropDown behavior, I called it _onParentChange2 and call this one when I want to invoke an ajax callback, the only difference is the extra argument moreKnownCatValues, the value of this argument will be appended to the knownCategoryValues which will get passed to the callback method. The changes to the original method have been bolded.

Now its possible to invoke a callback on any CascadingDropDown with the code below. 

$find('CDD1')._onParentChange2(null, false, "CountryId:25");

The line above will get a reference to a CascadingDropDown behaviour that I have given a BehaviorID of CDD1, it will then invoke the new _onParentChange2 method passing through my extra value of CountryId:25.

Its a shame that the CascadingDropDown does not have a more elegant approach for adding to the knownCategoryValues programatically, but at least this workaround is not to hacky. 

 

Thursday, November 06, 2008 1:52:00 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
ASP.NET
Archive
<November 2008>
SunMonTueWedThuFriSat
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456
Blogroll
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2012
Ian Warwick
Sign In
Statistics
Total Posts: 33
This Year: 0
This Month: 0
This Week: 0
Comments: 4
Themes
Pick a theme:
All Content © 2012, Ian Warwick
DasBlog theme 'Business' created by Christoph De Baene (delarou)