4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-form-field-Text'>/**
19 </span> * @docauthor Jason Johnston <jason@sencha.com>
21 * A basic text field. Can be used as a direct replacement for traditional text inputs,
22 * or as the base class for more sophisticated input controls (like {@link Ext.form.field.TextArea}
23 * and {@link Ext.form.field.ComboBox}). Has support for empty-field placeholder values (see {@link #emptyText}).
27 * The Text field has a useful set of validations built in:
29 * - {@link #allowBlank} for making the field required
30 * - {@link #minLength} for requiring a minimum value length
31 * - {@link #maxLength} for setting a maximum value length (with {@link #enforceMaxLength} to add it
32 * as the `maxlength` attribute on the input element)
33 * - {@link #regex} to specify a custom regular expression for validation
35 * In addition, custom validations may be added:
37 * - {@link #vtype} specifies a virtual type implementation from {@link Ext.form.field.VTypes} which can contain
38 * custom validation logic
39 * - {@link #validator} allows a custom arbitrary function to be called during validation
41 * The details around how and when each of these validation options get used are described in the
42 * documentation for {@link #getErrors}.
44 * By default, the field value is checked for validity immediately while the user is typing in the
45 * field. This can be controlled with the {@link #validateOnChange}, {@link #checkChangeEvents}, and
46 * {@link #checkChangeBuffer} configurations. Also see the details on Form Validation in the
47 * {@link Ext.form.Panel} class documentation.
49 * # Masking and Character Stripping
51 * Text fields can be configured with custom regular expressions to be applied to entered values before
52 * validation: see {@link #maskRe} and {@link #stripCharsRe} for details.
57 * Ext.create('Ext.form.Panel', {
58 * title: 'Contact Info',
61 * renderTo: Ext.getBody(),
66 * allowBlank: false // requires a non-empty value
70 * fieldLabel: 'Email Address',
71 * vtype: 'email' // requires value to be a valid email address format
75 Ext.define('Ext.form.field.Text', {
76 extend:'Ext.form.field.Base',
77 alias: 'widget.textfield',
78 requires: ['Ext.form.field.VTypes', 'Ext.layout.component.field.Text'],
79 alternateClassName: ['Ext.form.TextField', 'Ext.form.Text'],
81 <span id='Ext-form-field-Text-cfg-vtypeText'> /**
82 </span> * @cfg {String} vtypeText
83 * A custom error message to display in place of the default message provided for the **`{@link #vtype}`** currently
84 * set for this field. **Note**: only applies if **`{@link #vtype}`** is set, else ignored.
87 <span id='Ext-form-field-Text-cfg-stripCharsRe'> /**
88 </span> * @cfg {RegExp} stripCharsRe
89 * A JavaScript RegExp object used to strip unwanted content from the value
90 * before validation. If <tt>stripCharsRe</tt> is specified,
91 * every character matching <tt>stripCharsRe</tt> will be removed before fed to validation.
92 * This does not change the value of the field.
95 <span id='Ext-form-field-Text-cfg-size'> /**
96 </span> * @cfg {Number} size
97 * An initial value for the 'size' attribute on the text input element. This is only used if the field has no
98 * configured {@link #width} and is not given a width by its container's layout. Defaults to 20.
102 <span id='Ext-form-field-Text-cfg-grow'> /**
103 </span> * @cfg {Boolean} [grow=false]
104 * true if this field should automatically grow and shrink to its content
107 <span id='Ext-form-field-Text-cfg-growMin'> /**
108 </span> * @cfg {Number} growMin
109 * The minimum width to allow when `{@link #grow} = true`
113 <span id='Ext-form-field-Text-cfg-growMax'> /**
114 </span> * @cfg {Number} growMax
115 * The maximum width to allow when `{@link #grow} = true`
119 <span id='Ext-form-field-Text-cfg-growAppend'> /**
120 </span> * @cfg {String} growAppend
121 * A string that will be appended to the field's current value for the purposes of calculating the target field
122 * size. Only used when the {@link #grow} config is true. Defaults to a single capital "W" (the widest character in
123 * common fonts) to leave enough space for the next typed character and avoid the field value shifting before the
128 <span id='Ext-form-field-Text-cfg-vtype'> /**
129 </span> * @cfg {String} vtype
130 * A validation type name as defined in {@link Ext.form.field.VTypes}
133 <span id='Ext-form-field-Text-cfg-maskRe'> /**
134 </span> * @cfg {RegExp} maskRe An input mask regular expression that will be used to filter keystrokes (character being
135 * typed) that do not match.
136 * Note: It dose not filter characters already in the input.
139 <span id='Ext-form-field-Text-cfg-disableKeyFilter'> /**
140 </span> * @cfg {Boolean} [disableKeyFilter=false]
141 * Specify true to disable input keystroke filtering
144 <span id='Ext-form-field-Text-cfg-allowBlank'> /**
145 </span> * @cfg {Boolean} allowBlank
146 * Specify false to validate that the value's length is > 0
150 <span id='Ext-form-field-Text-cfg-minLength'> /**
151 </span> * @cfg {Number} minLength
152 * Minimum input field length required
156 <span id='Ext-form-field-Text-cfg-maxLength'> /**
157 </span> * @cfg {Number} maxLength
158 * Maximum input field length allowed by validation (defaults to Number.MAX_VALUE). This behavior is intended to
159 * provide instant feedback to the user by improving usability to allow pasting and editing or overtyping and back
160 * tracking. To restrict the maximum number of characters that can be entered into the field use the **{@link
161 * Ext.form.field.Text#enforceMaxLength enforceMaxLength}** option.
163 maxLength : Number.MAX_VALUE,
165 <span id='Ext-form-field-Text-cfg-enforceMaxLength'> /**
166 </span> * @cfg {Boolean} enforceMaxLength
167 * True to set the maxLength property on the underlying input field. Defaults to false
170 <span id='Ext-form-field-Text-cfg-minLengthText'> /**
171 </span> * @cfg {String} minLengthText
172 * Error text to display if the **{@link #minLength minimum length}** validation fails.
174 minLengthText : 'The minimum length for this field is {0}',
176 <span id='Ext-form-field-Text-cfg-maxLengthText'> /**
177 </span> * @cfg {String} maxLengthText
178 * Error text to display if the **{@link #maxLength maximum length}** validation fails
180 maxLengthText : 'The maximum length for this field is {0}',
182 <span id='Ext-form-field-Text-cfg-selectOnFocus'> /**
183 </span> * @cfg {Boolean} [selectOnFocus=false]
184 * true to automatically select any existing field text when the field receives input focus
187 <span id='Ext-form-field-Text-cfg-blankText'> /**
188 </span> * @cfg {String} blankText
189 * The error text to display if the **{@link #allowBlank}** validation fails
191 blankText : 'This field is required',
193 <span id='Ext-form-field-Text-cfg-validator'> /**
194 </span> * @cfg {Function} validator
195 * A custom validation function to be called during field validation ({@link #getErrors}).
196 * If specified, this function will be called first, allowing the developer to override the default validation
199 * This function will be passed the following parameters:
201 * @cfg {Object} validator.value The current field value
202 * @cfg {Boolean/String} validator.return
204 * - True if the value is valid
205 * - An error message if the value is invalid
208 <span id='Ext-form-field-Text-cfg-regex'> /**
209 </span> * @cfg {RegExp} regex A JavaScript RegExp object to be tested against the field value during validation.
210 * If the test fails, the field will be marked invalid using
211 * either <b><tt>{@link #regexText}</tt></b> or <b><tt>{@link #invalidText}</tt></b>.
214 <span id='Ext-form-field-Text-cfg-regexText'> /**
215 </span> * @cfg {String} regexText
216 * The error text to display if **{@link #regex}** is used and the test fails during validation
220 <span id='Ext-form-field-Text-cfg-emptyText'> /**
221 </span> * @cfg {String} emptyText
222 * The default text to place into an empty field.
224 * Note that normally this value will be submitted to the server if this field is enabled; to prevent this you can
225 * set the {@link Ext.form.action.Action#submitEmptyText submitEmptyText} option of {@link Ext.form.Basic#submit} to
228 * Also note that if you use {@link #inputType inputType}:'file', {@link #emptyText} is not supported and should be
232 <span id='Ext-form-field-Text-cfg-emptyCls'> /**
233 </span> * @cfg {String} [emptyCls='x-form-empty-field']
234 * The CSS class to apply to an empty field to style the **{@link #emptyText}**.
235 * This class is automatically added and removed as needed depending on the current field value.
237 emptyCls : Ext.baseCSSPrefix + 'form-empty-field',
241 <span id='Ext-form-field-Text-cfg-enableKeyEvents'> /**
242 </span> * @cfg {Boolean} [enableKeyEvents=false]
243 * true to enable the proxying of key events for the HTML input field
246 componentLayout: 'textfield',
248 initComponent : function(){
251 <span id='Ext-form-field-Text-event-autosize'> /**
252 </span> * @event autosize
253 * Fires when the **{@link #autoSize}** function is triggered and the field is resized according to the
254 * {@link #grow}/{@link #growMin}/{@link #growMax} configs as a result. This event provides a hook for the
255 * developer to apply additional logic at runtime to resize the field if needed.
256 * @param {Ext.form.field.Text} this This text field
257 * @param {Number} width The new field width
261 <span id='Ext-form-field-Text-event-keydown'> /**
262 </span> * @event keydown
263 * Keydown input field event. This event only fires if **{@link #enableKeyEvents}** is set to true.
264 * @param {Ext.form.field.Text} this This text field
265 * @param {Ext.EventObject} e
268 <span id='Ext-form-field-Text-event-keyup'> /**
269 </span> * @event keyup
270 * Keyup input field event. This event only fires if **{@link #enableKeyEvents}** is set to true.
271 * @param {Ext.form.field.Text} this This text field
272 * @param {Ext.EventObject} e
275 <span id='Ext-form-field-Text-event-keypress'> /**
276 </span> * @event keypress
277 * Keypress input field event. This event only fires if **{@link #enableKeyEvents}** is set to true.
278 * @param {Ext.form.field.Text} this This text field
279 * @param {Ext.EventObject} e
286 initEvents : function(){
291 if(me.selectOnFocus || me.emptyText){
292 me.mon(el, 'mousedown', me.onMouseDown, me);
294 if(me.maskRe || (me.vtype && me.disableKeyFilter !== true && (me.maskRe = Ext.form.field.VTypes[me.vtype+'Mask']))){
295 me.mon(el, 'keypress', me.filterKeys, me);
298 if (me.enableKeyEvents) {
302 keydown: me.onKeyDown,
303 keypress: me.onKeyPress
308 <span id='Ext-form-field-Text-method-isEqual'> /**
310 * Override. Treat undefined and null values as equal to an empty string value.
312 isEqual: function(value1, value2) {
313 return this.isEqualAsString(value1, value2);
316 <span id='Ext-form-field-Text-method-onChange'> /**
318 * If grow=true, invoke the autoSize method when the field's value is changed.
320 onChange: function() {
325 afterRender: function(){
327 if (me.enforceMaxLength) {
328 me.inputEl.dom.maxLength = me.maxLength;
335 onMouseDown: function(e){
338 me.mon(me.inputEl, 'mouseup', Ext.emptyFn, me, { single: true, preventDefault: true });
342 <span id='Ext-form-field-Text-method-processRawValue'> /**
343 </span> * Performs any necessary manipulation of a raw String value to prepare it for conversion and/or
344 * {@link #validate validation}. For text fields this applies the configured {@link #stripCharsRe}
346 * @param {String} value The unprocessed string value
347 * @return {String} The processed string value
349 processRawValue: function(value) {
351 stripRe = me.stripCharsRe,
355 newValue = value.replace(stripRe, '');
356 if (newValue !== value) {
357 me.setRawValue(newValue);
365 onDisable: function(){
368 this.inputEl.dom.unselectable = 'on';
373 onEnable: function(){
376 this.inputEl.dom.unselectable = '';
380 onKeyDown: function(e) {
381 this.fireEvent('keydown', this, e);
384 onKeyUp: function(e) {
385 this.fireEvent('keyup', this, e);
388 onKeyPress: function(e) {
389 this.fireEvent('keypress', this, e);
392 <span id='Ext-form-field-Text-method-reset'> /**
393 </span> * Resets the current field value to the originally-loaded value and clears any validation messages.
394 * Also adds **{@link #emptyText}** and **{@link #emptyCls}** if the original value was blank.
398 this.applyEmptyText();
401 applyEmptyText : function(){
403 emptyText = me.emptyText,
406 if (me.rendered && emptyText) {
407 isEmpty = me.getRawValue().length < 1 && !me.hasFocus;
409 if (Ext.supports.Placeholder) {
410 me.inputEl.dom.placeholder = emptyText;
411 } else if (isEmpty) {
412 me.setRawValue(emptyText);
415 //all browsers need this because of a styling issue with chrome + placeholders.
416 //the text isnt vertically aligned when empty (and using the placeholder)
418 me.inputEl.addCls(me.emptyCls);
426 preFocus : function(){
428 inputEl = me.inputEl,
429 emptyText = me.emptyText,
432 if (emptyText && !Ext.supports.Placeholder && inputEl.dom.value === emptyText) {
435 inputEl.removeCls(me.emptyCls);
436 } else if (Ext.supports.Placeholder) {
437 me.inputEl.removeCls(me.emptyCls);
439 if (me.selectOnFocus || isEmpty) {
440 inputEl.dom.select();
444 onFocus: function() {
446 me.callParent(arguments);
453 postBlur : function(){
454 this.applyEmptyText();
458 filterKeys : function(e){
460 * On European keyboards, the right alt key, Alt Gr, is used to type certain special characters.
461 * JS detects a keypress of this as ctrlKey & altKey. As such, we check that alt isn't pressed
462 * so we can still process these special characters.
464 if (e.ctrlKey && !e.altKey) {
467 var key = e.getKey(),
468 charCode = String.fromCharCode(e.getCharCode());
470 if(Ext.isGecko && (e.isNavKeyPress() || key === e.BACKSPACE || (key === e.DELETE && e.button === -1))){
474 if(!Ext.isGecko && e.isSpecialKey() && !charCode){
477 if(!this.maskRe.test(charCode)){
482 <span id='Ext-form-field-Text-method-getRawValue'> /**
483 </span> * Returns the raw String value of the field, without performing any normalization, conversion, or validation. Gets
484 * the current value of the input element if the field has been rendered, ignoring the value if it is the
485 * {@link #emptyText}. To get a normalized and converted value see {@link #getValue}.
486 * @return {String} The raw String value of the field
488 getRawValue: function() {
491 if (v === me.emptyText) {
497 <span id='Ext-form-field-Text-method-setValue'> /**
498 </span> * Sets a data value into the field and runs the change detection and validation. Also applies any configured
499 * {@link #emptyText} for text fields. To set the value directly without these inspections see {@link #setRawValue}.
500 * @param {Object} value The value to set
501 * @return {Ext.form.field.Text} this
503 setValue: function(value) {
505 inputEl = me.inputEl;
507 if (inputEl && me.emptyText && !Ext.isEmpty(value)) {
508 inputEl.removeCls(me.emptyCls);
511 me.callParent(arguments);
517 <span id='Ext-form-field-Text-method-getErrors'> /**
518 </span> * Validates a value according to the field's validation rules and returns an array of errors
519 * for any failing validations. Validation rules are processed in the following order:
521 * 1. **Field specific validator**
523 * A validator offers a way to customize and reuse a validation specification.
524 * If a field is configured with a `{@link #validator}`
525 * function, it will be passed the current field value. The `{@link #validator}`
526 * function is expected to return either:
528 * - Boolean `true` if the value is valid (validation continues).
529 * - a String to represent the invalid message if invalid (validation halts).
531 * 2. **Basic Validation**
533 * If the `{@link #validator}` has not halted validation,
534 * basic validation proceeds as follows:
536 * - `{@link #allowBlank}` : (Invalid message = `{@link #emptyText}`)
538 * Depending on the configuration of `{@link #allowBlank}`, a
539 * blank field will cause validation to halt at this step and return
540 * Boolean true or false accordingly.
542 * - `{@link #minLength}` : (Invalid message = `{@link #minLengthText}`)
544 * If the passed value does not satisfy the `{@link #minLength}`
545 * specified, validation halts.
547 * - `{@link #maxLength}` : (Invalid message = `{@link #maxLengthText}`)
549 * If the passed value does not satisfy the `{@link #maxLength}`
550 * specified, validation halts.
552 * 3. **Preconfigured Validation Types (VTypes)**
554 * If none of the prior validation steps halts validation, a field
555 * configured with a `{@link #vtype}` will utilize the
556 * corresponding {@link Ext.form.field.VTypes VTypes} validation function.
557 * If invalid, either the field's `{@link #vtypeText}` or
558 * the VTypes vtype Text property will be used for the invalid message.
559 * Keystrokes on the field will be filtered according to the VTypes
560 * vtype Mask property.
562 * 4. **Field specific regex test**
564 * If none of the prior validation steps halts validation, a field's
565 * configured <code>{@link #regex}</code> test will be processed.
566 * The invalid message for this test is configured with `{@link #regexText}`
568 * @param {Object} value The value to validate. The processed raw value will be used if nothing is passed.
569 * @return {String[]} Array of any validation errors
571 getErrors: function(value) {
573 errors = me.callParent(arguments),
574 validator = me.validator,
575 emptyText = me.emptyText,
576 allowBlank = me.allowBlank,
578 vtypes = Ext.form.field.VTypes,
580 format = Ext.String.format,
583 value = value || me.processRawValue(me.getRawValue());
585 if (Ext.isFunction(validator)) {
586 msg = validator.call(me, value);
592 if (value.length < 1 || value === emptyText) {
594 errors.push(me.blankText);
596 //if value is blank, there cannot be any additional errors
600 if (value.length < me.minLength) {
601 errors.push(format(me.minLengthText, me.minLength));
604 if (value.length > me.maxLength) {
605 errors.push(format(me.maxLengthText, me.maxLength));
609 if(!vtypes[vtype](value, me)){
610 errors.push(me.vtypeText || vtypes[vtype +'Text']);
614 if (regex && !regex.test(value)) {
615 errors.push(me.regexText || me.invalidText);
621 <span id='Ext-form-field-Text-method-selectText'> /**
622 </span> * Selects text in this field
623 * @param {Number} [start=0] The index where the selection should start
624 * @param {Number} [end] The index where the selection should end (defaults to the text length)
626 selectText : function(start, end){
628 v = me.getRawValue(),
634 if (v.length > 0) {
635 start = start === undef ? 0 : start;
636 end = end === undef ? v.length : end;
637 if (el.setSelectionRange) {
638 el.setSelectionRange(start, end);
640 else if(el.createTextRange) {
641 range = el.createTextRange();
642 range.moveStart('character', start);
643 range.moveEnd('character', end - v.length);
646 doFocus = Ext.isGecko || Ext.isOpera;
653 <span id='Ext-form-field-Text-method-autoSize'> /**
654 </span> * Automatically grows the field to accomodate the width of the text up to the maximum field width allowed. This
655 * only takes effect if {@link #grow} = true, and fires the {@link #autosize} event if the width changes.
657 autoSize: function() {
660 if (me.grow && me.rendered) {
661 me.doComponentLayout();
662 width = me.inputEl.getWidth();
663 if (width !== me.lastInputWidth) {
664 me.fireEvent('autosize', width);
665 me.lastInputWidth = width;
670 initAria: function() {
672 this.getActionEl().dom.setAttribute('aria-required', this.allowBlank === false);
675 <span id='Ext-form-field-Text-method-getBodyNaturalWidth'> /**
676 </span> * To get the natural width of the inputEl, we do a simple calculation based on the 'size' config. We use
677 * hard-coded numbers to approximate what browsers do natively, to avoid having to read any styles which would hurt
678 * performance. Overrides Labelable method.
681 getBodyNaturalWidth: function() {
682 return Math.round(this.size * 6.5) + 20;