]>
Commit | Line | Data |
---|---|---|
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 | |
58 | Ext.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 |