Changeset 11982

Show
Ignore:
Timestamp:
01/09/08 14:20:14 (18 months ago)
Author:
doughays
Message:

Fixes #5222 !strict. Split out the special value processing in _FormWidget and subclassed it into _FormValueWidget so that Button and TextBox? could inherit from different classes, allowing value to be treated like a simple string attribute for Buttons/checkboxes and as complex objects for input widgets (dates/times/currency/etc). Deprecated setChecked and setValue for Button widgets (and subclasses) for the new setAttribute method for all simple attributes.
Removed onChange(string) that was being called for Buttons/checkboxes when the value attribute was changed. Only onChange(boolean) should be called for checkboxes.

Location:
dijit/trunk
Files:
14 modified

Legend:

Unmodified
Added
Removed
  • dijit/trunk/form/Button.js

    r11893 r11982  
    7777                        dojo.addClass(this.containerNode,"dijitDisplayNone"); 
    7878                } 
     79                dojo.setSelectable(this.focusNode, false); 
    7980                this.inherited(arguments); 
    8081        }, 
     
    390391        checked: false, 
    391392 
     393        _onChangeMonitor: 'checked', 
     394 
     395        attributeMap: dojo.mixin(dojo.clone(dijit.form.Button.prototype.attributeMap), 
     396                {checked:"focusNode"}), 
     397 
    392398        _clicked: function(/*Event*/ evt){ 
    393                 this.setChecked(!this.checked); 
    394         }, 
     399                this.setAttribute('checked', !this.checked); 
     400        }, 
     401 
     402        setAttribute: function(/*String*/ attr, /*anything*/ value){ 
     403                this.inherited(arguments); 
     404                switch(attr){ 
     405                        case "checked": 
     406                                dijit.setWaiState(this.focusNode || this.domNode, "pressed", this.checked); 
     407                                this._setStateClass();           
     408                                this._handleOnChange(this.checked, true); 
     409                } 
     410        }, 
     411 
    395412 
    396413        setChecked: function(/*Boolean*/ checked){ 
    397414                // summary: 
    398415                //      Programatically deselect the button 
    399                 this.checked = checked; 
    400                 dijit.setWaiState(this.focusNode || this.domNode, "pressed", this.checked); 
    401                 this._setStateClass();           
    402                 this.onChange(checked); 
     416                dojo.deprecated("setChecked("+checked+") is deprecated. Use setAttribute('checked',"+checked+") instead.", "", "2.0"); 
     417                this.setAttribute('checked', checked); 
    403418        } 
    404419}); 
  • dijit/trunk/form/CheckBox.js

    r11107 r11982  
    3333                //      equivalent to value field on normal checkbox (if checked, the value is passed as 
    3434                //      the value when form is submitted) 
    35                 value: "on", 
    36  
    37                 postCreate: function(){ 
    38                         dojo.setSelectable(this.inputNode, false); 
    39                         this.setChecked(this.checked); 
    40                         this.inherited(arguments); 
    41                 }, 
    42  
    43                 setChecked: function(/*Boolean*/ checked){ 
    44                         if(dojo.isIE){ 
    45                                 if(checked){ this.inputNode.setAttribute('checked', 'checked'); } 
    46                                 else{ this.inputNode.removeAttribute('checked'); } 
    47                         }else{ this.inputNode.checked = checked; } 
    48                         this.inherited(arguments); 
    49                 }, 
    50  
    51                 setValue: function(/*String*/ value){ 
    52                         if(value == null){ value = ""; } 
    53                         this.inputNode.value = value; 
    54                         dijit.form.CheckBox.superclass.setValue.call(this,value); 
    55                 } 
     35                value: "on" 
    5636        } 
    5737); 
     
    9575                }, 
    9676 
    97                 setChecked: function(/*Boolean*/ checked){ 
     77                setAttribute: function(/*String*/ attr, /*anything*/ value){ 
    9878                        // If I am being checked then have to deselect currently checked radio button 
    99                         if(checked){ 
    100                                 dojo.forEach(this._groups[this.name], function(widget){ 
    101                                         if(widget != this && widget.checked){ 
    102                                                 widget.setChecked(false); 
     79                        this.inherited(arguments); 
     80                        switch(attr){ 
     81                                case "checked": 
     82                                        if(this.checked){ 
     83                                                dojo.forEach(this._groups[this.name], function(widget){ 
     84                                                        if(widget != this && widget.checked){ 
     85                                                                widget.setAttribute('checked', false); 
     86                                                        } 
     87                                                }, this); 
    10388                                        } 
    104                                 }, this); 
    10589                        } 
    106                         this.inherited(arguments);                       
    10790                }, 
    10891 
    10992                _clicked: function(/*Event*/ e){ 
    11093                        if(!this.checked){ 
    111                                 this.setChecked(true); 
     94                                this.setAttribute('checked', true); 
    11295                        } 
    11396                } 
  • dijit/trunk/form/Form.js

    r11660 r11982  
    7878                        }); 
    7979 
    80                         // call setValue() or setChecked() for each widget, according to obj 
     80                        // call setValue() or setAttribute('checked') for each widget, according to obj 
    8181                        for(var name in map){ 
    8282                                var widgets = map[name],                                                // array of widgets w/this name 
     
    8585                                        values = [ values ]; 
    8686                                } 
    87                                 if(widgets[0].setChecked){ 
     87                                if(typeof widgets[0].checked == 'boolean'){ 
    8888                                        // for checkbox/radio, values is a list of which widgets should be checked 
    8989                                        dojo.forEach(widgets, function(w, i){ 
    90                                                 w.setChecked(dojo.indexOf(values, w.value) != -1); 
     90                                                w.setAttribute('checked', (dojo.indexOf(values, w.value) != -1)); 
    9191                                        }); 
    9292                                }else{ 
     
    176176                        var obj = {}; 
    177177                        dojo.forEach(this.getDescendants(), function(widget){ 
    178                                 var value = widget.getValue ? widget.getValue() : widget.value; 
     178                                var value = (widget.getValue && !widget._getValueDeprecated) ? widget.getValue() : widget.value; 
    179179                                var name = widget.name; 
    180180                                if(!name){ return; } 
    181181 
    182182                                // Store widget's value(s) as a scalar, except for checkboxes which are automatically arrays 
    183                                 if(widget.setChecked){ 
     183                                if(typeof widget.checked == 'boolean'){ 
    184184                                        if(/Radio/.test(widget.declaredClass)){ 
    185185                                                // radio button 
  • dijit/trunk/form/Slider.js

    r11899 r11982  
    1010dojo.declare( 
    1111        "dijit.form.HorizontalSlider", 
    12         [dijit.form._FormWidget, dijit._Container], 
     12        [dijit.form._FormValueWidget, dijit._Container], 
    1313{ 
    1414        // summary 
  • dijit/trunk/form/templates/CheckBox.html

    r11961 r11982  
    33                type="${type}" name="${name}" 
    44                class="dijitReset dijitCheckBoxInput" 
    5                 dojoAttachPoint="inputNode,focusNode" 
     5                dojoAttachPoint="focusNode" 
    66                dojoAttachEvent="onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick" 
    77/></div> 
  • dijit/trunk/form/Textarea.js

    r11908 r11982  
    77dojo.declare( 
    88        "dijit.form.Textarea", 
    9         dijit.form._FormWidget, 
     9        dijit.form._FormValueWidget, 
    1010        { 
    1111        // summary: A resizing textarea widget 
     
    2121        // 
    2222 
    23         attributeMap: dojo.mixin(dojo.clone(dijit.form._FormWidget.prototype.attributeMap), 
     23        attributeMap: dojo.mixin(dojo.clone(dijit.form._FormValueWidget.prototype.attributeMap), 
    2424                {style:"styleNode", 'class':"styleNode"}), 
    2525 
  • dijit/trunk/form/TextBox.js

    r11779 r11982  
    55dojo.declare( 
    66        "dijit.form.TextBox", 
    7         dijit.form._FormWidget, 
     7        dijit.form._FormValueWidget, 
    88        { 
    99                // summary: 
     
    3434                baseClass: "dijitTextBox", 
    3535 
    36                 attributeMap: dojo.mixin(dojo.clone(dijit.form._FormWidget.prototype.attributeMap), 
     36                attributeMap: dojo.mixin(dojo.clone(dijit.form._FormValueWidget.prototype.attributeMap), 
    3737                        {maxLength:"focusNode"}), 
    3838 
  • dijit/trunk/form/_FormWidget.js

    r11894 r11982  
    88        /* 
    99        Summary: 
    10                 FormElement widgets correspond to native HTML elements such as <input> or <button> or <select>. 
    11                 Each FormElement represents a single input value, and has a (possibly hidden) <input> element, 
    12                 to which it serializes its input value, so that form submission (either normal submission or via FormBind?) 
    13                 works as expected. 
     10                _FormWidget's correspond to native HTML elements such as <checkbox> or <button>. 
     11                Each _FormWidget represents a single HTML element. 
    1412 
    1513                All these widgets should have these attributes just like native HTML input elements. 
    16                 You can set them during widget construction, but after that they are read only. 
     14                You can set them during widget construction. 
    1715 
    1816                They also share some common methods. 
     
    2523        baseClass: "", 
    2624 
     25        // name: String 
     26        //              Name used when submitting form; same as "name" attribute or plain HTML elements 
     27        name: "", 
     28 
     29        // alt: String 
     30        //              Corresponds to the native HTML <input> element's attribute. 
     31        alt: "", 
     32 
    2733        // value: String 
    2834        //              Corresponds to the native HTML <input> element's attribute. 
    2935        value: "", 
    30  
    31         // name: String 
    32         //              Name used when submitting form; same as "name" attribute or plain HTML elements 
    33         name: "", 
    34  
    35         // alt: String 
    36         //              Corresponds to the native HTML <input> element's attribute. 
    37         alt: "", 
    3836 
    3937        // type: String 
     
    6563        // require the 'name' attribute at element creation time. 
    6664        attributeMap: dojo.mixin(dojo.clone(dijit._Widget.prototype.attributeMap), 
    67                 {disabled:"focusNode", readOnly:"focusNode", id:"focusNode", tabIndex:"focusNode", alt:"focusNode"}), 
     65                {value:"focusNode", disabled:"focusNode", readOnly:"focusNode", id:"focusNode", tabIndex:"focusNode", alt:"focusNode"}), 
    6866 
    6967        setAttribute: function(/*String*/ attr, /*anything*/ value){ 
     
    218216        }, 
    219217 
     218        _onChangeMonitor: 'value', 
     219        _onChangeActive: false, 
     220 
     221        _handleOnChange: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){ 
     222                // summary: set the value of the widget. 
     223                this._lastValue = newValue; 
     224                if(this._lastValueReported == undefined && priorityChange === null){ 
     225                        this._lastValueReported = newValue; 
     226                } 
     227                if((this.intermediateChanges || priorityChange || priorityChange === undefined) &&  
     228                        ((newValue && newValue.toString)?newValue.toString():newValue) !== ((this._lastValueReported && this._lastValueReported.toString)?this._lastValueReported.toString():this._lastValueReported)){ 
     229                        this._lastValueReported = newValue; 
     230                        if(this._onChangeActive){ this.onChange(newValue); } 
     231                } 
     232        }, 
     233 
     234        create: function(){ 
     235                this.inherited(arguments); 
     236                this._onChangeActive = true; 
     237                this._setStateClass(); 
     238        }, 
     239 
    220240        postCreate: function(){ 
    221                 this.setValue(this.value, null); // null reserved for initial value 
    222                 this._setStateClass(); 
     241                this._lastValueReported = this[this._onChangeMonitor]; 
     242        }, 
     243 
     244        setValue: function(/*String*/ value){ 
     245                dojo.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated.  Use setAttribute('value',"+value+") instead.", "", "2.0"); 
     246                this.setAttribute('value', value); 
     247        }, 
     248 
     249        _getValueDeprecated: true, // Form uses this, remove when getValue is removed 
     250        getValue: function(){ 
     251                dojo.deprecated("dijit.form._FormWidget:getValue() is deprecated.  Use widget.value instead.", "", "2.0"); 
     252                return this.value; 
     253        } 
     254}); 
     255 
     256dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget, 
     257{ 
     258        /* 
     259        Summary: 
     260                _FormValueWidget's correspond to native HTML elements such as <input> or <select> that have user changeable values. 
     261                Each _ValueWidget represents a single input value, and has a (possibly hidden) <input> element, 
     262                to which it serializes its input value, so that form submission (either normal submission or via FormBind?) 
     263                works as expected. 
     264        */ 
     265 
     266        attributeMap: dojo.mixin(dojo.clone(dijit.form._FormWidget.prototype.attributeMap), 
     267                {value:""}), 
     268 
     269        postCreate: function(){ 
     270                this.setValue(this.value, null); 
    223271        }, 
    224272 
    225273        setValue: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){ 
    226274                // summary: set the value of the widget. 
    227                 this._lastValue = newValue; 
     275                this._handleOnChange(newValue, priorityChange); 
    228276                dijit.setWaiState(this.focusNode || this.domNode, "valuenow", this.forWaiValuenow()); 
    229                 if(priorityChange === undefined){ priorityChange = true; } // setValue with value only should fire onChange 
    230                 if(this._lastValueReported == undefined && priorityChange === null){ // don't report the initial value 
    231                         this._lastValueReported = newValue; 
    232                 } 
    233                 if((this.intermediateChanges || priorityChange) &&  
    234                         ((newValue && newValue.toString)?newValue.toString():newValue) !== ((this._lastValueReported && this._lastValueReported.toString)?this._lastValueReported.toString():this._lastValueReported)){ 
    235                         this._lastValueReported = newValue; 
    236                         this.onChange(newValue); 
    237                 } 
    238         }, 
    239  
     277        }, 
     278 
     279        _getValueDeprecated: false, // remove when _FormWidget:getValue is removed 
    240280        getValue: function(){ 
    241281                // summary: get the value of the widget. 
  • dijit/trunk/layout/StackContainer.js

    r11846 r11982  
    315315                        if(this._currentChild){ 
    316316                                var oldButton=this.pane2button[this._currentChild]; 
    317                                 oldButton.setChecked(false); 
     317                                oldButton.setAttribute('checked', false); 
    318318                                oldButton.focusNode.setAttribute("tabIndex", "-1"); 
    319319                        } 
    320320 
    321321                        var newButton=this.pane2button[page]; 
    322                         newButton.setChecked(true); 
     322                        newButton.setAttribute('checked', true); 
    323323                        this._currentChild = page; 
    324324                        newButton.focusNode.setAttribute("tabIndex", "0"); 
     
    345345                // TODO: this is a bit redundant with forward, back api in StackContainer 
    346346                adjacent: function(/*Boolean*/ forward){ 
    347                         var forward = this.isLeftToRight()? forward : !forward; 
     347                        forward = this.isLeftToRight()? forward : !forward; 
    348348                        // find currently focused button in children array 
    349349                        var children = this.getChildren(); 
  • dijit/trunk/tests/form/test_Button.html

    r11952 r11982  
    129129        <p>The button CSS as well as the icon CSS can change on toggle </p> 
    130130        <div class="box"> 
    131                 <button dojoType="dijit.form.ToggleButton" onChange="console.log('toggled button checked='+arguments[0]);" iconClass="dijitCheckBoxIcon"> 
     131                <button dojoType="dijit.form.ToggleButton" checked onChange="console.log('toggled button checked='+arguments[0]);" iconClass="dijitCheckBoxIcon"> 
    132132                        Toggle me 
    133133                </button> 
  • dijit/trunk/tests/form/test_CheckBox.html

    r11818 r11982  
    3737                        var params = {id: "cb6", name: "cb6"}; 
    3838                        var widget = new dijit.form.CheckBox(params, dojo.byId("checkboxContainer")); 
    39                         widget.setChecked(true); 
     39                        widget.setAttribute('checked', true); 
    4040                }); 
    4141        </script> 
     
    5353        </p> 
    5454        <!--  <form onSubmit="return outputValues(this);"> --> 
     55        <!--    to test form submission, you'll need to create an action handler similar to 
     56                http://www.utexas.edu/teamweb/cgi-bin/generic.cgi --> 
    5557        <form> 
    5658                <input type="checkbox" name="cb0" id="cb0" /> 
  • dijit/trunk/tests/form/test_Slider.html

    r11818 r11982  
    3535                                                    console.log(arguments); 
    3636                                                }, 
     37                                                name:"programaticSlider", 
    3738                                                style:"height:165px", 
    3839                                                minimum:1000, 
     
    7172                Also try using the arrow keys, buttons, or clicking on the progress bar to move the slider. 
    7273                <br> 
     74                <!--    to test form submission, you'll need to create an action handler similar to 
     75                        http://www.utexas.edu/teamweb/cgi-bin/generic.cgi --> 
     76                <form id="form1" action="" name="example" method="post"> 
    7377                <br>initial value=10, min=0, max=100, pageIncrement=100, onChange event triggers input box value change immediately<br> 
    7478 
     
    176180                <div id="programaticSlider"></div> 
    177181 
     182                        <script> 
     183                                function displayData() { 
     184                                        var f = document.getElementById("form1"); 
     185                                        var s = ""; 
     186                                        for (var i = 0; i < f.elements.length; i++) { 
     187                                                var elem = f.elements[i]; 
     188                                                if (elem.name == "button")  { continue; } 
     189                                                s += elem.name + ": " + elem.value + "\n"; 
     190                                        } 
     191                                        alert(s); 
     192                                } 
     193                        </script> 
     194 
     195                        <div> 
     196                                <button name="button" onclick="displayData(); return false;">view data</button> 
     197                                <input type="submit" name="submit" /> 
     198                        </div> 
     199 
     200                </form> 
    178201        </body> 
    179202</html> 
  • dijit/trunk/_editor/plugins/LinkDialog.js

    r11620 r11982  
    1515        { 
    1616                // summary: a DropDownButton but button can be displayed in two states (checked or unchecked) 
    17                 setChecked: dijit.form.ToggleButton.prototype.setChecked 
     17                checked: false, 
     18                setAttribute: dijit.form.ToggleButton.prototype.setAttribute 
    1819        } 
    1920); 
     
    143144                                        // display button differently if there is an existing link associated with the current selection 
    144145                                        var hasA = dojo.withGlobal(this.editor.window, "hasAncestorElement",dijit._editor.selection, ['a']); 
    145                                         this.button.setChecked(hasA); 
     146                                        this.button.setAttribute('checked', hasA); 
    146147                                }catch(e){ 
    147148                                        console.debug(e); //FIXME: probably shouldn't squelch an exception here 
  • dijit/trunk/_editor/_Plugin.js

    r11965 r11982  
    5454                                var enabled = _e.queryCommandEnabled(_c); 
    5555                                this.button.setAttribute('disabled',!enabled); 
    56                                 if(this.button.setChecked){ 
    57                                         this.button.setChecked(_e.queryCommandState(_c)); 
     56                                if(typeof this.button.checked == 'boolean'){ 
     57                                        this.button.setAttribute('checked', _e.queryCommandState(_c)); 
    5858                                } 
    5959                        }catch(e){