]> git.proxmox.com Git - extjs.git/blame - extjs/modern/modern/src/field/Checkbox.js
add extjs 6.0.1 sources
[extjs.git] / extjs / modern / modern / src / field / Checkbox.js
CommitLineData
6527f429
DM
1/**\r
2 * The checkbox field is an enhanced version of the native browser checkbox and is great for enabling your user to\r
3 * choose one or more items from a set (for example choosing toppings for a pizza order). It works like any other\r
4 * {@link Ext.field.Field field} and is usually found in the context of a form:\r
5 *\r
6 * ## Example\r
7 *\r
8 * @example miniphone preview\r
9 * var form = Ext.create('Ext.form.Panel', {\r
10 * fullscreen: true,\r
11 * items: [\r
12 * {\r
13 * xtype: 'checkboxfield',\r
14 * name : 'tomato',\r
15 * label: 'Tomato',\r
16 * value: 'tomato',\r
17 * checked: true\r
18 * },\r
19 * {\r
20 * xtype: 'checkboxfield',\r
21 * name : 'salami',\r
22 * label: 'Salami'\r
23 * },\r
24 * {\r
25 * xtype: 'toolbar',\r
26 * docked: 'bottom',\r
27 * items: [\r
28 * { xtype: 'spacer' },\r
29 * {\r
30 * text: 'getValues',\r
31 * handler: function() {\r
32 * var form = Ext.ComponentQuery.query('formpanel')[0],\r
33 * values = form.getValues();\r
34 *\r
35 * Ext.Msg.alert(null,\r
36 * "Tomato: " + ((values.tomato) ? "yes" : "no") +\r
37 * "<br />Salami: " + ((values.salami) ? "yes" : "no")\r
38 * );\r
39 * }\r
40 * },\r
41 * { xtype: 'spacer' }\r
42 * ]\r
43 * }\r
44 * ]\r
45 * });\r
46 *\r
47 *\r
48 * The form above contains two check boxes - one for Tomato, one for Salami. We configured the Tomato checkbox to be\r
49 * checked immediately on load, and the Salami checkbox to be unchecked. We also specified an optional text\r
50 * {@link #value} that will be sent when we submit the form. We can get this value using the Form's\r
51 * {@link Ext.form.Panel#getValues getValues} function, or have it sent as part of the data that is sent when the\r
52 * form is submitted:\r
53 *\r
54 * form.getValues(); //contains a key called 'tomato' if the Tomato field is still checked\r
55 * form.submit(); //will send 'tomato' in the form submission data\r
56 *\r
57 */\r
58Ext.define('Ext.field.Checkbox', {\r
59 extend: 'Ext.field.Field',\r
60 alternateClassName: 'Ext.form.Checkbox',\r
61\r
62 xtype: 'checkboxfield',\r
63 qsaLeftRe: /[\[]/g,\r
64 qsaRightRe: /[\]]/g,\r
65\r
66 isCheckbox: true,\r
67\r
68 defaultBindProperty: 'checked',\r
69\r
70 twoWayBindable: {\r
71 checked: 1\r
72 },\r
73\r
74 publishes: {\r
75 checked: 1\r
76 },\r
77\r
78 /**\r
79 * @event change\r
80 * Fires when the field value changes.\r
81 * @param {Ext.field.Checkbox} this This field.\r
82 * @param {Boolean} newValue The new value.\r
83 * @param {Boolean} oldValue The original value.\r
84 */\r
85\r
86 /**\r
87 * @event check\r
88 * Fires when the checkbox is checked.\r
89 * @param {Ext.field.Checkbox} this This checkbox.\r
90 */\r
91\r
92 /**\r
93 * @event uncheck\r
94 * Fires when the checkbox is unchecked.\r
95 * @param {Ext.field.Checkbox} this This checkbox.\r
96 */\r
97\r
98 config: {\r
99 /**\r
100 * @cfg\r
101 * @inheritdoc\r
102 */\r
103 ui: 'checkbox',\r
104\r
105 /**\r
106 * @cfg {String} value The string value to submit if the item is in a checked state.\r
107 * @accessor\r
108 */\r
109 value: '',\r
110\r
111 /**\r
112 * @cfg {Boolean} checked `true` if the checkbox should render initially checked.\r
113 * @accessor\r
114 */\r
115 checked: false,\r
116\r
117 /**\r
118 * @cfg {Number} tabIndex\r
119 * @hide\r
120 */\r
121 tabIndex: -1,\r
122\r
123 /**\r
124 * @cfg\r
125 * @inheritdoc\r
126 */\r
127 component: {\r
128 xtype: 'input',\r
129 type: 'checkbox',\r
130 useMask: true,\r
131 cls: Ext.baseCSSPrefix + 'input-checkbox'\r
132 }\r
133\r
134 /**\r
135 * @cfg {Boolean} labelMaskTap\r
136 * @private\r
137 */\r
138 },\r
139\r
140 /**\r
141 * @private\r
142 */\r
143 initialize: function() {\r
144 var me = this,\r
145 component = me.getComponent();\r
146\r
147 me.callParent();\r
148\r
149 component.on({\r
150 scope: me,\r
151 order: 'before',\r
152 masktap: 'onMaskTap'\r
153 });\r
154\r
155 component.doMaskTap = Ext.emptyFn;\r
156\r
157 me.label.on({\r
158 scope: me,\r
159 tap: 'onMaskTap'\r
160 });\r
161\r
162 // Important to publish the value here, since we\r
163 // may be relying on checked. This differs from other\r
164 // fields because the initial value may not come from\r
165 // the viewModel if it detaults to false.\r
166 me.publishState('checked', me.getChecked());\r
167 },\r
168\r
169 /**\r
170 * @private\r
171 */\r
172 doInitValue: function() {\r
173 var me = this,\r
174 initialConfig = me.getInitialConfig();\r
175\r
176 // you can have a value or checked config, but checked get priority\r
177 if (initialConfig.hasOwnProperty('value')) {\r
178 me.originalState = initialConfig.value;\r
179 }\r
180\r
181 if (initialConfig.hasOwnProperty('checked')) {\r
182 me.originalState = initialConfig.checked;\r
183 }\r
184\r
185 me.callParent(arguments);\r
186 },\r
187\r
188 /**\r
189 * @private\r
190 */\r
191 updateInputType: function(newInputType) {\r
192 var component = this.getComponent();\r
193 if (component) {\r
194 component.setType(newInputType);\r
195 }\r
196 },\r
197\r
198 /**\r
199 * @private\r
200 */\r
201 updateName: function(newName) {\r
202 var component = this.getComponent();\r
203 if (component) {\r
204 component.setName(newName);\r
205 }\r
206 },\r
207\r
208 /**\r
209 * Returns the submit value for the checkbox which can be used when submitting forms.\r
210 * @return {Boolean/String} value The value of {@link #value} or `true`, if {@link #checked}.\r
211 */\r
212 getSubmitValue: function() {\r
213 return (this.getChecked()) ? Ext.isEmpty(this._value) ? true : this._value : null;\r
214 },\r
215\r
216 updateChecked: function(checked, oldChecked) {\r
217 var me = this,\r
218 eventName;\r
219\r
220 me.getComponent().setChecked(checked);\r
221\r
222 // only call onChange (which fires events) if the component has been initialized\r
223 if (me.initialized) {\r
224 eventName = checked ? 'check' : 'uncheck';\r
225 me.fireEvent(eventName, me);\r
226 me.fireEvent('change', me, checked, oldChecked);\r
227 }\r
228 },\r
229\r
230 /**\r
231 * @private\r
232 */\r
233 onMaskTap: function(component, e) {\r
234 var me = this,\r
235 dom = me.getComponent().input.dom;\r
236\r
237 if (me.getDisabled()) {\r
238 return false;\r
239 }\r
240\r
241 //we must manually update the input dom with the new checked value\r
242 dom.checked = !dom.checked;\r
243\r
244 me.setChecked(dom.checked);\r
245\r
246 //return false so the mask does not disappear\r
247 return false;\r
248 },\r
249\r
250 /**\r
251 * Returns the checked state of the checkbox.\r
252 * @return {Boolean} `true` if checked, `false` otherwise.\r
253 */\r
254 isChecked: function() {\r
255 return this.getChecked();\r
256 },\r
257\r
258 /**\r
259 * Set the checked state of the checkbox to `true`.\r
260 * @return {Ext.field.Checkbox} This checkbox.\r
261 */\r
262 check: function() {\r
263 return this.setChecked(true);\r
264 },\r
265\r
266 /**\r
267 * Set the checked state of the checkbox to `false`.\r
268 * @return {Ext.field.Checkbox} This checkbox.\r
269 */\r
270 uncheck: function() {\r
271 return this.setChecked(false);\r
272 },\r
273\r
274 getSameGroupFields: function() {\r
275 var me = this,\r
276 component = me.up('formpanel') || me.up('fieldset'),\r
277 name = me.getName(),\r
278 replaceLeft = me.qsaLeftRe,\r
279 replaceRight = me.qsaRightRe,\r
280 //handle baseCls with multiple class values\r
281 baseCls = me.getBaseCls().split(' ').join('.'),\r
282 components = [],\r
283 elements, element, i, ln;\r
284\r
285 if (!component) {\r
286 // <debug>\r
287 Ext.Logger.warn('Ext.field.Radio components must always be descendants of an Ext.form.Panel or Ext.form.FieldSet.');\r
288 // </debug>\r
289 component = Ext.Viewport;\r
290 }\r
291\r
292 // This is to handle ComponentQuery's lack of handling [name=foo[bar]] properly\r
293 name = name.replace(replaceLeft, '\\[');\r
294 name = name.replace(replaceRight, '\\]');\r
295\r
296 elements = Ext.query('[name=' + name + ']', component.element.dom);\r
297 ln = elements.length;\r
298 for (i = 0; i < ln; i++) {\r
299 element = elements[i];\r
300 element = Ext.fly(element).up('.' + baseCls);\r
301 if (element && element.id) {\r
302 components.push(Ext.getCmp(element.id));\r
303 }\r
304 }\r
305 return components;\r
306 },\r
307\r
308 /**\r
309 * Returns an array of values from the checkboxes in the group that are checked.\r
310 * @return {Array}\r
311 */\r
312 getGroupValues: function() {\r
313 var values = [];\r
314\r
315 this.getSameGroupFields().forEach(function(field) {\r
316 if (field.getChecked()) {\r
317 values.push(field.getValue());\r
318 }\r
319 });\r
320\r
321 return values;\r
322 },\r
323\r
324 /**\r
325 * Set the status of all matched checkboxes in the same group to checked.\r
326 * @param {Array} values An array of values.\r
327 * @return {Ext.field.Checkbox} This checkbox.\r
328 */\r
329 setGroupValues: function(values) {\r
330 this.getSameGroupFields().forEach(function(field) {\r
331 field.setChecked((values.indexOf(field.getValue()) !== -1));\r
332 });\r
333\r
334 return this;\r
335 },\r
336\r
337 /**\r
338 * Resets the status of all matched checkboxes in the same group to checked.\r
339 * @return {Ext.field.Checkbox} This checkbox.\r
340 */\r
341 resetGroupValues: function() {\r
342 this.getSameGroupFields().forEach(function(field) {\r
343 field.setChecked(field.originalState);\r
344 });\r
345\r
346 return this;\r
347 },\r
348\r
349 reset: function() {\r
350 this.setChecked(this.originalState);\r
351 return this;\r
352 }\r
353});\r