summaryrefslogtreecommitdiff
path: root/js/dojo/dojox/form/TriStateCheckBox.js
blob: 04ccff2ee61f72e32fc566bd35285382182a2bbd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
//>>built
require({cache:{
'url:dojox/form/resources/TriStateCheckBox.html':"<div class=\"dijit dijitReset dijitInline\" role=\"presentation\"\n\t><div class=\"dojoxTriStateCheckBoxInner\" dojoAttachPoint=\"stateLabelNode\"></div\n\t><input ${!nameAttrSetting} type=\"${type}\" dojoAttachPoint=\"focusNode\"\n\tclass=\"dijitReset dojoxTriStateCheckBoxInput\" dojoAttachEvent=\"onclick:_onClick\"\n/></div>"}});
define("dojox/form/TriStateCheckBox", [
	"dojo/_base/kernel",
	"dojo/_base/declare",
	"dojo/_base/array",
	"dojo/_base/event",
	"dojo/query",
	"dojo/dom-attr",
	"dojo/text!./resources/TriStateCheckBox.html",
	"dijit/form/ToggleButton"
], function(kernel, declare, array, event, query, domAttr, template, ToggleButton){
//	module:
//		dojox/form/TriStateCheckBox
//	summary:
//		Checkbox with three states
//

	/*=====
		ToggleButton = dijit.form.ToggleButton;
	=====*/
return declare("dojox.form.TriStateCheckBox", ToggleButton,
	{
		// summary:
		//		Checkbox with three states

		templateString: template,

		baseClass: "dojoxTriStateCheckBox",

		// type: [private] String
		//		type attribute on <input> node.
		//		Overrides `dijit.form.Button.type`.  Users should not change this value.
		type: "checkbox",

		/*=====
		// states: Array
		//		States of TriStateCheckBox.
		//		The value of This.checked should be one of these three states.
		states: [false, true, "mixed"],
		=====*/

		/*=====
		// _stateLabels: Object
		//		These characters are used to replace the image to show
		//		current state of TriStateCheckBox in high contrast mode.
		_stateLabels: {
				"False": '&#63219',
				"True": '&#8730;',
				"Mixed": '&#8801'
		},
		=====*/

		/*=====
		// stateValues: Object
		//		The values of the TriStateCheckBox in corresponding states.
		stateValues:	{
				"False": "off",
				"True": "on",
				"Mixed": "mixed"
		},
		=====*/

		// _currentState: Integer
		//		The current state of the TriStateCheckBox
		_currentState: 0,

		// _stateType: String
		//		The current state type of the TriStateCheckBox
		//		Could be "False", "True" or "Mixed"
		_stateType: "False",

		// readOnly: Boolean
		//		Should this widget respond to user input?
		//		In markup, this is specified as "readOnly".
		//		Similar to disabled except readOnly form values are submitted.
		readOnly: false,

		constructor: function(){
			// summary:
			//		Runs on widget initialization to setup arrays etc.
			// tags:
			//		private
			this.states = [false, true, "mixed"];
			this._stateLabels = {
				"False": '&#63219',
				"True": '&#8730;',
				"Mixed": '&#8801'
			};
			this.stateValues = {
				"False": "off",
				"True": "on",
				"Mixed": "mixed"
			};
		},

		// Override behavior from Button, since we don't have an iconNode
		_setIconClassAttr: null,

		_setCheckedAttr: function(/*String|Boolean*/ checked, /*Boolean?*/ priorityChange){
			// summary:
			//		Handler for checked = attribute to constructor, and also calls to
			//		set('checked', val).
			// checked:
			//		true, false or 'mixed'
			// description:
			//		Controls the state of the TriStateCheckBox. Set this.checked,
			//		this._currentState, value attribute of the <input type=checkbox>
			//		according to the value of 'checked'.
			this._set("checked", checked);
			this._currentState = array.indexOf(this.states, checked);
			this._stateType = this._getStateType(checked);
			domAttr.set(this.focusNode || this.domNode, "checked", checked);
			domAttr.set(this.focusNode, "value", this.stateValues[this._stateType]);
			(this.focusNode || this.domNode).setAttribute("aria-checked", checked);
			this._handleOnChange(checked, priorityChange);
		},

		setChecked: function(/*String|Boolean*/ checked){
			// summary:
			//		Deprecated.  Use set('checked', true/false) instead.
			kernel.deprecated("setChecked("+checked+") is deprecated. Use set('checked',"+checked+") instead.", "", "2.0");
			this.set('checked', checked);
		},

		_setReadOnlyAttr: function(/*Boolean*/ value){
			this._set("readOnly", value);
			domAttr.set(this.focusNode, "readOnly", value);
			this.focusNode.setAttribute("aria-readonly", value);
		},

		_setValueAttr: function(/*String|Boolean*/ newValue, /*Boolean*/ priorityChange){
			// summary:
			//		Handler for value = attribute to constructor, and also calls to
			//		set('value', val).
			// description:
			//		During initialization, just saves as attribute to the <input type=checkbox>.
			//
			//		After initialization,
			//		when passed a boolean or the string 'mixed', controls the state of the
			//		TriStateCheckBox.
			//		If passed a string except 'mixed', changes the value attribute of the
			//		TriStateCheckBox. Sets the state of the TriStateCheckBox to checked.
			if(typeof newValue == "string" && (array.indexOf(this.states, newValue) < 0)){
				if(newValue == ""){
					newValue = "on";
				}
				this.stateValues["True"] = newValue;
				newValue = true;
			}
			if(this._created){
				this._currentState = array.indexOf(this.states, newValue);
				this.set('checked', newValue, priorityChange);
				domAttr.set(this.focusNode, "value", this.stateValues[this._stateType]);
			}
		},

		_setValuesAttr: function(/*Array*/ newValues){
			// summary:
			//		Handler for values = attribute to constructor, and also calls to
			//		set('values', val).
			// newValues:
			//		If the length of newValues is 1, it will replace the value of
			//		the TriStateCheckBox in true state. Otherwise, the values of
			//		the TriStateCheckBox in true state and 'mixed' state will be
			//		replaced by the first two values in newValues.
			// description:
			//		Change the value of the TriStateCheckBox in 'mixed' and true states.
			this.stateValues["True"] = newValues[0] ? newValues[0] : this.stateValues["True"];
			this.stateValues["Mixed"] = newValues[1] ? newValues[1] : this.stateValues["False"];
		},

		_getValueAttr: function(){
			// summary:
			//		Hook so get('value') works.
			// description:
			//		Returns value according to current state of the TriStateCheckBox.
			return this.stateValues[this._stateType];
		},

		startup: function(){
			this.set("checked", this.params.checked || this.states[this._currentState]);
			domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
			this.inherited(arguments);
		},

		 _fillContent: function(/*DomNode*/ source){
			// Override Button::_fillContent() since it doesn't make sense for CheckBox,
			// since CheckBox doesn't even have a container
		},

		reset: function(){
			this._hasBeenBlurred = false;
			this.stateValues = {
				"False" : "off",
				"True" : "on",
				"Mixed" : "mixed"
			};
			this.set('checked', this.params.checked || this.states[0]);
		},

		_onFocus: function(){
			if(this.id){
				query("label[for='"+this.id+"']").addClass("dijitFocusedLabel");
			}
			this.inherited(arguments);
		},

		_onBlur: function(){
			if(this.id){
				query("label[for='"+this.id+"']").removeClass("dijitFocusedLabel");
			}
			this.inherited(arguments);
		},

		_onClick: function(/*Event*/ e){
			// summary:
			//		Internal function to handle click actions - need to check
			//		readOnly and disabled
			if(this.readOnly || this.disabled){
				event.stop(e);
				return false;
			}
			if(this._currentState >= this.states.length - 1){
				this._currentState = 0;
			}else{
				this._currentState++;
			}
			this.set("checked", this.states[this._currentState]);
			domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
			return this.onClick(e); // user click actions
		},

		_getStateType: function(/*String|Boolean*/ state){
			//	summary:
			//		Internal function to return the type of a certain state
			//		false: False
			//		true: True
			//		"mixed": Mixed
			return state ? (state == "mixed" ? "Mixed" : "True") : "False";
		}
	}
);

});