source: Dev/trunk/src/client/dojox/form/TriStateCheckBox.js @ 532

Last change on this file since 532 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 8.8 KB
Line 
1define([
2        "dojo/_base/kernel", // kernel.deprecated
3        "dojo/_base/declare", // declare
4        "dojo/_base/array", // array.indexOf
5        "dojo/_base/lang", // lang.isArray, lang.isString
6        "dojo/_base/event", // event.stop
7        "dojo/query", // query()
8        "dojo/dom-attr", // domAttr.set
9        "dojo/text!./resources/TriStateCheckBox.html",
10        "dijit/form/Button",
11        "dijit/form/_ToggleButtonMixin",
12        "dojo/NodeList-dom" // NodeList.addClass/removeClass
13], function(kernel, declare, array, lang, event, query, domAttr, template, Button, _ToggleButtonMixin){
14
15return declare("dojox.form.TriStateCheckBox", [Button, _ToggleButtonMixin], {
16        // summary:
17        //              Checkbox with three states
18       
19                templateString: template,
20
21                baseClass: "dojoxTriStateCheckBox",
22
23                // type: [private] String
24                //              type attribute on `<input>` node.
25                //              Overrides `dijit/form/Button.type`.  Users should not change this value.
26                type: "checkbox",
27
28                // states: Array
29                //              States of TriStateCheckBox.
30                //              The value of This.checked should be one of these three states:
31                //              [false, true, "mixed"]
32                states: "",
33
34                // _stateLabels: Object
35                //              These characters are used to replace the image to show
36                //              current state of TriStateCheckBox in high contrast mode. This is an associate array of
37                //      states with their corresponding replacing characters. State can either be "False", "True" or "Mixed".
38                 _stateLabels: null,
39
40                // stateValues: Object
41                //              The values of the TriStateCheckBox in corresponding states. This is an associate array of
42                //      states with their corresponding values. State can either be "False", "True" or "Mixed".
43                stateValue: null,
44
45                // _currentState: Integer
46                //              The current state of the TriStateCheckBox
47                _currentState: 0,
48
49                // _stateType: String
50                //              The current state type of the TriStateCheckBox
51                //              Could be "False", "True" or "Mixed"
52                _stateType: "False",
53
54                // readOnly: Boolean
55                //              Should this widget respond to user input?
56                //              In markup, this is specified as "readOnly".
57                //              Similar to disabled except readOnly form values are submitted.
58                readOnly: false,
59
60                // checked: Boolean|String
61                //              Current check state of the check box.
62                checked: "",
63               
64                // aria-pressed for toggle buttons, and aria-checked for checkboxes
65                _aria_attr: "aria-checked",
66
67                constructor: function(){
68                        // summary:
69                        //              Runs on widget initialization to setup arrays etc.
70                        // tags:
71                        //              private
72                        this.states = [false, "mixed", true];
73                        this.checked = false;
74                        this._stateLabels = {
75                                "False": '&#9633;',
76                                "True": '&#8730;',
77                                "Mixed": '&#9632;'
78                        };
79                        this.stateValues = {
80                                "False": false,
81                                "True": "on",
82                                "Mixed": "mixed"
83                        };
84                },
85               
86                _fillContent: function(/*DomNode*/ source){
87                        // Override Button::_fillContent() since it doesn't make sense for CheckBox,
88                        // since CheckBox doesn't even have a container
89                },
90               
91                postCreate: function(){
92                        domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
93                        this.inherited(arguments);
94                },
95               
96                startup: function(){
97                        this.set("checked", this.params.checked || this.states[this._currentState]);
98                        domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
99                        this.inherited(arguments);
100                },
101               
102                // Override behavior from Button, since we don't have an iconNode
103                _setIconClassAttr: null,
104               
105                _setCheckedAttr: function(/*String|Boolean*/ checked, /*Boolean?*/ priorityChange){
106                        // summary:
107                        //              Handler for checked = attribute to constructor, and also calls to
108                        //              set('checked', val).
109                        // checked:
110                        //              true, false or 'mixed'
111                        // description:
112                        //              Controls the state of the TriStateCheckBox. Set this.checked,
113                        //              this._currentState, value attribute of the `<input type=checkbox>`
114                        //              according to the value of 'checked'.                   
115                        var stateIndex = array.indexOf(this.states, checked), changed = false;
116                        if(stateIndex >= 0){
117                                this._currentState = stateIndex;
118                                this._stateType = this._getStateType(checked);
119                                domAttr.set(this.focusNode, "value", this.stateValues[this._stateType]);
120                                domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
121                                this.inherited(arguments);
122                        }else{
123                                console.warn("Invalid state!");
124                        }
125                },
126
127                setChecked: function(/*String|Boolean*/ checked){
128                        // summary:
129                        //              Deprecated.  Use set('checked', true/false) instead.
130                        kernel.deprecated("setChecked("+checked+") is deprecated. Use set('checked',"+checked+") instead.", "", "2.0");
131                        this.set('checked', checked);
132                },
133
134                _setStatesAttr: function(/*Array|String*/ states){
135                        if(lang.isArray(states)){
136                                this._set("states", states);
137                        }else if(lang.isString(states)){
138                                var map = {
139                                        "true": true,
140                                        "false": false,
141                                        "mixed": "mixed"
142                                };
143                                states = states.split(/\s*,\s*/);
144                                for(var i = 0; i < states.length; i++){
145                                        states[i] = map[states[i]] !== undefined ? map[states[i]] : false;
146                                }
147                                this._set("states", states);
148                        }
149                },
150               
151                _setReadOnlyAttr: function(/*Boolean*/ value){
152                        this._set("readOnly", value);
153                        domAttr.set(this.focusNode, "readOnly", value);
154                },
155
156                _setValueAttr: function(/*String|Boolean*/ newValue, /*Boolean*/ priorityChange){
157                        // summary:
158                        //              Handler for value = attribute to constructor, and also calls to
159                        //              set('value', val).
160                        // description:
161                        //              During initialization, just saves as attribute to the `<input type=checkbox>`.
162                        //
163                        //              After initialization,
164                        //              when passed a boolean or the string 'mixed', controls the state of the
165                        //              TriStateCheckBox.
166                        //              If passed a string except 'mixed', changes the value attribute of the
167                        //              TriStateCheckBox. Sets the state of the TriStateCheckBox to checked.
168                        if(typeof newValue == "string" && (array.indexOf(this.states, newValue) < 0)){
169                                if(newValue == ""){
170                                        newValue = "on";
171                                }
172                                this.stateValues["True"] = newValue;
173                                newValue = true;
174                        }
175                        if(this._created){
176                                this._currentState = array.indexOf(this.states, newValue);
177                                this.set('checked', newValue, priorityChange);
178                                domAttr.set(this.focusNode, "value", this.stateValues[this._stateType]);
179                        }
180                },
181
182                _setValuesAttr: function(/*Array*/ newValues){
183                        // summary:
184                        //              Handler for values = attribute to constructor, and also calls to
185                        //              set('values', val).
186                        // newValues:
187                        //              If the length of newValues is 1, it will replace the value of
188                        //              the TriStateCheckBox in true state. Otherwise, the values of
189                        //              the TriStateCheckBox in true state and 'mixed' state will be
190                        //              replaced by the first two values in newValues.
191                        // description:
192                        //              Change the value of the TriStateCheckBox in 'mixed' and true states.
193                        this.stateValues["True"] = newValues[0] ? newValues[0] : this.stateValues["True"];
194                        this.stateValues["Mixed"] = newValues[1] ? newValues[1] : this.stateValues["Mixed"];
195                },
196
197                _getValueAttr: function(){
198                        // summary:
199                        //              Hook so get('value') works.
200                        // description:
201                        //              Returns value according to current state of the TriStateCheckBox.
202                        return this.stateValues[this._stateType];
203                },
204
205                reset: function(){
206                        this._hasBeenBlurred = false;
207                        this.set("states", this.params.states || [false, "mixed", true]);
208                        this.stateValues = this.params.stateValues || {
209                                "False" : false,
210                                "True" : "on",
211                                "Mixed" : "mixed"
212                        };
213                        this.set("values", this.params.values || []);
214                        this.set('checked', this.params.checked || this.states[0]);
215                },
216
217                _onFocus: function(){
218                        if(this.id){
219                                query("label[for='"+this.id+"']").addClass("dijitFocusedLabel");
220                        }
221                        this.inherited(arguments);
222                },
223
224                _onBlur: function(){
225                        if(this.id){
226                                query("label[for='"+this.id+"']").removeClass("dijitFocusedLabel");
227                        }
228                        this.mouseFocus = false;
229                        this.inherited(arguments);
230                },
231
232                _onClick: function(/*Event*/ e){
233                        // summary:
234                        //              Internal function to handle click actions - need to check
235                        //              readOnly and disabled
236                        if(this.readOnly || this.disabled){
237                                event.stop(e);
238                                return false;
239                        }
240                        this.click();
241                        return this.onClick(e); // user click actions
242                },
243
244                click: function(){
245                        // summary:
246                        //              Emulate a click on the check box, but will not trigger the
247                        //              onClick method.
248                        if(this._currentState >= this.states.length - 1){
249                                this._currentState = 0;
250                        }else{
251                                if(this._currentState == -1){
252                                        this.fixState();
253                                }else{
254                                        this._currentState++;
255                                }
256                        }
257                        var oldState = this._currentState;
258                        this.set("checked", this.states[this._currentState]);
259                        this._currentState = oldState;
260                        domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
261                },
262               
263                fixState: function(){
264                        // summary:
265                        //              Fix _currentState property if it's out of bound.
266                        this._currentState = this.states.length - 1;
267                },
268               
269                _getStateType: function(/*String|Boolean*/ state){
270                        // summary:
271                        //              Internal function to return the type of a certain state:
272                        //
273                        //              - false: False
274                        //              - true: True
275                        //              - "mixed": Mixed
276                        return state ? (state == "mixed" ? "Mixed" : "True") : "False";
277                },
278               
279                _onMouseDown: function(){
280                        this.mouseFocus = true;
281                }
282        });
283
284});
Note: See TracBrowser for help on using the repository browser.