views:

109

answers:

2

Hey,

I have a dojo (dijit) select dropdown that calls a js function onChange. I was expecting this to only call the onChange function when the user changes the value in the dropdown, however, it even calls the onChange function when I programatically change the value of the dropdown from js code. How do I get it to only call the function when the user changes the dropdown value? It shouldn't call the function when I programatically change the value.

<select jsId="ddlBoundaryType" id="ddlBoundaryType" name="ddlBoundaryType" 
                            dojoType="dijit.form.Select">
                            <option value="0">Circle</option>
                            <option value="1">Polygon</option>
                        </select>

dojo.addOnLoad(InitBoundaries);
    function InitBoundaries() {
        dojo.connect(dijit.byId("ddlBoundaryType"), 'onChange', Boundaries_ChangeBoundaryType); 
    }

Thanks, Justin

+1  A: 

Often people solve this by using the priorityChange flag:

myWidget.set("value", 1234, false);

That will solve your problem except for subtle issues where the value is originally 123, you set it programatically to 456, and then the user sets it back to 123, in which case there won't be an onChange() event for the user action either.

For that reason you can additionally do:

myWidget._lastValueReported=null;
Bill Keese
"set" isn't a function, I tried dojo.byId, dijit.byId, and this for accessing it and none of them have that as an available function.
Justin
_Widget.set() is a new function in 1.5. Pre-1.5 it was called attr().Note that this issue has been fixed in http://bugs.dojotoolkit.org/ticket/10988, for dojo 1.6, but since that won't be released for a while, try the workaround above.
Bill Keese
Thanks but unfortunately it doesn't work (at least in dojo 1.4.2.) Setting the 3rd parameter of .attr() to false had no effect, it still calls the onchange event. Additionally, setting the _lastValueReported=null calls the onchange event a second time...
Justin
A: 

I think the proper fix in this case for you would be http://bugs.dojotoolkit.org/ticket/10594, since it deals directly with dijit.form.Select. Of course, there are a few ways to fix this.

  1. Upgrade dojo :).
  2. Inherit dijit.form.Select and "patch" the _updateSelection function.
  3. Extend dijit.form.Select and "patch" it directly there.

I will forgo the first. The the second and the third method are similar, so I will just post a simple fix using the third way,

dijit.form.Select.extend({
   _updateSelection: function() {
        this.value = this._getValueFromOpts();
        var val = this.value;
        if(!dojo.isArray(val)){
            val = [val];
        }
        if(val && val[0]){
            dojo.forEach(this._getChildren(), function(child){
                var isSelected = dojo.some(val, function(v){
                    return child.option && (v === child.option.value);
                });
                dojo.toggleClass(child.domNode, this.baseClass + "SelectedOption", isSelected);
                dijit.setWaiState(child.domNode, "selected", isSelected);
            }, this);
        }
   }
});

Note that I did not write this function, I happily plagiarized it from the source code with the last line, this._handleOnChange(this.value) removed.

myWidget.attr('value', newValue, false) // should now work without firing onChange.
Anh-Kiet Ngo
#1 isn't an option since dojo is version 1.5 and this is going into 1.6. I'll take a look at #3, thanks!
Justin
Blah, I didn't notice it was for 1.6, boo me!
Anh-Kiet Ngo