Search code examples
dojodijit.form

Dojo Select onChange event firing when changing value programmatically


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 programmatically 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 programmatically 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); 
    }

Solution

  • 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.