Field.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:24k
源码类别:

JavaScript

开发平台:

JavaScript

  1. /*!
  2.  * Ext JS Library 3.1.0
  3.  * Copyright(c) 2006-2009 Ext JS, LLC
  4.  * licensing@extjs.com
  5.  * http://www.extjs.com/license
  6.  */
  7. /**
  8.  * @class Ext.form.Field
  9.  * @extends Ext.BoxComponent
  10.  * Base class for form fields that provides default event handling, sizing, value handling and other functionality.
  11.  * @constructor
  12.  * Creates a new Field
  13.  * @param {Object} config Configuration options
  14.  * @xtype field
  15.  */
  16. Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
  17.     /**
  18.      * <p>The label Element associated with this Field. <b>Only available after this Field has been rendered by a
  19.      * {@link form Ext.layout.FormLayout} layout manager.</b></p>
  20.      * @type Ext.Element
  21.      * @property label
  22.      */
  23.     /**
  24.      * @cfg {String} inputType The type attribute for input fields -- e.g. radio, text, password, file (defaults
  25.      * to 'text'). The types 'file' and 'password' must be used to render those field types currently -- there are
  26.      * no separate Ext components for those. Note that if you use <tt>inputType:'file'</tt>, {@link #emptyText}
  27.      * is not supported and should be avoided.
  28.      */
  29.     /**
  30.      * @cfg {Number} tabIndex The tabIndex for this field. Note this only applies to fields that are rendered,
  31.      * not those which are built via applyTo (defaults to undefined).
  32.      */
  33.     /**
  34.      * @cfg {Mixed} value A value to initialize this field with (defaults to undefined).
  35.      */
  36.     /**
  37.      * @cfg {String} name The field's HTML name attribute (defaults to '').
  38.      * <b>Note</b>: this property must be set if this field is to be automatically included with
  39.      * {@link Ext.form.BasicForm#submit form submit()}.
  40.      */
  41.     /**
  42.      * @cfg {String} cls A custom CSS class to apply to the field's underlying element (defaults to '').
  43.      */
  44.     /**
  45.      * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to 'x-form-invalid')
  46.      */
  47.     invalidClass : 'x-form-invalid',
  48.     /**
  49.      * @cfg {String} invalidText The error text to use when marking a field invalid and no message is provided
  50.      * (defaults to 'The value in this field is invalid')
  51.      */
  52.     invalidText : 'The value in this field is invalid',
  53.     /**
  54.      * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to 'x-form-focus')
  55.      */
  56.     focusClass : 'x-form-focus',
  57.     /**
  58.      * @cfg {Boolean} preventMark
  59.      * <tt>true</tt> to disable {@link #markInvalid marking the field invalid}.
  60.      * Defaults to <tt>false</tt>.
  61.      */
  62.     /**
  63.      * @cfg {String/Boolean} validationEvent The event that should initiate field validation. Set to false to disable
  64.       automatic validation (defaults to 'keyup').
  65.      */
  66.     validationEvent : 'keyup',
  67.     /**
  68.      * @cfg {Boolean} validateOnBlur Whether the field should validate when it loses focus (defaults to true).
  69.      */
  70.     validateOnBlur : true,
  71.     /**
  72.      * @cfg {Number} validationDelay The length of time in milliseconds after user input begins until validation
  73.      * is initiated (defaults to 250)
  74.      */
  75.     validationDelay : 250,
  76.     /**
  77.      * @cfg {String/Object} autoCreate <p>A {@link Ext.DomHelper DomHelper} element spec, or true for a default
  78.      * element spec. Used to create the {@link Ext.Component#getEl Element} which will encapsulate this Component.
  79.      * See <tt>{@link Ext.Component#autoEl autoEl}</tt> for details.  Defaults to:</p>
  80.      * <pre><code>{tag: 'input', type: 'text', size: '20', autocomplete: 'off'}</code></pre>
  81.      */
  82.     defaultAutoCreate : {tag: 'input', type: 'text', size: '20', autocomplete: 'off'},
  83.     /**
  84.      * @cfg {String} fieldClass The default CSS class for the field (defaults to 'x-form-field')
  85.      */
  86.     fieldClass : 'x-form-field',
  87.     /**
  88.      * @cfg {String} msgTarget<p>The location where the message text set through {@link #markInvalid} should display. 
  89.      * Must be one of the following values:</p>
  90.      * <div class="mdetail-params"><ul>
  91.      * <li><code>qtip</code> Display a quick tip containing the message when the user hovers over the field. This is the default.
  92.      * <div class="subdesc"><b>{@link Ext.QuickTips#init Ext.QuickTips.init} must have been called for this setting to work.</b></div</li>
  93.      * <li><code>title</code> Display the message in a default browser title attribute popup.</li>
  94.      * <li><code>under</code> Add a block div beneath the field containing the error message.</li>
  95.      * <li><code>side</code> Add an error icon to the right of the field, displaying the message in a popup on hover.</li>
  96.      * <li><code>[element id]</code> Add the error message directly to the innerHTML of the specified element.</li>
  97.      * </ul></div>
  98.      */
  99.     msgTarget : 'qtip',
  100.     /**
  101.      * @cfg {String} msgFx <b>Experimental</b> The effect used when displaying a validation message under the field
  102.      * (defaults to 'normal').
  103.      */
  104.     msgFx : 'normal',
  105.     /**
  106.      * @cfg {Boolean} readOnly <tt>true</tt> to mark the field as readOnly in HTML
  107.      * (defaults to <tt>false</tt>).
  108.      * <br><p><b>Note</b>: this only sets the element's readOnly DOM attribute.
  109.      * Setting <code>readOnly=true</code>, for example, will not disable triggering a
  110.      * ComboBox or DateField; it gives you the option of forcing the user to choose
  111.      * via the trigger without typing in the text box. To hide the trigger use
  112.      * <code>{@link Ext.form.TriggerField#hideTrigger hideTrigger}</code>.</p>
  113.      */
  114.     readOnly : false,
  115.     /**
  116.      * @cfg {Boolean} disabled True to disable the field (defaults to false).
  117.      * <p>Be aware that conformant with the <a href="http://www.w3.org/TR/html401/interact/forms.html#h-17.12.1">HTML specification</a>,
  118.      * disabled Fields will not be {@link Ext.form.BasicForm#submit submitted}.</p>
  119.      */
  120.     disabled : false,
  121.     /**
  122.      * @cfg {Boolean} submitValue False to clear the name attribute on the field so that it is not submitted during a form post.
  123.      * Defaults to <tt>true</tt>.
  124.      */
  125.     submitValue: true,
  126.     // private
  127.     isFormField : true,
  128.     // private
  129.     msgDisplay: '',
  130.     // private
  131.     hasFocus : false,
  132.     // private
  133.     initComponent : function(){
  134.         Ext.form.Field.superclass.initComponent.call(this);
  135.         this.addEvents(
  136.             /**
  137.              * @event focus
  138.              * Fires when this field receives input focus.
  139.              * @param {Ext.form.Field} this
  140.              */
  141.             'focus',
  142.             /**
  143.              * @event blur
  144.              * Fires when this field loses input focus.
  145.              * @param {Ext.form.Field} this
  146.              */
  147.             'blur',
  148.             /**
  149.              * @event specialkey
  150.              * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed.
  151.              * To handle other keys see {@link Ext.Panel#keys} or {@link Ext.KeyMap}.
  152.              * You can check {@link Ext.EventObject#getKey} to determine which key was pressed.
  153.              * For example: <pre><code>
  154. var form = new Ext.form.FormPanel({
  155.     ...
  156.     items: [{
  157.             fieldLabel: 'Field 1',
  158.             name: 'field1',
  159.             allowBlank: false
  160.         },{
  161.             fieldLabel: 'Field 2',
  162.             name: 'field2',
  163.             listeners: {
  164.                 specialkey: function(field, e){
  165.                     // e.HOME, e.END, e.PAGE_UP, e.PAGE_DOWN,
  166.                     // e.TAB, e.ESC, arrow keys: e.LEFT, e.RIGHT, e.UP, e.DOWN
  167.                     if (e.{@link Ext.EventObject#getKey getKey()} == e.ENTER) {
  168.                         var form = field.ownerCt.getForm();
  169.                         form.submit();
  170.                     }
  171.                 }
  172.             }
  173.         }
  174.     ],
  175.     ...
  176. });
  177.              * </code></pre>
  178.              * @param {Ext.form.Field} this
  179.              * @param {Ext.EventObject} e The event object
  180.              */
  181.             'specialkey',
  182.             /**
  183.              * @event change
  184.              * Fires just before the field blurs if the field value has changed.
  185.              * @param {Ext.form.Field} this
  186.              * @param {Mixed} newValue The new value
  187.              * @param {Mixed} oldValue The original value
  188.              */
  189.             'change',
  190.             /**
  191.              * @event invalid
  192.              * Fires after the field has been marked as invalid.
  193.              * @param {Ext.form.Field} this
  194.              * @param {String} msg The validation message
  195.              */
  196.             'invalid',
  197.             /**
  198.              * @event valid
  199.              * Fires after the field has been validated with no errors.
  200.              * @param {Ext.form.Field} this
  201.              */
  202.             'valid'
  203.         );
  204.     },
  205.     /**
  206.      * Returns the {@link Ext.form.Field#name name} or {@link Ext.form.ComboBox#hiddenName hiddenName}
  207.      * attribute of the field if available.
  208.      * @return {String} name The field {@link Ext.form.Field#name name} or {@link Ext.form.ComboBox#hiddenName hiddenName}
  209.      */
  210.     getName : function(){
  211.         return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || '';
  212.     },
  213.     // private
  214.     onRender : function(ct, position){
  215.         if(!this.el){
  216.             var cfg = this.getAutoCreate();
  217.             if(!cfg.name){
  218.                 cfg.name = this.name || this.id;
  219.             }
  220.             if(this.inputType){
  221.                 cfg.type = this.inputType;
  222.             }
  223.             this.autoEl = cfg;
  224.         }
  225.         Ext.form.Field.superclass.onRender.call(this, ct, position);
  226.         if(this.submitValue === false){
  227.             this.el.dom.removeAttribute('name');
  228.         }
  229.         var type = this.el.dom.type;
  230.         if(type){
  231.             if(type == 'password'){
  232.                 type = 'text';
  233.             }
  234.             this.el.addClass('x-form-'+type);
  235.         }
  236.         if(this.readOnly){
  237.             this.setReadOnly(true);
  238.         }
  239.         if(this.tabIndex !== undefined){
  240.             this.el.dom.setAttribute('tabIndex', this.tabIndex);
  241.         }
  242.         this.el.addClass([this.fieldClass, this.cls]);
  243.     },
  244.     // private
  245.     getItemCt : function(){
  246.         return this.itemCt;
  247.     },
  248.     // private
  249.     initValue : function(){
  250.         if(this.value !== undefined){
  251.             this.setValue(this.value);
  252.         }else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){
  253.             this.setValue(this.el.dom.value);
  254.         }
  255.         /**
  256.          * The original value of the field as configured in the {@link #value} configuration, or
  257.          * as loaded by the last form load operation if the form's {@link Ext.form.BasicForm#trackResetOnLoad trackResetOnLoad}
  258.          * setting is <code>true</code>.
  259.          * @type mixed
  260.          * @property originalValue
  261.          */
  262.         this.originalValue = this.getValue();
  263.     },
  264.     /**
  265.      * <p>Returns true if the value of this Field has been changed from its original value.
  266.      * Will return false if the field is disabled or has not been rendered yet.</p>
  267.      * <p>Note that if the owning {@link Ext.form.BasicForm form} was configured with
  268.      * {@link Ext.form.BasicForm}.{@link Ext.form.BasicForm#trackResetOnLoad trackResetOnLoad}
  269.      * then the <i>original value</i> is updated when the values are loaded by
  270.      * {@link Ext.form.BasicForm}.{@link Ext.form.BasicForm#setValues setValues}.</p>
  271.      * @return {Boolean} True if this field has been changed from its original value (and
  272.      * is not disabled), false otherwise.
  273.      */
  274.     isDirty : function() {
  275.         if(this.disabled || !this.rendered) {
  276.             return false;
  277.         }
  278.         return String(this.getValue()) !== String(this.originalValue);
  279.     },
  280.     
  281.     /**
  282.      * Sets the read only state of this field.
  283.      * @param {Boolean} readOnly Whether the field should be read only.
  284.      */
  285.     setReadOnly : function(readOnly){
  286.         if(this.rendered){
  287.             this.el.dom.readOnly = readOnly;
  288.         }
  289.         this.readOnly = readOnly;
  290.     },
  291.     // private
  292.     afterRender : function(){
  293.         Ext.form.Field.superclass.afterRender.call(this);
  294.         this.initEvents();
  295.         this.initValue();
  296.     },
  297.     // private
  298.     fireKey : function(e){
  299.         if(e.isSpecialKey()){
  300.             this.fireEvent('specialkey', this, e);
  301.         }
  302.     },
  303.     /**
  304.      * Resets the current field value to the originally loaded value and clears any validation messages.
  305.      * See {@link Ext.form.BasicForm}.{@link Ext.form.BasicForm#trackResetOnLoad trackResetOnLoad}
  306.      */
  307.     reset : function(){
  308.         this.setValue(this.originalValue);
  309.         this.clearInvalid();
  310.     },
  311.     // private
  312.     initEvents : function(){
  313.         this.mon(this.el, Ext.EventManager.useKeydown ? 'keydown' : 'keypress', this.fireKey,  this);
  314.         this.mon(this.el, 'focus', this.onFocus, this);
  315.         // standardise buffer across all browsers + OS-es for consistent event order.
  316.         // (the 10ms buffer for Editors fixes a weird FF/Win editor issue when changing OS window focus)
  317.         this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {buffer:10} : null);
  318.     },
  319.     // private
  320.     preFocus: Ext.emptyFn,
  321.     // private
  322.     onFocus : function(){
  323.         this.preFocus();
  324.         if(this.focusClass){
  325.             this.el.addClass(this.focusClass);
  326.         }
  327.         if(!this.hasFocus){
  328.             this.hasFocus = true;
  329.             /**
  330.              * <p>The value that the Field had at the time it was last focused. This is the value that is passed
  331.              * to the {@link #change} event which is fired if the value has been changed when the Field is blurred.</p>
  332.              * <p><b>This will be undefined until the Field has been visited.</b> Compare {@link #originalValue}.</p>
  333.              * @type mixed
  334.              * @property startValue
  335.              */
  336.             this.startValue = this.getValue();
  337.             this.fireEvent('focus', this);
  338.         }
  339.     },
  340.     // private
  341.     beforeBlur : Ext.emptyFn,
  342.     // private
  343.     onBlur : function(){
  344.         this.beforeBlur();
  345.         if(this.focusClass){
  346.             this.el.removeClass(this.focusClass);
  347.         }
  348.         this.hasFocus = false;
  349.         if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent == 'blur')){
  350.             this.validate();
  351.         }
  352.         var v = this.getValue();
  353.         if(String(v) !== String(this.startValue)){
  354.             this.fireEvent('change', this, v, this.startValue);
  355.         }
  356.         this.fireEvent('blur', this);
  357.         this.postBlur();
  358.     },
  359.     // private
  360.     postBlur : Ext.emptyFn,
  361.     /**
  362.      * Returns whether or not the field value is currently valid by
  363.      * {@link #validateValue validating} the {@link #processValue processed value}
  364.      * of the field. <b>Note</b>: {@link #disabled} fields are ignored.
  365.      * @param {Boolean} preventMark True to disable marking the field invalid
  366.      * @return {Boolean} True if the value is valid, else false
  367.      */
  368.     isValid : function(preventMark){
  369.         if(this.disabled){
  370.             return true;
  371.         }
  372.         var restore = this.preventMark;
  373.         this.preventMark = preventMark === true;
  374.         var v = this.validateValue(this.processValue(this.getRawValue()));
  375.         this.preventMark = restore;
  376.         return v;
  377.     },
  378.     /**
  379.      * Validates the field value
  380.      * @return {Boolean} True if the value is valid, else false
  381.      */
  382.     validate : function(){
  383.         if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
  384.             this.clearInvalid();
  385.             return true;
  386.         }
  387.         return false;
  388.     },
  389.     /**
  390.      * This method should only be overridden if necessary to prepare raw values
  391.      * for validation (see {@link #validate} and {@link #isValid}).  This method
  392.      * is expected to return the processed value for the field which will
  393.      * be used for validation (see validateValue method).
  394.      * @param {Mixed} value
  395.      */
  396.     processValue : function(value){
  397.         return value;
  398.     },
  399.     /**
  400.      * @private
  401.      * Subclasses should provide the validation implementation by overriding this
  402.      * @param {Mixed} value
  403.      */
  404.     validateValue : function(value){
  405.         return true;
  406.     },
  407.     
  408.     /**
  409.      * Gets the active error message for this field.
  410.      * @return {String} Returns the active error message on the field, if there is no error, an empty string is returned.
  411.      */
  412.     getActiveError : function(){
  413.         return this.activeError || '';    
  414.     },
  415.     /**
  416.      * <p>Display an error message associated with this field, using {@link #msgTarget} to determine how to
  417.      * display the message and applying {@link #invalidClass} to the field's UI element.</p>
  418.      * <p><b>Note</b>: this method does not cause the Field's {@link #validate} method to return <code>false</code>
  419.      * if the value does <i>pass</i> validation. So simply marking a Field as invalid will not prevent
  420.      * submission of forms submitted with the {@link Ext.form.Action.Submit#clientValidation} option set.</p>
  421.      * {@link #isValid invalid}.
  422.      * @param {String} msg (optional) The validation message (defaults to {@link #invalidText})
  423.      */
  424.     markInvalid : function(msg){
  425.         if(!this.rendered || this.preventMark){ // not rendered
  426.             return;
  427.         }
  428.         msg = msg || this.invalidText;
  429.         var mt = this.getMessageHandler();
  430.         if(mt){
  431.             mt.mark(this, msg);
  432.         }else if(this.msgTarget){
  433.             this.el.addClass(this.invalidClass);
  434.             var t = Ext.getDom(this.msgTarget);
  435.             if(t){
  436.                 t.innerHTML = msg;
  437.                 t.style.display = this.msgDisplay;
  438.             }
  439.         }
  440.         this.activeError = msg;
  441.         this.fireEvent('invalid', this, msg);
  442.     },
  443.     /**
  444.      * Clear any invalid styles/messages for this field
  445.      */
  446.     clearInvalid : function(){
  447.         if(!this.rendered || this.preventMark){ // not rendered
  448.             return;
  449.         }
  450.         this.el.removeClass(this.invalidClass);
  451.         var mt = this.getMessageHandler();
  452.         if(mt){
  453.             mt.clear(this);
  454.         }else if(this.msgTarget){
  455.             this.el.removeClass(this.invalidClass);
  456.             var t = Ext.getDom(this.msgTarget);
  457.             if(t){
  458.                 t.innerHTML = '';
  459.                 t.style.display = 'none';
  460.             }
  461.         }
  462.         delete this.activeError;
  463.         this.fireEvent('valid', this);
  464.     },
  465.     // private
  466.     getMessageHandler : function(){
  467.         return Ext.form.MessageTargets[this.msgTarget];
  468.     },
  469.     // private
  470.     getErrorCt : function(){
  471.         return this.el.findParent('.x-form-element', 5, true) || // use form element wrap if available
  472.             this.el.findParent('.x-form-field-wrap', 5, true);   // else direct field wrap
  473.     },
  474.     // private
  475.     alignErrorIcon : function(){
  476.         this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
  477.     },
  478.     /**
  479.      * Returns the raw data value which may or may not be a valid, defined value.  To return a normalized value see {@link #getValue}.
  480.      * @return {Mixed} value The field value
  481.      */
  482.     getRawValue : function(){
  483.         var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
  484.         if(v === this.emptyText){
  485.             v = '';
  486.         }
  487.         return v;
  488.     },
  489.     /**
  490.      * Returns the normalized data value (undefined or emptyText will be returned as '').  To return the raw value see {@link #getRawValue}.
  491.      * @return {Mixed} value The field value
  492.      */
  493.     getValue : function(){
  494.         if(!this.rendered) {
  495.             return this.value;
  496.         }
  497.         var v = this.el.getValue();
  498.         if(v === this.emptyText || v === undefined){
  499.             v = '';
  500.         }
  501.         return v;
  502.     },
  503.     /**
  504.      * Sets the underlying DOM field's value directly, bypassing validation.  To set the value with validation see {@link #setValue}.
  505.      * @param {Mixed} value The value to set
  506.      * @return {Mixed} value The field value that is set
  507.      */
  508.     setRawValue : function(v){
  509.         return this.rendered ? (this.el.dom.value = (Ext.isEmpty(v) ? '' : v)) : '';
  510.     },
  511.     /**
  512.      * Sets a data value into the field and validates it.  To set the value directly without validation see {@link #setRawValue}.
  513.      * @param {Mixed} value The value to set
  514.      * @return {Ext.form.Field} this
  515.      */
  516.     setValue : function(v){
  517.         this.value = v;
  518.         if(this.rendered){
  519.             this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
  520.             this.validate();
  521.         }
  522.         return this;
  523.     },
  524.     // private, does not work for all fields
  525.     append : function(v){
  526.          this.setValue([this.getValue(), v].join(''));
  527.     }
  528.     /**
  529.      * @cfg {Boolean} autoWidth @hide
  530.      */
  531.     /**
  532.      * @cfg {Boolean} autoHeight @hide
  533.      */
  534.     /**
  535.      * @cfg {String} autoEl @hide
  536.      */
  537. });
  538. Ext.form.MessageTargets = {
  539.     'qtip' : {
  540.         mark: function(field, msg){
  541.             field.el.addClass(field.invalidClass);
  542.             field.el.dom.qtip = msg;
  543.             field.el.dom.qclass = 'x-form-invalid-tip';
  544.             if(Ext.QuickTips){ // fix for floating editors interacting with DND
  545.                 Ext.QuickTips.enable();
  546.             }
  547.         },
  548.         clear: function(field){
  549.             field.el.removeClass(field.invalidClass);
  550.             field.el.dom.qtip = '';
  551.         }
  552.     },
  553.     'title' : {
  554.         mark: function(field, msg){
  555.             field.el.addClass(field.invalidClass);
  556.             field.el.dom.title = msg;
  557.         },
  558.         clear: function(field){
  559.             field.el.dom.title = '';
  560.         }
  561.     },
  562.     'under' : {
  563.         mark: function(field, msg){
  564.             field.el.addClass(field.invalidClass);
  565.             if(!field.errorEl){
  566.                 var elp = field.getErrorCt();
  567.                 if(!elp){ // field has no container el
  568.                     field.el.dom.title = msg;
  569.                     return;
  570.                 }
  571.                 field.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
  572.                 field.errorEl.setWidth(elp.getWidth(true)-20);
  573.             }
  574.             field.errorEl.update(msg);
  575.             Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field);
  576.         },
  577.         clear: function(field){
  578.             field.el.removeClass(field.invalidClass);
  579.             if(field.errorEl){
  580.                 Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl, field);
  581.             }else{
  582.                 field.el.dom.title = '';
  583.             }
  584.         }
  585.     },
  586.     'side' : {
  587.         mark: function(field, msg){
  588.             field.el.addClass(field.invalidClass);
  589.             if(!field.errorIcon){
  590.                 var elp = field.getErrorCt();
  591.                 if(!elp){ // field has no container el
  592.                     field.el.dom.title = msg;
  593.                     return;
  594.                 }
  595.                 field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
  596.             }
  597.             field.alignErrorIcon();
  598.             field.errorIcon.dom.qtip = msg;
  599.             field.errorIcon.dom.qclass = 'x-form-invalid-tip';
  600.             field.errorIcon.show();
  601.             field.on('resize', field.alignErrorIcon, field);
  602.         },
  603.         clear: function(field){
  604.             field.el.removeClass(field.invalidClass);
  605.             if(field.errorIcon){
  606.                 field.errorIcon.dom.qtip = '';
  607.                 field.errorIcon.hide();
  608.                 field.un('resize', field.alignErrorIcon, field);
  609.             }else{
  610.                 field.el.dom.title = '';
  611.             }
  612.         }
  613.     }
  614. };
  615. // anything other than normal should be considered experimental
  616. Ext.form.Field.msgFx = {
  617.     normal : {
  618.         show: function(msgEl, f){
  619.             msgEl.setDisplayed('block');
  620.         },
  621.         hide : function(msgEl, f){
  622.             msgEl.setDisplayed(false).update('');
  623.         }
  624.     },
  625.     slide : {
  626.         show: function(msgEl, f){
  627.             msgEl.slideIn('t', {stopFx:true});
  628.         },
  629.         hide : function(msgEl, f){
  630.             msgEl.slideOut('t', {stopFx:true,useDisplay:true});
  631.         }
  632.     },
  633.     slideRight : {
  634.         show: function(msgEl, f){
  635.             msgEl.fixDisplay();
  636.             msgEl.alignTo(f.el, 'tl-tr');
  637.             msgEl.slideIn('l', {stopFx:true});
  638.         },
  639.         hide : function(msgEl, f){
  640.             msgEl.slideOut('l', {stopFx:true,useDisplay:true});
  641.         }
  642.     }
  643. };
  644. Ext.reg('field', Ext.form.Field);