]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * This mixin provides a common interface for the logical behavior and state of form fields, including:\r | |
3 | *\r | |
4 | * - Getter and setter methods for field values\r | |
5 | * - Events and methods for tracking value and validity changes\r | |
6 | * - Methods for triggering validation\r | |
7 | *\r | |
8 | * **NOTE**: When implementing custom fields, it is most likely that you will want to extend the {@link Ext.form.field.Base}\r | |
9 | * component class rather than using this mixin directly, as BaseField contains additional logic for generating an\r | |
10 | * actual DOM complete with {@link Ext.form.Labelable label and error message} display and a form input field,\r | |
11 | * plus methods that bind the Field value getters and setters to the input field's value.\r | |
12 | *\r | |
13 | * If you do want to implement this mixin directly and don't want to extend {@link Ext.form.field.Base}, then\r | |
14 | * you will most likely want to override the following methods with custom implementations: {@link #getValue},\r | |
15 | * {@link #setValue}, and {@link #getErrors}. Other methods may be overridden as needed but their base\r | |
16 | * implementations should be sufficient for common cases. You will also need to make sure that {@link #initField}\r | |
17 | * is called during the component's initialization.\r | |
18 | */\r | |
19 | Ext.define('Ext.form.field.Field', {\r | |
20 | mixinId: 'field',\r | |
21 | \r | |
22 | /**\r | |
23 | * @property {Boolean} isFormField\r | |
24 | * Flag denoting that this component is a Field. Always true.\r | |
25 | */\r | |
26 | isFormField : true,\r | |
27 | \r | |
28 | config: {\r | |
29 | /**\r | |
30 | * @cfg {Boolean/String} validation\r | |
31 | * This property, when a `String`, contributes its value to the error state of this\r | |
32 | * instance as reported by `getErrors`.\r | |
33 | */\r | |
34 | validation: null,\r | |
35 | \r | |
36 | /**\r | |
37 | * @cfg {Ext.data.Field} validationField\r | |
38 | * When binding is used with a model, this maps to the underlying {@link Ext.data.field.Field} if\r | |
39 | * it is available. This can be used to validate the value against the model field without needing\r | |
40 | * to push the value back into the model.\r | |
41 | *\r | |
42 | * @private\r | |
43 | */\r | |
44 | validationField: null\r | |
45 | },\r | |
46 | \r | |
47 | /**\r | |
48 | * @cfg {Object} value\r | |
49 | * A value to initialize this field with.\r | |
50 | */\r | |
51 | \r | |
52 | /**\r | |
53 | * @cfg {String} name\r | |
54 | * The name of the field. By default this is used as the parameter name when including the\r | |
55 | * {@link #getSubmitData field value} in a {@link Ext.form.Basic#submit form submit()}. To prevent the field from\r | |
56 | * being included in the form submit, set {@link #submitValue} to false.\r | |
57 | */\r | |
58 | \r | |
59 | /**\r | |
60 | * @cfg {Boolean} disabled\r | |
61 | * True to disable the field. Disabled Fields will not be {@link Ext.form.Basic#submit submitted}.\r | |
62 | */\r | |
63 | disabled : false,\r | |
64 | \r | |
65 | /**\r | |
66 | * @cfg {Boolean} submitValue\r | |
67 | * Setting this to false will prevent the field from being {@link Ext.form.Basic#submit submitted} even when it is\r | |
68 | * not disabled.\r | |
69 | */\r | |
70 | submitValue: true,\r | |
71 | \r | |
72 | /**\r | |
73 | * @cfg {Boolean} validateOnChange\r | |
74 | * Specifies whether this field should be validated immediately whenever a change in its value is detected.\r | |
75 | * If the validation results in a change in the field's validity, a {@link #validitychange} event will be\r | |
76 | * fired. This allows the field to show feedback about the validity of its contents immediately as the user is\r | |
77 | * typing.\r | |
78 | *\r | |
79 | * When set to false, feedback will not be immediate. However the form will still be validated before submitting if\r | |
80 | * the clientValidation option to {@link Ext.form.Basic#doAction} is enabled, or if the field or form are validated\r | |
81 | * manually.\r | |
82 | *\r | |
83 | * See also {@link Ext.form.field.Base#checkChangeEvents} for controlling how changes to the field's value are\r | |
84 | * detected.\r | |
85 | */\r | |
86 | validateOnChange: true,\r | |
87 | \r | |
88 | /**\r | |
89 | * @cfg {String[]/String} valuePublishEvent\r | |
90 | * The event name(s) to use to publish the {@link #value}\r | |
91 | * {@link Ext.form.field.Base#bind} for this field.\r | |
92 | * @since 5.0.1\r | |
93 | */\r | |
94 | valuePublishEvent: 'change',\r | |
95 | \r | |
96 | /**\r | |
97 | * @private\r | |
98 | */\r | |
99 | suspendCheckChange: 0,\r | |
100 | \r | |
101 | /**\r | |
102 | * @property {Boolean} dirty\r | |
103 | * The dirty state of the field.\r | |
104 | * @private\r | |
105 | */\r | |
106 | dirty: false,\r | |
107 | \r | |
108 | /**\r | |
109 | * @event change\r | |
110 | * Fires when the value of a field is changed. The value of a field is \r | |
111 | * checked for changes when the field's {@link #setValue} method \r | |
112 | * is called and when any of the events listed in \r | |
113 | * {@link Ext.form.field.Base#checkChangeEvents checkChangeEvents} are fired.\r | |
114 | * @param {Ext.form.field.Field} this\r | |
115 | * @param {Object} newValue The new value\r | |
116 | * @param {Object} oldValue The original value\r | |
117 | */\r | |
118 | \r | |
119 | /**\r | |
120 | * @event validitychange\r | |
121 | * Fires when a change in the field's validity is detected.\r | |
122 | * @param {Ext.form.field.Field} this\r | |
123 | * @param {Boolean} isValid Whether or not the field is now valid\r | |
124 | */\r | |
125 | \r | |
126 | /**\r | |
127 | * @event dirtychange\r | |
128 | * Fires when a change in the field's {@link #isDirty} state is detected.\r | |
129 | * @param {Ext.form.field.Field} this\r | |
130 | * @param {Boolean} isDirty Whether or not the field is now dirty\r | |
131 | */\r | |
132 | \r | |
133 | /**\r | |
134 | * Initializes this Field mixin on the current instance. Components using this mixin should call this method during\r | |
135 | * their own initialization process.\r | |
136 | */\r | |
137 | initField: function() {\r | |
138 | var me = this,\r | |
139 | valuePublishEvent = me.valuePublishEvent,\r | |
140 | len, i;\r | |
141 | \r | |
142 | me.initValue();\r | |
143 | \r | |
144 | //<debug>\r | |
145 | var badNames = [\r | |
146 | 'tagName',\r | |
147 | 'nodeName',\r | |
148 | 'children',\r | |
149 | 'childNodes'\r | |
150 | ], name = this.name;\r | |
151 | \r | |
152 | if (name && Ext.Array.indexOf(badNames, name) > -1) {\r | |
153 | Ext.log.warn(\r | |
154 | ['It is recommended to not use "', name, '" as a field name, because it ',\r | |
155 | 'can cause naming collisions during form submission.'].join('')\r | |
156 | );\r | |
157 | }\r | |
158 | //</debug>\r | |
159 | \r | |
160 | // Vast majority of cases won't be an array\r | |
161 | if (Ext.isString(valuePublishEvent)) {\r | |
162 | me.on(valuePublishEvent, me.publishValue, me);\r | |
163 | } else {\r | |
164 | for (i = 0, len = valuePublishEvent.length; i < len; ++i) {\r | |
165 | me.on(valuePublishEvent[i], me.publishValue, me);\r | |
166 | }\r | |
167 | }\r | |
168 | },\r | |
169 | \r | |
170 | /**\r | |
171 | * Initializes the field's value based on the initial config.\r | |
172 | */\r | |
173 | initValue: function() {\r | |
174 | var me = this;\r | |
175 | \r | |
176 | // Set the initial value if we have one.\r | |
177 | // Prevent validation on initial set.\r | |
178 | if ('value' in me) {\r | |
179 | me.suspendCheckChange++;\r | |
180 | me.setValue(me.value);\r | |
181 | me.suspendCheckChange--;\r | |
182 | }\r | |
183 | \r | |
184 | /**\r | |
185 | * @property {Object} originalValue\r | |
186 | * The original value of the field as configured in the {@link #value} configuration, or as loaded by the last\r | |
187 | * form load operation if the form's {@link Ext.form.Basic#trackResetOnLoad trackResetOnLoad} setting is `true`.\r | |
188 | */\r | |
189 | me.initialValue = me.originalValue = me.lastValue = me.getValue();\r | |
190 | },\r | |
191 | \r | |
192 | // Fields can be editors, and some editors may not have a name property that maps\r | |
193 | // to its data index, so it's necessary in these cases to look it up by its dataIndex\r | |
194 | // property. See EXTJSIV-11650.\r | |
195 | getFieldIdentifier: function () {\r | |
196 | return this.isEditorComponent ? this.dataIndex : this.name;\r | |
197 | },\r | |
198 | \r | |
199 | /**\r | |
200 | * Returns the {@link Ext.form.field.Field#name name} attribute of the field. This is used as the parameter name\r | |
201 | * when including the field value in a {@link Ext.form.Basic#submit form submit()}.\r | |
202 | * @return {String} name The field {@link Ext.form.field.Field#name name}\r | |
203 | */\r | |
204 | getName: function() {\r | |
205 | return this.name;\r | |
206 | },\r | |
207 | \r | |
208 | /**\r | |
209 | * Returns the current data value of the field. The type of value returned is particular to the type of the\r | |
210 | * particular field (e.g. a Date object for {@link Ext.form.field.Date}).\r | |
211 | * @return {Object} value The field value\r | |
212 | */\r | |
213 | getValue: function() {\r | |
214 | return this.value;\r | |
215 | },\r | |
216 | \r | |
217 | /**\r | |
218 | * Sets a data value into the field and runs the change detection and validation.\r | |
219 | * @param {Object} value The value to set\r | |
220 | * @return {Ext.form.field.Field} this\r | |
221 | */\r | |
222 | setValue: function(value) {\r | |
223 | var me = this;\r | |
224 | me.value = value;\r | |
225 | me.checkChange();\r | |
226 | return me;\r | |
227 | },\r | |
228 | \r | |
229 | /**\r | |
230 | * Returns whether two field {@link #getValue values} are logically equal. Field implementations may override this\r | |
231 | * to provide custom comparison logic appropriate for the particular field's data type.\r | |
232 | * @param {Object} value1 The first value to compare\r | |
233 | * @param {Object} value2 The second value to compare\r | |
234 | * @return {Boolean} True if the values are equal, false if inequal.\r | |
235 | */\r | |
236 | isEqual: function(value1, value2) {\r | |
237 | return String(value1) === String(value2);\r | |
238 | },\r | |
239 | \r | |
240 | /**\r | |
241 | * Returns whether two values are logically equal.\r | |
242 | * Similar to {@link #isEqual}, however null or undefined values will be treated as empty strings.\r | |
243 | * @private\r | |
244 | * @param {Object} value1 The first value to compare\r | |
245 | * @param {Object} value2 The second value to compare\r | |
246 | * @return {Boolean} True if the values are equal, false if inequal.\r | |
247 | */\r | |
248 | isEqualAsString: function(value1, value2){\r | |
249 | return String(Ext.valueFrom(value1, '')) === String(Ext.valueFrom(value2, ''));\r | |
250 | },\r | |
251 | \r | |
252 | /**\r | |
253 | * Returns the parameter(s) that would be included in a standard form submit for this field. Typically this will be\r | |
254 | * an object with a single name-value pair, the name being this field's {@link #getName name} and the value being\r | |
255 | * its current stringified value. More advanced field implementations may return more than one name-value pair.\r | |
256 | *\r | |
257 | * Note that the values returned from this method are not guaranteed to have been successfully {@link #validate\r | |
258 | * validated}.\r | |
259 | *\r | |
260 | * @return {Object} A mapping of submit parameter names to values; each value should be a string, or an array of\r | |
261 | * strings if that particular name has multiple values. It can also return null if there are no parameters to be\r | |
262 | * submitted.\r | |
263 | */\r | |
264 | getSubmitData: function() {\r | |
265 | var me = this,\r | |
266 | data = null;\r | |
267 | if (!me.disabled && me.submitValue) {\r | |
268 | data = {};\r | |
269 | data[me.getName()] = '' + me.getValue();\r | |
270 | }\r | |
271 | return data;\r | |
272 | },\r | |
273 | \r | |
274 | /**\r | |
275 | * Returns the value(s) that should be saved to the {@link Ext.data.Model} instance for this field, when {@link\r | |
276 | * Ext.form.Basic#updateRecord} is called. Typically this will be an object with a single name-value pair, the name\r | |
277 | * being this field's {@link #getName name} and the value being its current data value. More advanced field\r | |
278 | * implementations may return more than one name-value pair. The returned values will be saved to the corresponding\r | |
279 | * field names in the Model.\r | |
280 | *\r | |
281 | * Note that the values returned from this method are not guaranteed to have been successfully {@link #validate\r | |
282 | * validated}.\r | |
283 | *\r | |
284 | * @return {Object} A mapping of submit parameter names to values; each value should be a string, or an array of\r | |
285 | * strings if that particular name has multiple values. It can also return null if there are no parameters to be\r | |
286 | * submitted.\r | |
287 | */\r | |
288 | getModelData: function(includeEmptyText, /*private*/ isSubmitting) {\r | |
289 | var me = this,\r | |
290 | data = null;\r | |
291 | \r | |
292 | // Note that we need to check if this operation is being called from a Submit action because displayfields aren't\r | |
293 | // to be submitted, but they can call this to get their model data.\r | |
294 | if (!me.disabled && (me.submitValue || !isSubmitting)) {\r | |
295 | data = {};\r | |
296 | data[me.getFieldIdentifier()] = me.getValue();\r | |
297 | }\r | |
298 | return data;\r | |
299 | },\r | |
300 | \r | |
301 | /**\r | |
302 | * Resets the current field value to the originally loaded value and clears any validation messages. See {@link\r | |
303 | * Ext.form.Basic}.{@link Ext.form.Basic#trackResetOnLoad trackResetOnLoad}\r | |
304 | */\r | |
305 | reset: function(){\r | |
306 | var me = this;\r | |
307 | \r | |
308 | me.beforeReset();\r | |
309 | me.setValue(me.originalValue);\r | |
310 | me.clearInvalid();\r | |
311 | // delete here so we reset back to the original state\r | |
312 | delete me.wasValid;\r | |
313 | },\r | |
314 | \r | |
315 | /**\r | |
316 | * Template method before a field is reset.\r | |
317 | * @protected\r | |
318 | */\r | |
319 | beforeReset: Ext.emptyFn,\r | |
320 | \r | |
321 | /**\r | |
322 | * Resets the field's {@link #originalValue} property so it matches the current {@link #getValue value}. This is\r | |
323 | * called by {@link Ext.form.Basic}.{@link Ext.form.Basic#setValues setValues} if the form's\r | |
324 | * {@link Ext.form.Basic#trackResetOnLoad trackResetOnLoad} property is set to true.\r | |
325 | */\r | |
326 | resetOriginalValue: function() {\r | |
327 | this.originalValue = this.getValue();\r | |
328 | this.checkDirty();\r | |
329 | },\r | |
330 | \r | |
331 | /**\r | |
332 | * Checks whether the value of the field has changed since the last time it was checked.\r | |
333 | * If the value has changed, it:\r | |
334 | *\r | |
335 | * 1. Fires the {@link #change change event},\r | |
336 | * 2. Performs validation if the {@link #validateOnChange} config is enabled, firing the\r | |
337 | * {@link #validitychange validitychange event} if the validity has changed, and\r | |
338 | * 3. Checks the {@link #isDirty dirty state} of the field and fires the {@link #dirtychange dirtychange event}\r | |
339 | * if it has changed.\r | |
340 | */\r | |
341 | checkChange: function() {\r | |
342 | var me = this,\r | |
343 | newVal, oldVal;\r | |
344 | \r | |
345 | if (!me.suspendCheckChange) {\r | |
346 | newVal = me.getValue();\r | |
347 | oldVal = me.lastValue;\r | |
348 | \r | |
349 | if (!me.destroyed && me.didValueChange(newVal, oldVal)) {\r | |
350 | me.lastValue = newVal;\r | |
351 | me.fireEvent('change', me, newVal, oldVal);\r | |
352 | me.onChange(newVal, oldVal);\r | |
353 | }\r | |
354 | }\r | |
355 | },\r | |
356 | \r | |
357 | /**\r | |
358 | * @private\r | |
359 | * Checks if the value has changed. Allows subclasses to override for\r | |
360 | * any more complex logic.\r | |
361 | */\r | |
362 | didValueChange: function(newVal, oldVal){\r | |
363 | return !this.isEqual(newVal, oldVal);\r | |
364 | },\r | |
365 | \r | |
366 | /**\r | |
367 | * @private\r | |
368 | * Called when the field's value changes. Performs validation if the {@link #validateOnChange}\r | |
369 | * config is enabled, and invokes the dirty check.\r | |
370 | */\r | |
371 | onChange: function (newVal) {\r | |
372 | var me = this;\r | |
373 | \r | |
374 | if (me.validateOnChange) {\r | |
375 | me.validate();\r | |
376 | }\r | |
377 | \r | |
378 | me.checkDirty();\r | |
379 | },\r | |
380 | \r | |
381 | /**\r | |
382 | * Publish the value of this field.\r | |
383 | *\r | |
384 | * @private\r | |
385 | */\r | |
386 | publishValue: function () {\r | |
387 | var me = this;\r | |
388 | \r | |
389 | if (me.rendered && !me.getErrors().length) {\r | |
390 | me.publishState('value', me.getValue());\r | |
391 | }\r | |
392 | },\r | |
393 | \r | |
394 | /**\r | |
395 | * Returns true if the value of this Field has been changed from its {@link #originalValue}.\r | |
396 | * Will always return false if the field is disabled.\r | |
397 | *\r | |
398 | * Note that if the owning {@link Ext.form.Basic form} was configured with\r | |
399 | * {@link Ext.form.Basic#trackResetOnLoad trackResetOnLoad} then the {@link #originalValue} is updated when\r | |
400 | * the values are loaded by {@link Ext.form.Basic}.{@link Ext.form.Basic#setValues setValues}.\r | |
401 | * @return {Boolean} True if this field has been changed from its original value (and is not disabled),\r | |
402 | * false otherwise.\r | |
403 | */\r | |
404 | isDirty : function() {\r | |
405 | var me = this;\r | |
406 | return !me.disabled && !me.isEqual(me.getValue(), me.originalValue);\r | |
407 | },\r | |
408 | \r | |
409 | /**\r | |
410 | * Checks the {@link #isDirty} state of the field and if it has changed since the last time it was checked,\r | |
411 | * fires the {@link #dirtychange} event.\r | |
412 | */\r | |
413 | checkDirty: function() {\r | |
414 | var me = this,\r | |
415 | isDirty = me.isDirty();\r | |
416 | \r | |
417 | if (isDirty !== me.wasDirty) {\r | |
418 | me.dirty = isDirty;\r | |
419 | me.fireEvent('dirtychange', me, isDirty);\r | |
420 | me.onDirtyChange(isDirty);\r | |
421 | me.wasDirty = isDirty;\r | |
422 | }\r | |
423 | },\r | |
424 | \r | |
425 | /**\r | |
426 | * @method\r | |
427 | * @private\r | |
428 | * Called when the field's dirty state changes.\r | |
429 | * @param {Boolean} isDirty\r | |
430 | */\r | |
431 | onDirtyChange: Ext.emptyFn,\r | |
432 | \r | |
433 | /**\r | |
434 | * Runs this field's validators and returns an array of error messages for any validation failures. This is called\r | |
435 | * internally during validation and would not usually need to be used manually.\r | |
436 | *\r | |
437 | * Each subclass should override or augment the return value to provide their own errors.\r | |
438 | *\r | |
439 | * @param {Object} value The value to get errors for (defaults to the current field value)\r | |
440 | * @return {String[]} All error messages for this field; an empty Array if none.\r | |
441 | */\r | |
442 | getErrors: function (value) {\r | |
443 | var errors = [],\r | |
444 | validationField = this.getValidationField(),\r | |
445 | validation = this.getValidation(),\r | |
446 | result;\r | |
447 | \r | |
448 | if (validationField) {\r | |
449 | result = validationField.validate(value);\r | |
450 | if (result !== true) {\r | |
451 | errors.push(result);\r | |
452 | }\r | |
453 | }\r | |
454 | \r | |
455 | if (validation && validation !== true) {\r | |
456 | errors.push(validation);\r | |
457 | }\r | |
458 | \r | |
459 | return errors;\r | |
460 | },\r | |
461 | \r | |
462 | /**\r | |
463 | * Returns whether or not the field value is currently valid by {@link #getErrors validating} the field's current\r | |
464 | * value. The {@link #validitychange} event will not be fired; use {@link #validate} instead if you want the event\r | |
465 | * to fire. **Note**: {@link #disabled} fields are always treated as valid.\r | |
466 | *\r | |
467 | * Implementations are encouraged to ensure that this method does not have side-effects such as triggering error\r | |
468 | * message display.\r | |
469 | *\r | |
470 | * @return {Boolean} True if the value is valid, else false\r | |
471 | */\r | |
472 | isValid : function() {\r | |
473 | var me = this;\r | |
474 | return me.disabled || Ext.isEmpty(me.getErrors());\r | |
475 | },\r | |
476 | \r | |
477 | /**\r | |
478 | * Returns whether or not the field value is currently valid by {@link #getErrors validating} the field's current\r | |
479 | * value, and fires the {@link #validitychange} event if the field's validity has changed since the last validation.\r | |
480 | * **Note**: {@link #disabled} fields are always treated as valid.\r | |
481 | *\r | |
482 | * Custom implementations of this method are allowed to have side-effects such as triggering error message display.\r | |
483 | * To validate without side-effects, use {@link #isValid}.\r | |
484 | *\r | |
485 | * @return {Boolean} True if the value is valid, else false\r | |
486 | */\r | |
487 | validate : function() {\r | |
488 | return this.checkValidityChange(this.isValid());\r | |
489 | },\r | |
490 | \r | |
491 | checkValidityChange: function(isValid) {\r | |
492 | var me = this;\r | |
493 | \r | |
494 | if (isValid !== me.wasValid) {\r | |
495 | me.wasValid = isValid;\r | |
496 | me.fireEvent('validitychange', me, isValid);\r | |
497 | }\r | |
498 | return isValid;\r | |
499 | },\r | |
500 | \r | |
501 | /**\r | |
502 | * A utility for grouping a set of modifications which may trigger value changes into a single transaction, to\r | |
503 | * prevent excessive firing of {@link #change} events. This is useful for instance if the field has sub-fields which\r | |
504 | * are being updated as a group; you don't want the container field to check its own changed state for each subfield\r | |
505 | * change.\r | |
506 | * @param {Function} fn The function to call with change checks suspended.\r | |
507 | */\r | |
508 | batchChanges: function(fn) {\r | |
509 | try {\r | |
510 | this.suspendCheckChange++;\r | |
511 | fn();\r | |
512 | }\r | |
513 | catch (pseudo) { //required with IE when using 'try'\r | |
514 | throw pseudo;\r | |
515 | }\r | |
516 | finally {\r | |
517 | this.suspendCheckChange--;\r | |
518 | }\r | |
519 | this.checkChange();\r | |
520 | },\r | |
521 | \r | |
522 | /**\r | |
523 | * Returns whether this Field is a file upload field; if it returns true, forms will use special techniques for\r | |
524 | * {@link Ext.form.Basic#submit submitting the form} via AJAX. See {@link Ext.form.Basic#hasUpload} for details. If\r | |
525 | * this returns true, the {@link #extractFileInput} method must also be implemented to return the corresponding file\r | |
526 | * input element.\r | |
527 | * @return {Boolean}\r | |
528 | */\r | |
529 | isFileUpload: function() {\r | |
530 | return false;\r | |
531 | },\r | |
532 | \r | |
533 | /**\r | |
534 | * Only relevant if the instance's {@link #isFileUpload} method returns true. Returns a reference to the file input\r | |
535 | * DOM element holding the user's selected file. The input will be appended into the submission form and will not be\r | |
536 | * returned, so this method should also create a replacement.\r | |
537 | * @return {HTMLElement}\r | |
538 | */\r | |
539 | extractFileInput: function() {\r | |
540 | return null;\r | |
541 | },\r | |
542 | \r | |
543 | /**\r | |
544 | * @method\r | |
545 | * Display one or more error messages associated with this field, using \r | |
546 | * {@link Ext.form.Labelable#msgTarget} to determine how to display the messages and \r | |
547 | * applying {@link Ext.form.Labelable#invalidCls} to the field's UI element.\r | |
548 | *\r | |
549 | * var formPanel = Ext.create('Ext.form.Panel', {\r | |
550 | * title: 'Contact Info',\r | |
551 | * width: 300,\r | |
552 | * bodyPadding: 10,\r | |
553 | * renderTo: Ext.getBody(),\r | |
554 | * items: [{\r | |
555 | * xtype: 'textfield',\r | |
556 | * name: 'name',\r | |
557 | * id: 'nameId',\r | |
558 | * fieldLabel: 'Name'\r | |
559 | * }],\r | |
560 | * bbar: [{\r | |
561 | * text: 'Mark both fields invalid',\r | |
562 | * handler: function() {\r | |
563 | * var nameField = formPanel.getForm().findField('name');\r | |
564 | * nameField.markInvalid('Name invalid message');\r | |
565 | * \r | |
566 | * // multiple error string syntax\r | |
567 | * // nameField.markInvalid(['First message', 'Second message']);\r | |
568 | * }\r | |
569 | * }]\r | |
570 | * });\r | |
571 | * \r | |
572 | * **Note**: this method does not cause the Field's {@link #validate} or \r | |
573 | * {@link #isValid} methods to return `false` if the value does _pass_ validation. \r | |
574 | * So simply marking a Field as invalid will not prevent submission of forms\r | |
575 | * submitted with the {@link Ext.form.action.Submit#clientValidation} option set.\r | |
576 | * \r | |
577 | * @param {String/String[]} errors The validation message(s) to display.\r | |
578 | */\r | |
579 | markInvalid: Ext.emptyFn,\r | |
580 | \r | |
581 | /**\r | |
582 | * @method clearInvalid\r | |
583 | * Clear any invalid styles/messages for this field. Components using this mixin should implement this method to\r | |
584 | * update the components rendering to clear any existing messages.\r | |
585 | *\r | |
586 | * **Note**: this method does not cause the Field's {@link #validate} or {@link #isValid} methods to return `true`\r | |
587 | * if the value does not _pass_ validation. So simply clearing a field's errors will not necessarily allow\r | |
588 | * submission of forms submitted with the {@link Ext.form.action.Submit#clientValidation} option set.\r | |
589 | */\r | |
590 | clearInvalid: Ext.emptyFn,\r | |
591 | \r | |
592 | updateValidation: function(validation, oldValidation) {\r | |
593 | // Only validate if the validation is changing, not when we initial set it,\r | |
594 | // otherwise it will mark the field invalid as soon as it is bound.\r | |
595 | if (oldValidation) {\r | |
596 | this.validate(); \r | |
597 | }\r | |
598 | },\r | |
599 | \r | |
600 | privates: {\r | |
601 | resetToInitialValue: function() {\r | |
602 | var me = this,\r | |
603 | originalValue = me.originalValue;\r | |
604 | \r | |
605 | me.originalValue = me.initialValue;\r | |
606 | me.reset();\r | |
607 | me.originalValue = originalValue;\r | |
608 | }\r | |
609 | }\r | |
610 | });\r |