2 * Ext JS Library 2.2.1
\r
3 * Copyright(c) 2006-2009, Ext JS, LLC.
\r
4 * licensing@extjs.com
\r
6 * http://extjs.com/license
\r
10 * @class Ext.form.TextField
\r
11 * @extends Ext.form.Field
\r
12 * Basic text field. Can be used as a direct replacement for traditional text inputs, or as the base
\r
13 * class for more sophisticated input controls (like {@link Ext.form.TextArea} and {@link Ext.form.ComboBox}).
\r
15 * Creates a new TextField
\r
16 * @param {Object} config Configuration options
\r
18 Ext.form.TextField = Ext.extend(Ext.form.Field, {
\r
20 * @cfg {String} vtypeText A custom error message to display in place of the default message provided
\r
21 * for the {@link #vtype} currently set for this field (defaults to ''). Only applies if vtype is set, else ignored.
\r
24 * @cfg {RegExp} stripCharsRe A JavaScript RegExp object used to strip unwanted content from the value before validation (defaults to null).
\r
27 * @cfg {Boolean} grow True if this field should automatically grow and shrink to its content
\r
31 * @cfg {Number} growMin The minimum width to allow when grow = true (defaults to 30)
\r
35 * @cfg {Number} growMax The maximum width to allow when grow = true (defaults to 800)
\r
39 * @cfg {String} vtype A validation type name as defined in {@link Ext.form.VTypes} (defaults to null)
\r
43 * @cfg {RegExp} maskRe An input mask regular expression that will be used to filter keystrokes that don't match
\r
44 * (defaults to null)
\r
48 * @cfg {Boolean} disableKeyFilter True to disable input keystroke filtering (defaults to false)
\r
50 disableKeyFilter : false,
\r
52 * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to true)
\r
56 * @cfg {Number} minLength Minimum input field length required (defaults to 0)
\r
60 * @cfg {Number} maxLength Maximum input field length allowed (defaults to Number.MAX_VALUE)
\r
62 maxLength : Number.MAX_VALUE,
\r
64 * @cfg {String} minLengthText Error text to display if the minimum length validation fails (defaults to
\r
65 * "The minimum length for this field is {minLength}")
\r
67 minLengthText : "The minimum length for this field is {0}",
\r
69 * @cfg {String} maxLengthText Error text to display if the maximum length validation fails (defaults to
\r
70 * "The maximum length for this field is {maxLength}")
\r
72 maxLengthText : "The maximum length for this field is {0}",
\r
74 * @cfg {Boolean} selectOnFocus True to automatically select any existing field text when the field receives
\r
75 * input focus (defaults to false)
\r
77 selectOnFocus : false,
\r
79 * @cfg {String} blankText Error text to display if the allow blank validation fails (defaults to "This field is required")
\r
81 blankText : "This field is required",
\r
83 * @cfg {Function} validator A custom validation function to be called during field validation (defaults to null).
\r
84 * If specified, this function will be called only after the built-in validations ({@link #allowBlank}, {@link #minLength},
\r
85 * {@link #maxLength}) and any configured {@link #vtype} all return true. This function will be passed the current field
\r
86 * value and expected to return boolean true if the value is valid or a string error message if invalid.
\r
90 * @cfg {RegExp} regex A JavaScript RegExp object to be tested against the field value during validation (defaults to null).
\r
91 * If available, this regex will be evaluated only after the basic validators all return true, and will be passed the
\r
92 * current field value. If the test fails, the field will be marked invalid using {@link #regexText}.
\r
96 * @cfg {String} regexText The error text to display if {@link #regex} is used and the test fails during
\r
97 * validation (defaults to "")
\r
101 * @cfg {String} emptyText The default text to place into an empty field (defaults to null). Note that this
\r
102 * value will be submitted to the server if this field is enabled and configured with a {@link #name}.
\r
106 * @cfg {String} emptyClass The CSS class to apply to an empty field to style the {@link #emptyText} (defaults to
\r
107 * 'x-form-empty-field'). This class is automatically added and removed as needed depending on the current field value.
\r
109 emptyClass : 'x-form-empty-field',
\r
112 * @cfg {Boolean} enableKeyEvents True to enable the proxying of key events for the HTML input field (defaults to false)
\r
115 initComponent : function(){
\r
116 Ext.form.TextField.superclass.initComponent.call(this);
\r
120 * Fires when the autosize function is triggered. The field may or may not have actually changed size
\r
121 * according to the default logic, but this event provides a hook for the developer to apply additional
\r
122 * logic at runtime to resize the field if needed.
\r
123 * @param {Ext.form.Field} this This text field
\r
124 * @param {Number} width The new field width
\r
130 * Keydown input field event. This event only fires if enableKeyEvents is set to true.
\r
131 * @param {Ext.form.TextField} this This text field
\r
132 * @param {Ext.EventObject} e
\r
137 * Keyup input field event. This event only fires if enableKeyEvents is set to true.
\r
138 * @param {Ext.form.TextField} this This text field
\r
139 * @param {Ext.EventObject} e
\r
144 * Keypress input field event. This event only fires if enableKeyEvents is set to true.
\r
145 * @param {Ext.form.TextField} this This text field
\r
146 * @param {Ext.EventObject} e
\r
153 initEvents : function(){
\r
154 Ext.form.TextField.superclass.initEvents.call(this);
\r
155 if(this.validationEvent == 'keyup'){
\r
156 this.validationTask = new Ext.util.DelayedTask(this.validate, this);
\r
157 this.el.on('keyup', this.filterValidation, this);
\r
159 else if(this.validationEvent !== false){
\r
160 this.el.on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
\r
162 if(this.selectOnFocus || this.emptyText){
\r
163 this.on("focus", this.preFocus, this);
\r
164 this.el.on('mousedown', function(){
\r
165 if(!this.hasFocus){
\r
166 this.el.on('mouseup', function(e){
\r
167 e.preventDefault();
\r
168 }, this, {single:true});
\r
171 if(this.emptyText){
\r
172 this.on('blur', this.postBlur, this);
\r
173 this.applyEmptyText();
\r
176 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
\r
177 this.el.on("keypress", this.filterKeys, this);
\r
180 this.el.on("keyup", this.onKeyUpBuffered, this, {buffer:50});
\r
181 this.el.on("click", this.autoSize, this);
\r
184 if(this.enableKeyEvents){
\r
185 this.el.on("keyup", this.onKeyUp, this);
\r
186 this.el.on("keydown", this.onKeyDown, this);
\r
187 this.el.on("keypress", this.onKeyPress, this);
\r
191 processValue : function(value){
\r
192 if(this.stripCharsRe){
\r
193 var newValue = value.replace(this.stripCharsRe, '');
\r
194 if(newValue !== value){
\r
195 this.setRawValue(newValue);
\r
202 filterValidation : function(e){
\r
203 if(!e.isNavKeyPress()){
\r
204 this.validationTask.delay(this.validationDelay);
\r
209 onDisable: function(){
\r
210 Ext.form.TextField.superclass.onDisable.call(this);
\r
212 this.el.dom.unselectable = 'on';
\r
217 onEnable: function(){
\r
218 Ext.form.TextField.superclass.onEnable.call(this);
\r
220 this.el.dom.unselectable = '';
\r
225 onKeyUpBuffered : function(e){
\r
226 if(!e.isNavKeyPress()){
\r
232 onKeyUp : function(e){
\r
233 this.fireEvent('keyup', this, e);
\r
237 onKeyDown : function(e){
\r
238 this.fireEvent('keydown', this, e);
\r
242 onKeyPress : function(e){
\r
243 this.fireEvent('keypress', this, e);
\r
247 * Resets the current field value to the originally-loaded value and clears any validation messages.
\r
248 * Also adds emptyText and emptyClass if the original value was blank.
\r
250 reset : function(){
\r
251 Ext.form.TextField.superclass.reset.call(this);
\r
252 this.applyEmptyText();
\r
255 applyEmptyText : function(){
\r
256 if(this.rendered && this.emptyText && this.getRawValue().length < 1 && !this.hasFocus){
\r
257 this.setRawValue(this.emptyText);
\r
258 this.el.addClass(this.emptyClass);
\r
263 preFocus : function(){
\r
264 if(this.emptyText){
\r
265 if(this.el.dom.value == this.emptyText){
\r
266 this.setRawValue('');
\r
268 this.el.removeClass(this.emptyClass);
\r
270 if(this.selectOnFocus){
\r
271 this.el.dom.select();
\r
276 postBlur : function(){
\r
277 this.applyEmptyText();
\r
281 filterKeys : function(e){
\r
285 var k = e.getKey();
\r
286 if(Ext.isGecko && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
\r
289 var c = e.getCharCode(), cc = String.fromCharCode(c);
\r
290 if(!Ext.isGecko && e.isSpecialKey() && !cc){
\r
293 if(!this.maskRe.test(cc)){
\r
298 setValue : function(v){
\r
299 if(this.emptyText && this.el && v !== undefined && v !== null && v !== ''){
\r
300 this.el.removeClass(this.emptyClass);
\r
302 Ext.form.TextField.superclass.setValue.apply(this, arguments);
\r
303 this.applyEmptyText();
\r
308 * Validates a value according to the field's validation rules and marks the field as invalid
\r
309 * if the validation fails
\r
310 * @param {Mixed} value The value to validate
\r
311 * @return {Boolean} True if the value is valid, else false
\r
313 validateValue : function(value){
\r
314 if(value.length < 1 || value === this.emptyText){ // if it's blank
\r
315 if(this.allowBlank){
\r
316 this.clearInvalid();
\r
319 this.markInvalid(this.blankText);
\r
323 if(value.length < this.minLength){
\r
324 this.markInvalid(String.format(this.minLengthText, this.minLength));
\r
327 if(value.length > this.maxLength){
\r
328 this.markInvalid(String.format(this.maxLengthText, this.maxLength));
\r
332 var vt = Ext.form.VTypes;
\r
333 if(!vt[this.vtype](value, this)){
\r
334 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
\r
338 if(typeof this.validator == "function"){
\r
339 var msg = this.validator(value);
\r
341 this.markInvalid(msg);
\r
345 if(this.regex && !this.regex.test(value)){
\r
346 this.markInvalid(this.regexText);
\r
353 * Selects text in this field
\r
354 * @param {Number} start (optional) The index where the selection should start (defaults to 0)
\r
355 * @param {Number} end (optional) The index where the selection should end (defaults to the text length)
\r
357 selectText : function(start, end){
\r
358 var v = this.getRawValue();
\r
359 var doFocus = false;
\r
361 start = start === undefined ? 0 : start;
\r
362 end = end === undefined ? v.length : end;
\r
363 var d = this.el.dom;
\r
364 if(d.setSelectionRange){
\r
365 d.setSelectionRange(start, end);
\r
366 }else if(d.createTextRange){
\r
367 var range = d.createTextRange();
\r
368 range.moveStart("character", start);
\r
369 range.moveEnd("character", end-v.length);
\r
372 doFocus = Ext.isGecko || Ext.isOpera;
\r
382 * Automatically grows the field to accomodate the width of the text up to the maximum field width allowed.
\r
383 * This only takes effect if grow = true, and fires the {@link #autosize} event.
\r
385 autoSize : function(){
\r
386 if(!this.grow || !this.rendered){
\r
390 this.metrics = Ext.util.TextMetrics.createInstance(this.el);
\r
393 var v = el.dom.value;
\r
394 var d = document.createElement('div');
\r
395 d.appendChild(document.createTextNode(v));
\r
400 var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + /* add extra padding */ 10, this.growMin));
\r
401 this.el.setWidth(w);
\r
402 this.fireEvent("autosize", this, w);
\r
405 Ext.reg('textfield', Ext.form.TextField);
\r