X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/c930e9176a5a85509c5b0230e2bff5c22a591432..c8256059947f3aa8f5b0a9a2acf55e2142bb4742:/src/widgets/form/TextField.js?ds=inline
diff --git a/src/widgets/form/TextField.js b/src/widgets/form/TextField.js
index 2ecaa217..2f84e160 100644
--- a/src/widgets/form/TextField.js
+++ b/src/widgets/form/TextField.js
@@ -1,6 +1,6 @@
/*!
- * Ext JS Library 3.0.0
- * Copyright(c) 2006-2009 Ext JS, LLC
+ * Ext JS Library 3.2.1
+ * Copyright(c) 2006-2010 Ext JS, Inc.
* licensing@extjs.com
* http://www.extjs.com/license
*/
@@ -11,44 +11,10 @@
* or as the base class for more sophisticated input controls (like {@link Ext.form.TextArea}
* and {@link Ext.form.ComboBox}).
* Validation
- * Field validation is processed in a particular order. If validation fails at any particular
- * step the validation routine halts.
+ * The validation procedure is described in the documentation for {@link #validateValue}.
+ * Alter Validation Behavior
+ * Validation behavior for each field can be configured:
*
- * - 1. Field specific validator
- *
- *
If a field is configured with a {@link Ext.form.TextField#validator validator}
function,
- * it will be passed the current field value. The {@link Ext.form.TextField#validator validator}
- * function is expected to return boolean true if the value is valid or return a string to
- * represent the invalid message if invalid.
- *
- * - 2. Built in Validation
- *
- *
Basic validation is affected with the following configuration properties:
- *
- * Validation Invalid Message
- * {@link Ext.form.TextField#allowBlank allowBlank} {@link Ext.form.TextField#emptyText emptyText}
- * {@link Ext.form.TextField#minLength minLength} {@link Ext.form.TextField#minLengthText minLengthText}
- * {@link Ext.form.TextField#maxLength maxLength} {@link Ext.form.TextField#maxLengthText maxLengthText}
- *
- *
- * - 3. Preconfigured Validation Types (VTypes)
- *
- *
Using VTypes offers a convenient way to reuse validation. If a field is configured with a
- * {@link Ext.form.TextField#vtype vtype}
, the corresponding {@link Ext.form.VTypes VTypes}
- * validation function will be used for validation. If invalid, either the field's
- * {@link Ext.form.TextField#vtypeText vtypeText}
or the VTypes vtype Text property will be
- * used for the invalid message. Keystrokes on the field will be filtered according to the VTypes
- * vtype Mask property.
- *
- * - 4. Field specific regex test
- *
- *
Each field may also specify a {@link Ext.form.TextField#regex regex}
test.
- * The invalid message for this test is configured with
- * {@link Ext.form.TextField#regexText regexText}
.
- *
- * - Alter Validation Behavior
- *
- *
Validation behavior for each field can be configured:
* {@link Ext.form.TextField#invalidText invalidText}
: the default validation message to
* show if any validation step above does not provide a message when invalid
* {@link Ext.form.TextField#maskRe maskRe}
: filter out keystrokes before any validation occurs
@@ -58,12 +24,11 @@
* {@link Ext.form.Field#validateOnBlur validateOnBlur}
,
* {@link Ext.form.Field#validationDelay validationDelay}
, and
* {@link Ext.form.Field#validationEvent validationEvent}
: modify how/when validation is triggered
- *
- *
*
- * @constructor
- * Creates a new TextField
+ *
+ * @constructor Creates a new TextField
* @param {Object} config Configuration options
+ *
* @xtype textfield
*/
Ext.form.TextField = Ext.extend(Ext.form.Field, {
@@ -151,11 +116,22 @@ var myField = new Ext.form.NumberField({
*/
blankText : 'This field is required',
/**
- * @cfg {Function} validator A custom validation function to be called during field validation
+ * @cfg {Function} validator
+ * A custom validation function to be called during field validation ({@link #validateValue})
* (defaults to null). If specified, this function will be called first, allowing the
- * developer to override the default validation process. This function will be passed the current
- * field value and expected to return boolean true if the value is valid or a string
- * error message if invalid.
+ * developer to override the default validation process.
+ *
This function will be passed the following Parameters:
+ *
+ * value
: Mixed
+ * The current field value
+ *
+ *
This function is to Return:
+ *
*/
validator : null,
/**
@@ -234,22 +210,13 @@ var myField = new Ext.form.NumberField({
this.validationTask = new Ext.util.DelayedTask(this.validate, this);
this.mon(this.el, 'keyup', this.filterValidation, this);
}
- else if(this.validationEvent !== false){
+ else if(this.validationEvent !== false && this.validationEvent != 'blur'){
this.mon(this.el, this.validationEvent, this.validate, this, {buffer: this.validationDelay});
}
- if(this.selectOnFocus || this.emptyText){
- this.on('focus', this.preFocus, this);
-
- this.mon(this.el, 'mousedown', function(){
- if(!this.hasFocus){
- this.el.on('mouseup', function(e){
- e.preventDefault();
- }, this, {single:true});
- }
- }, this);
+ if(this.selectOnFocus || this.emptyText){
+ this.mon(this.el, 'mousedown', this.onMouseDown, this);
if(this.emptyText){
- this.on('blur', this.postBlur, this);
this.applyEmptyText();
}
}
@@ -261,9 +228,18 @@ var myField = new Ext.form.NumberField({
this.mon(this.el, 'click', this.autoSize, this);
}
if(this.enableKeyEvents){
- this.mon(this.el, 'keyup', this.onKeyUp, this);
- this.mon(this.el, 'keydown', this.onKeyDown, this);
- this.mon(this.el, 'keypress', this.onKeyPress, this);
+ this.mon(this.el, {
+ scope: this,
+ keyup: this.onKeyUp,
+ keydown: this.onKeyDown,
+ keypress: this.onKeyPress
+ });
+ }
+ },
+
+ onMouseDown: function(e){
+ if(!this.hasFocus){
+ this.mon(this.el, 'mouseup', Ext.emptyFn, this, { single: true, preventDefault: true });
}
},
@@ -302,10 +278,15 @@ var myField = new Ext.form.NumberField({
// private
onKeyUpBuffered : function(e){
- if(!e.isNavKeyPress()){
+ if(this.doAutoSize(e)){
this.autoSize();
}
},
+
+ // private
+ doAutoSize : function(e){
+ return !e.isNavKeyPress();
+ },
// private
onKeyUp : function(e){
@@ -349,9 +330,7 @@ var myField = new Ext.form.NumberField({
el.removeClass(this.emptyClass);
}
if(this.selectOnFocus){
- (function(){
- el.dom.select();
- }).defer(this.inEditor && Ext.isIE ? 50 : 0);
+ el.dom.select();
}
},
@@ -362,12 +341,18 @@ var myField = new Ext.form.NumberField({
// private
filterKeys : function(e){
- // special keys don't generate charCodes, so leave them alone
- if(e.ctrlKey || e.isSpecialKey()){
+ if(e.ctrlKey){
return;
}
-
- if(!this.maskRe.test(String.fromCharCode(e.getCharCode()))){
+ var k = e.getKey();
+ if(Ext.isGecko && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
+ return;
+ }
+ var cc = String.fromCharCode(e.getCharCode());
+ if(!Ext.isGecko && e.isSpecialKey() && !cc){
+ return;
+ }
+ if(!this.maskRe.test(cc)){
e.stopEvent();
}
},
@@ -383,48 +368,118 @@ var myField = new Ext.form.NumberField({
},
/**
- * Validates a value according to the field's validation rules and marks the field as invalid
- * if the validation fails
- * @param {Mixed} value The value to validate
- * @return {Boolean} True if the value is valid, else false
+ * Validates a value according to the field's validation rules and returns an array of errors
+ * for any failing validations. Validation rules are processed in the following order:
+ *
+ *
+ * - 1. Field specific validator
+ *
+ *
A validator offers a way to customize and reuse a validation specification.
+ * If a field is configured with a {@link #validator}
+ * function, it will be passed the current field value. The {@link #validator}
+ * function is expected to return either:
+ *
+ * - Boolean true if the value is valid (validation continues).
+ * - a String to represent the invalid message if invalid (validation halts).
+ *
+ *
+ *
+ * - 2. Basic Validation
+ *
+ *
If the {@link #validator}
has not halted validation,
+ * basic validation proceeds as follows:
+ *
+ *
+ *
+ * {@link #allowBlank}
: (Invalid message =
+ * {@link #emptyText}
)
+ * Depending on the configuration of {@link #allowBlank}
, a
+ * blank field will cause validation to halt at this step and return
+ * Boolean true or false accordingly.
+ *
+ *
+ * {@link #minLength}
: (Invalid message =
+ * {@link #minLengthText}
)
+ * If the passed value does not satisfy the {@link #minLength}
+ * specified, validation halts.
+ *
+ *
+ * {@link #maxLength}
: (Invalid message =
+ * {@link #maxLengthText}
)
+ * If the passed value does not satisfy the {@link #maxLength}
+ * specified, validation halts.
+ *
+ *
+ *
+ *
+ *
+ * - 3. Preconfigured Validation Types (VTypes)
+ *
+ *
If none of the prior validation steps halts validation, a field
+ * configured with a {@link #vtype}
will utilize the
+ * corresponding {@link Ext.form.VTypes VTypes} validation function.
+ * If invalid, either the field's {@link #vtypeText}
or
+ * the VTypes vtype Text property will be used for the invalid message.
+ * Keystrokes on the field will be filtered according to the VTypes
+ * vtype Mask property.
+ *
+ *
+ * - 4. Field specific regex test
+ *
+ *
If none of the prior validation steps halts validation, a field's
+ * configured {@link #regex}
test will be processed.
+ * The invalid message for this test is configured with
+ * {@link #regexText}
.
+ *
+ *
+ * @param {Mixed} value The value to validate. The processed raw value will be used if nothing is passed
+ * @return {Array} Array of any validation errors
*/
- validateValue : function(value){
- if(Ext.isFunction(this.validator)){
+ getErrors: function(value) {
+ var errors = Ext.form.TextField.superclass.getErrors.apply(this, arguments);
+
+ value = value || this.processValue(this.getRawValue());
+
+ if (Ext.isFunction(this.validator)) {
var msg = this.validator(value);
- if(msg !== true){
- this.markInvalid(msg);
- return false;
+ if (msg !== true) {
+ errors.push(msg);
}
}
- if(value.length < 1 || value === this.emptyText){ // if it's blank
- if(this.allowBlank){
- this.clearInvalid();
- return true;
- }else{
- this.markInvalid(this.blankText);
- return false;
- }
+
+ if (value.length < 1 || value === this.emptyText) {
+ if (this.allowBlank) {
+ //if value is blank and allowBlank is true, there cannot be any additional errors
+ return errors;
+ } else {
+ errors.push(this.blankText);
+ }
}
- if(value.length < this.minLength){
- this.markInvalid(String.format(this.minLengthText, this.minLength));
- return false;
+
+ if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) { // if it's blank
+ errors.push(this.blankText);
}
- if(value.length > this.maxLength){
- this.markInvalid(String.format(this.maxLengthText, this.maxLength));
- return false;
- }
- if(this.vtype){
+
+ if (value.length < this.minLength) {
+ errors.push(String.format(this.minLengthText, this.minLength));
+ }
+
+ if (value.length > this.maxLength) {
+ errors.push(String.format(this.maxLengthText, this.maxLength));
+ }
+
+ if (this.vtype) {
var vt = Ext.form.VTypes;
if(!vt[this.vtype](value, this)){
- this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
- return false;
+ errors.push(this.vtypeText || vt[this.vtype +'Text']);
}
}
- if(this.regex && !this.regex.test(value)){
- this.markInvalid(this.regexText);
- return false;
+
+ if (this.regex && !this.regex.test(value)) {
+ errors.push(this.regexText);
}
- return true;
+
+ return errors;
},
/**
@@ -472,8 +527,8 @@ var myField = new Ext.form.NumberField({
var d = document.createElement('div');
d.appendChild(document.createTextNode(v));
v = d.innerHTML;
- d = null;
Ext.removeNode(d);
+ d = null;
v += ' ';
var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + /* add extra padding */ 10, this.growMin));
this.el.setWidth(w);