/** * @class Ext.form.Field *

This mixin provides a common interface for the logical behavior of form fields, including:

* *

When implementing custom fields, it is likely that you will want to extend the {@link Ext.form.BaseField} * component class rather than using this mixin directly, as it contains additional logic for generating an * actual DOM complete with {@link Ext.form.Labelable label and error message} display.

*

If you want to implement this mixin directly and don't want to extend {@link Ext.form.BaseField}, then * you will most likely want to override the following methods with custom implementations: {@link #getRawValue}, * {@link #setRawValue}, and {@link #getErrors}. If your field implementation handles custom data types you may * also want to override {@link #valueToRaw} and {@link #rawToValue}. Other methods may be overridden as needed * but their base implementations should be sufficient for common cases.

*/ Ext.define('Ext.form.Field', {
/** * @property isFormField * @type {Boolean} * Flag denoting that this component is a Field. Always true. */ isFormField : true,
/** * @cfg {Mixed} value A value to initialize this field with (defaults to undefined). */
/** * @cfg {String} name The name of the field (defaults to undefined). This is used as the parameter * name when including the field value in a {@link Ext.form.Basic#submit form submit()}. If no name is * configured, it falls back to the {@link #inputId}. To prevent the field from being included in the * form submit, set {@link #submitValue} to false. */
/** * @cfg {Boolean} disabled True to disable the field (defaults to false). Disabled Fields will not be * {@link Ext.form.Basic#submit submitted}.

*/ disabled : false,
/** * @cfg {Boolean} submitValue Setting this to false will prevent the field from being * {@link Ext.form.Basic#submit submitted} even when it is not disabled. Defaults to true. */ submitValue: true,
/** * @cfg {Boolean} validateOnChange *

Specifies whether this field should be validated immediately whenever a change in its value is detected. * Defaults to true. If the validation results in a change in the field's validity, a * {@link #validitychange} event will be fired. This allows the field to show feedback about the * validity of its contents immediately as the user is typing.

*

When set to false, feedback will not be immediate. However the form will still be validated * before submitting if the clientValidation option to {@link Ext.form.Basic#doAction} is * enabled, or if the field or form are validated manually.

*

See also {@link Ext.form.BaseField#checkChangeEvents}for controlling how changes to the field's value are detected.

*/ validateOnChange: true,
/** * Initializes this Field mixin on the current instance. Components using this mixin should call * this method during their own initialization process. */ initField: function() { this.addEvents(
/** * @event change * Fires when a user-initiated change is detected in the value of the field. * @param {Ext.form.Field} this * @param {Mixed} newValue The new value * @param {Mixed} oldValue The original value */ 'change',
/** * @event validitychange * Fires when a change in the field's validity is detected. * @param {Ext.form.Field} this * @param {Boolean} isValid Whether or not the field is now valid */ 'validitychange',
/** * @event dirtychange * Fires when a change in the field's {@link #isDirty} state is detected. * @param {Ext.form.Field} this * @param {Boolean} isDirty Whether or not the field is now dirty */ 'dirtychange' ); this.initValue(); },
/** * @protected * Initializes the field's value based on the initial config. */ initValue: function() { var me = this;
/** * The original value of the field as configured in the {@link #value} configuration, or * as loaded by the last form load operation if the form's {@link Ext.form.Basic#trackResetOnLoad trackResetOnLoad} * setting is true. * @type Mixed * @property originalValue */ me.originalValue = me._lastValue = me.value; // Set the initial value and perform conversion/validation me.setValue(me.value); me.clearInvalid(); },
/** * Returns the {@link Ext.form.Field#name name} attribute of the field. This is used as the parameter * name when including the field value in a {@link Ext.form.Basic#submit form submit()}. * @return {String} name The field {@link Ext.form.Field#name name} */ getName: function() { return this.name; },
/** * Returns the current data value of the field. The type of value returned is particular to the type of the * particular field (e.g. a Date object for {@link Ext.form.Date}), as the result of calling {@link #rawToValue} on * the field's {@link #processRawValue processed} String value. To return the raw String value, see {@link #getRawValue}. * @return {Mixed} value The field value */ getValue: function() { var me = this, val = me.rawToValue(me.processRawValue(me.getRawValue())); me.value = val; return val; },
/** * Sets a data value into the field and runs the change detection and validation. To set the value directly * without these inspections see {@link #setRawValue}. * @param {Mixed} value The value to set * @return {Ext.form.Field} this */ setValue: function(value) { var me = this; me.value = value; me.setRawValue(this.valueToRaw(value)); me.checkChange(); return me; },
/** * Returns the raw value of the field, without performing any normalization, conversion, or validation. * To get a normalized and converted value see {@link #getValue}. * @return {String} value The raw String value of the field */ getRawValue: function() { var me = this, value = Ext.value(me.rawValue, ''); me.rawValue = value; return value; },
/** * Sets the field's raw value directly, bypassing {@link #valueToRaw value conversion}, change detection, and * validation. To set the value with these additional inspections see {@link #setValue}. * @param {Mixed} value The value to set * @return {Mixed} value The field value that is set */ setRawValue: function(value) { value = Ext.value(value, ''); this.rawValue = value; return value; },
/** *

Converts a mixed-type value to a raw representation suitable for displaying in the field. This allows * controlling how value objects passed to {@link #setValue} are shown to the user, including localization. * For instance, for a {@link Ext.form.Date}, this would control how a Date object passed to {@link #setValue} * would be converted to a String for display in the field.

*

See {@link #rawToValue} for the opposite conversion.

*

The base implementation simply does a standard toString conversion, and converts * {@link Ext#isEmpty empty values} to an empty string.

* @param {Mixed} value The mixed-type value to convert to the raw representation. * @return {Mixed} The converted raw value. */ valueToRaw: function(value) { return '' + Ext.value(value, ''); },
/** *

Converts a raw input field value into a mixed-type value that is suitable for this particular field type. * This allows controlling the normalization and conversion of user-entered values into field-type-appropriate * values, e.g. a Date object for {@link Ext.form.Date}, and is invoked by {@link #getValue}.

*

It is up to individual implementations to decide how to handle raw values that cannot be successfully * converted to the desired object type.

*

See {@link #valueToRaw} for the opposite conversion.

*

The base implementation does no conversion, returning the raw value untouched.

* @param {Mixed} rawValue * @return {Mixed} The converted value. */ rawToValue: function(rawValue) { return rawValue; },
/** * Performs any necessary manipulation of a raw field value to prepare it for {@link #rawToValue conversion} * and/or {@link #validate validation}, for instance stripping out ignored characters. In the base implementation * it does nothing; individual subclasses may override this as needed. * @param {Mixed} value The unprocessed string value * @return {Mixed} The processed string value */ processRawValue: function(value) { return value; },
/** *

Returns the value that would be included in a standard form submit for this field. This will be combined * with the field's name to form a name=value pair in the submitted parameters. If an empty string is returned * then just the name= will be submitted; if null is returned then nothing will be submitted.

*

Note that the value returned will have been {@link #processRawValue processed} but may or may not have * been successfully {@link #validate validated}.

* @return {String} The value to be submitted, or null. */ getSubmitValue: function() { var me = this; return (me.disabled || !me.submitValue) ? null : me.processRawValue(me.getRawValue()); },
/** * Resets the current field value to the originally loaded value and clears any validation messages. * See {@link Ext.form.Basic}.{@link Ext.form.Basic#trackResetOnLoad trackResetOnLoad} */ reset : function(){ this.setValue(this.originalValue); this.clearInvalid(); },
/** *

Checks whether the value of the field has changed since the last time it was checked. If the value * has changed, it:

*
    *
  1. Fires the {@link #change change event},
  2. *
  3. Performs validation if the {@link #validateOnChange} config is enabled, firing the * {@link #validationchange validationchange event} if the validity has changed, and
  4. *
  5. Checks the {@link #isDirty dirty state} of the field and fires the {@link #dirtychange dirtychange event} * if it has changed.
  6. *
*/ checkChange: function() { var me = this, newVal = me.getRawValue(), //use unprocessed value oldVal = me._lastValue; if (String(newVal) !== String(oldVal) && !me.isDestroyed) { me._lastValue = newVal; me.fireEvent('change', me, newVal, oldVal); me.onChange(newVal, oldVal); } }, /** * @private * Called when the field's value changes. Performs validation if the {@link #validateOnChange} * config is enabled, and invokes the dirty check. */ onChange: function(newVal, oldVal) { if (this.validateOnChange) { this.checkValidityChange(); } this.checkDirtyChange(); },
/** *

Returns true if the value of this Field has been changed from its {@link #originalValue}. * Will always return false if the field is disabled.

*

Note that if the owning {@link Ext.form.Basic form} was configured with * {@link Ext.form.Basic#trackResetOnLoad trackResetOnLoad} * then the {@lnk #originalValue} is updated when the values are loaded by * {@link Ext.form.Basic}.{@link Ext.form.Basic#setValues setValues}.

* @return {Boolean} True if this field has been changed from its original value (and * is not disabled), false otherwise. */ isDirty : function() { return !this.disabled && String(this.getValue()) !== String(this.originalValue); },
/** * Checks the {@link #isDirty} state of the field and if it has changed since the last time * it was checked, fires the {@link #dirtychange} event. */ checkDirtyChange: function() { var me = this, isDirty = me.isDirty; if (isDirty !== me.wasDirty) { me.fireEvent('dirtychange', me, isDirty); me.wasDirty = isDirty; } },
/** * Validates the field and if its validity has changed since the last time it was checked, * fires the {@link #validitychange} event. * @return {Boolean} true if the validitychange event was fired, false if not. */ checkValidityChange: function() { var me = this, changed = false, isValid = me.validate(); if (isValid !== me.wasValid) { me.fireEvent('validitychange', me, isValid); me.wasValid = isValid; changed = true; } return changed; },
/** *

Runs this field's validators and returns an array of error messages for any validation failures. * This is called internally during validation and would not usually need to be used manually.

*

Each subclass should override or augment the return value to provide their own errors.

* @param {Mixed} value The value to get errors for (defaults to the current field value) * @return {Array} All error messages for this field; an empty Array if none. */ getErrors: function(value) { return []; },
/** *

Returns whether or not the field value is currently valid by {@link #getErrors validating} the * field's current value. Note: {@link #disabled} fields are always treated as valid.

*

Logically this is identical to the {@link #validate} method, but implementations are encouraged * to ensure that this method does not have side-effects such as triggering error message display.

* @return {Boolean} True if the value is valid, else false */ isValid : function() { var me = this; return me.disabled || me.getErrors().length === 0; },
/** *

Returns whether or not the field value is currently valid by {@link #getErrors validating} the * field's current value. Note: {@link #disabled} fields are always treated as valid.

*

Logically this is identical to the {@link #isValid} method, but unlike that method this one * may have side-effects such as triggering error message display.

* @return {Boolean} True if the value is valid, else false */ validate : function() { return this.isValid(); } });