};
Roo.extend(Roo.form.Field, Roo.BoxComponent, {
-});
\ No newline at end of file
+ /**
+ * @cfg {String} fieldLabel Label to use when rendering a form.
+ */
+ /**
+ * @cfg {String} qtip Mouse over tip
+ */
+
+ /**
+ * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
+ */
+ invalidClass : "x-form-invalid",
+ /**
+ * @cfg {String} invalidText The error text to use when marking a field invalid and no message is provided (defaults to "The value in this field is invalid")
+ */
+ invalidText : "The value in this field is invalid",
+ /**
+ * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to "x-form-focus")
+ */
+ focusClass : "x-form-focus",
+ /**
+ * @cfg {String/Boolean} validationEvent The event that should initiate field validation. Set to false to disable
+ automatic validation (defaults to "keyup").
+ */
+ validationEvent : "keyup",
+ /**
+ * @cfg {Boolean} validateOnBlur Whether the field should validate when it loses focus (defaults to true).
+ */
+ validateOnBlur : true,
+ /**
+ * @cfg {Number} validationDelay The length of time in milliseconds after user input begins until validation is initiated (defaults to 250)
+ */
+ validationDelay : 250,
+ /**
+ * @cfg {String/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to
+ * {tag: "input", type: "text", size: "20", autocomplete: "off"})
+ */
+ defaultAutoCreate : {tag: "input", type: "text", size: "20", autocomplete: "off"},
+ /**
+ * @cfg {String} fieldClass The default CSS class for the field (defaults to "x-form-field")
+ */
+ fieldClass : "x-form-field",
+ /**
+ * @cfg {String} msgTarget The location where error text should display. Should be one of the following values (defaults to 'qtip'):
+ *<pre>
+Value Description
+----------- ----------------------------------------------------------------------
+qtip Display a quick tip when the user hovers over the field
+title Display a default browser title attribute popup
+under Add a block div beneath the field containing the error text
+side Add an error icon to the right of the field with a popup on hover
+[element id] Add the error text directly to the innerHTML of the specified element
+</pre>
+ */
+ msgTarget : 'qtip',
+ /**
+ * @cfg {String} msgFx <b>Experimental</b> The effect used when displaying a validation message under the field (defaults to 'normal').
+ */
+ msgFx : 'normal',
+
+ /**
+ * @cfg {Boolean} readOnly True to mark the field as readOnly in HTML (defaults to false) -- Note: this only sets the element's readOnly DOM attribute.
+ */
+ readOnly : false,
+
+ /**
+ * @cfg {Boolean} disabled True to disable the field (defaults to false).
+ */
+ disabled : false,
+
+ /**
+ * @cfg {String} inputType The type attribute for input fields -- e.g. radio, text, password (defaults to "text").
+ */
+ inputType : undefined,
+
+ /**
+ * @cfg {Number} tabIndex The tabIndex for this field. Note this only applies to fields that are rendered, not those which are built via applyTo (defaults to undefined).
+ */
+ tabIndex : undefined,
+
+ // private
+ isFormField : true,
+
+ // private
+ hasFocus : false,
+ /**
+ * @property {Roo.Element} fieldEl
+ * Element Containing the rendered Field (with label etc.)
+ */
+ /**
+ * @cfg {Mixed} value A value to initialize this field with.
+ */
+ value : undefined,
+
+ /**
+ * @cfg {String} name The field's HTML name attribute.
+ */
+ /**
+ * @cfg {String} cls A CSS class to apply to the field's underlying element.
+ */
+
+ // private ??
+ initComponent : function(){
+ Roo.form.Field.superclass.initComponent.call(this);
+ this.addEvents({
+ /**
+ * @event focus
+ * Fires when this field receives input focus.
+ * @param {Roo.form.Field} this
+ */
+ focus : true,
+ /**
+ * @event blur
+ * Fires when this field loses input focus.
+ * @param {Roo.form.Field} this
+ */
+ blur : true,
+ /**
+ * @event specialkey
+ * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed. You can check
+ * {@link Roo.EventObject#getKey} to determine which key was pressed.
+ * @param {Roo.form.Field} this
+ * @param {Roo.EventObject} e The event object
+ */
+ specialkey : true,
+ /**
+ * @event change
+ * Fires just before the field blurs if the field value has changed.
+ * @param {Roo.form.Field} this
+ * @param {Mixed} newValue The new value
+ * @param {Mixed} oldValue The original value
+ */
+ change : true,
+ /**
+ * @event invalid
+ * Fires after the field has been marked as invalid.
+ * @param {Roo.form.Field} this
+ * @param {String} msg The validation message
+ */
+ invalid : true,
+ /**
+ * @event valid
+ * Fires after the field has been validated with no errors.
+ * @param {Roo.form.Field} this
+ */
+ valid : true,
+ /**
+ * @event keyup
+ * Fires after the key up
+ * @param {Roo.form.Field} this
+ * @param {Roo.EventObject} e The event Object
+ */
+ keyup : true
+ });
+ },
+
+ /**
+ * Returns the name attribute of the field if available
+ * @return {String} name The field name
+ */
+ getName: function(){
+ return this.rendered && this.el.dom.name ? this.el.dom.name : (this.hiddenName || '');
+ },
+
+ // private
+ onRender : function(ct, position){
+ Roo.form.Field.superclass.onRender.call(this, ct, position);
+ if(!this.el){
+ var cfg = this.getAutoCreate();
+ if(!cfg.name){
+ cfg.name = typeof(this.name) == 'undefined' ? this.id : this.name;
+ }
+ if (!cfg.name.length) {
+ delete cfg.name;
+ }
+ if(this.inputType){
+ cfg.type = this.inputType;
+ }
+ this.el = ct.createChild(cfg, position);
+ }
+ var type = this.el.dom.type;
+ if(type){
+ if(type == 'password'){
+ type = 'text';
+ }
+ this.el.addClass('x-form-'+type);
+ }
+ if(this.readOnly){
+ this.el.dom.readOnly = true;
+ }
+ if(this.tabIndex !== undefined){
+ this.el.dom.setAttribute('tabIndex', this.tabIndex);
+ }
+
+ this.el.addClass([this.fieldClass, this.cls]);
+ this.initValue();
+ },
+
+ /**
+ * Apply the behaviors of this component to an existing element. <b>This is used instead of render().</b>
+ * @param {String/HTMLElement/Element} el The id of the node, a DOM node or an existing Element
+ * @return {Roo.form.Field} this
+ */
+ applyTo : function(target){
+ this.allowDomMove = false;
+ this.el = Roo.get(target);
+ this.render(this.el.dom.parentNode);
+ return this;
+ },
+
+ // private
+ initValue : function(){
+ if(this.value !== undefined){
+ this.setValue(this.value);
+ }else if(this.el.dom.value.length > 0){
+ this.setValue(this.el.dom.value);
+ }
+ },
+
+ /**
+ * Returns true if this field has been changed since it was originally loaded and is not disabled.
+ */
+ isDirty : function() {
+ if(this.disabled) {
+ return false;
+ }
+ return String(this.getValue()) !== String(this.originalValue);
+ },
+
+ // private
+ afterRender : function(){
+ Roo.form.Field.superclass.afterRender.call(this);
+ this.initEvents();
+ },
+
+ // private
+ fireKey : function(e){
+ //Roo.log('field ' + e.getKey());
+ if(e.isNavKeyPress()){
+ this.fireEvent("specialkey", this, e);
+ }
+ },
+
+ /**
+ * Resets the current field value to the originally loaded value and clears any validation messages
+ */
+ reset : function(){
+ this.setValue(this.originalValue);
+ this.clearInvalid();
+ },
+
+ // private
+ initEvents : function(){
+ // safari killled keypress - so keydown is now used..
+ this.el.on("keydown" , this.fireKey, this);
+ this.el.on("focus", this.onFocus, this);
+ this.el.on("blur", this.onBlur, this);
+ this.el.relayEvent('keyup', this);
+
+ // reference to original value for reset
+ this.originalValue = this.getValue();
+ },
+
+ // private
+ onFocus : function(){
+ if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
+ this.el.addClass(this.focusClass);
+ }
+ if(!this.hasFocus){
+ this.hasFocus = true;
+ this.startValue = this.getValue();
+ this.fireEvent("focus", this);
+ }
+ },
+
+ beforeBlur : Roo.emptyFn,
+
+ // private
+ onBlur : function(){
+ this.beforeBlur();
+ if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
+ this.el.removeClass(this.focusClass);
+ }
+ this.hasFocus = false;
+ if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
+ this.validate();
+ }
+ var v = this.getValue();
+ if(String(v) !== String(this.startValue)){
+ this.fireEvent('change', this, v, this.startValue);
+ }
+ this.fireEvent("blur", this);
+ },
+
+ /**
+ * Returns whether or not the field value is currently valid
+ * @param {Boolean} preventMark True to disable marking the field invalid
+ * @return {Boolean} True if the value is valid, else false
+ */
+ isValid : function(preventMark){
+ if(this.disabled){
+ return true;
+ }
+ var restore = this.preventMark;
+ this.preventMark = preventMark === true;
+ var v = this.validateValue(this.processValue(this.getRawValue()));
+ this.preventMark = restore;
+ return v;
+ },
+
+ /**
+ * Validates the field value
+ * @return {Boolean} True if the value is valid, else false
+ */
+ validate : function(){
+ if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
+ this.clearInvalid();
+ return true;
+ }
+ return false;
+ },
+
+ processValue : function(value){
+ return value;
+ },
+
+ // private
+ // Subclasses should provide the validation implementation by overriding this
+ validateValue : function(value){
+ return true;
+ },
+
+ /**
+ * Mark this field as invalid
+ * @param {String} msg The validation message
+ */
+ markInvalid : function(msg){
+ if(!this.rendered || this.preventMark){ // not rendered
+ return;
+ }
+ this.el.addClass(this.invalidClass);
+ msg = msg || this.invalidText;
+ switch(this.msgTarget){
+ case 'qtip':
+ this.el.dom.qtip = msg;
+ this.el.dom.qclass = 'x-form-invalid-tip';
+ if(Roo.QuickTips){ // fix for floating editors interacting with DND
+ Roo.QuickTips.enable();
+ }
+ break;
+ case 'title':
+ this.el.dom.title = msg;
+ break;
+ case 'under':
+ if(!this.errorEl){
+ var elp = this.el.findParent('.x-form-element', 5, true);
+ this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
+ this.errorEl.setWidth(elp.getWidth(true)-20);
+ }
+ this.errorEl.update(msg);
+ Roo.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
+ break;
+ case 'side':
+ if(!this.errorIcon){
+ var elp = this.el.findParent('.x-form-element', 5, true);
+ this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
+ }
+ this.alignErrorIcon();
+ this.errorIcon.dom.qtip = msg;
+ this.errorIcon.dom.qclass = 'x-form-invalid-tip';
+ this.errorIcon.show();
+ this.on('resize', this.alignErrorIcon, this);
+ break;
+ default:
+ var t = Roo.getDom(this.msgTarget);
+ t.innerHTML = msg;
+ t.style.display = this.msgDisplay;
+ break;
+ }
+ this.fireEvent('invalid', this, msg);
+ },
+
+ // private
+ alignErrorIcon : function(){
+ this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
+ },
+
+ /**
+ * Clear any invalid styles/messages for this field
+ */
+ clearInvalid : function(){
+ if(!this.rendered || this.preventMark){ // not rendered
+ return;
+ }
+ this.el.removeClass(this.invalidClass);
+ switch(this.msgTarget){
+ case 'qtip':
+ this.el.dom.qtip = '';
+ break;
+ case 'title':
+ this.el.dom.title = '';
+ break;
+ case 'under':
+ if(this.errorEl){
+ Roo.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
+ }
+ break;
+ case 'side':
+ if(this.errorIcon){
+ this.errorIcon.dom.qtip = '';
+ this.errorIcon.hide();
+ this.un('resize', this.alignErrorIcon, this);
+ }
+ break;
+ default:
+ var t = Roo.getDom(this.msgTarget);
+ t.innerHTML = '';
+ t.style.display = 'none';
+ break;
+ }
+ this.fireEvent('valid', this);
+ },
+
+ /**
+ * Returns the raw data value which may or may not be a valid, defined value. To return a normalized value see {@link #getValue}.
+ * @return {Mixed} value The field value
+ */
+ getRawValue : function(){
+ var v = this.el.getValue();
+ if(v === this.emptyText){
+ v = '';
+ }
+ return v;
+ },
+
+ /**
+ * Returns the normalized data value (undefined or emptyText will be returned as ''). To return the raw value see {@link #getRawValue}.
+ * @return {Mixed} value The field value
+ */
+ getValue : function(){
+ var v = this.el.getValue();
+ if(v === this.emptyText || v === undefined){
+ v = '';
+ }
+ return v;
+ },
+
+ /**
+ * Sets the underlying DOM field's value directly, bypassing validation. To set the value with validation see {@link #setValue}.
+ * @param {Mixed} value The value to set
+ */
+ setRawValue : function(v){
+ return this.el.dom.value = (v === null || v === undefined ? '' : v);
+ },
+
+ /**
+ * Sets a data value into the field and validates it. To set the value directly without validation see {@link #setRawValue}.
+ * @param {Mixed} value The value to set
+ */
+ setValue : function(v){
+ this.value = v;
+ if(this.rendered){
+ this.el.dom.value = (v === null || v === undefined ? '' : v);
+ this.validate();
+ }
+ },
+
+ adjustSize : function(w, h){
+ var s = Roo.form.Field.superclass.adjustSize.call(this, w, h);
+ s.width = this.adjustWidth(this.el.dom.tagName, s.width);
+ return s;
+ },
+
+ adjustWidth : function(tag, w){
+ tag = tag.toLowerCase();
+ if(typeof w == 'number' && Roo.isStrict && !Roo.isSafari){
+ if(Roo.isIE && (tag == 'input' || tag == 'textarea')){
+ if(tag == 'input'){
+ return w + 2;
+ }
+ if(tag = 'textarea'){
+ return w-2;
+ }
+ }else if(Roo.isOpera){
+ if(tag == 'input'){
+ return w + 2;
+ }
+ if(tag = 'textarea'){
+ return w-2;
+ }
+ }
+ }
+ return w;
+ }
+});
+
+
+// anything other than normal should be considered experimental
+Roo.form.Field.msgFx = {
+ normal : {
+ show: function(msgEl, f){
+ msgEl.setDisplayed('block');
+ },
+
+ hide : function(msgEl, f){
+ msgEl.setDisplayed(false).update('');
+ }
+ },
+
+ slide : {
+ show: function(msgEl, f){
+ msgEl.slideIn('t', {stopFx:true});
+ },
+
+ hide : function(msgEl, f){
+ msgEl.slideOut('t', {stopFx:true,useDisplay:true});
+ }
+ },
+
+ slideRight : {
+ show: function(msgEl, f){
+ msgEl.fixDisplay();
+ msgEl.alignTo(f.el, 'tl-tr');
+ msgEl.slideIn('l', {stopFx:true});
+ },
+
+ hide : function(msgEl, f){
+ msgEl.slideOut('l', {stopFx:true,useDisplay:true});
+ }
+ }
+};
\ No newline at end of file
};
Roo.extend(Roo.form.TextField, Roo.form.Field, {
+ /**
+ * @cfg {Boolean} grow True if this field should automatically grow and shrink to its content
+ */
+ grow : false,
+ /**
+ * @cfg {Number} growMin The minimum width to allow when grow = true (defaults to 30)
+ */
+ growMin : 30,
+ /**
+ * @cfg {Number} growMax The maximum width to allow when grow = true (defaults to 800)
+ */
+ growMax : 800,
+ /**
+ * @cfg {String} vtype A validation type name as defined in {@link Roo.form.VTypes} (defaults to null)
+ */
+ vtype : null,
+ /**
+ * @cfg {String} maskRe An input mask regular expression that will be used to filter keystrokes that don't match (defaults to null)
+ */
+ maskRe : null,
+ /**
+ * @cfg {Boolean} disableKeyFilter True to disable input keystroke filtering (defaults to false)
+ */
+ disableKeyFilter : false,
+ /**
+ * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to true)
+ */
+ allowBlank : true,
+ /**
+ * @cfg {Number} minLength Minimum input field length required (defaults to 0)
+ */
+ minLength : 0,
+ /**
+ * @cfg {Number} maxLength Maximum input field length allowed (defaults to Number.MAX_VALUE)
+ */
+ maxLength : Number.MAX_VALUE,
+ /**
+ * @cfg {String} minLengthText Error text to display if the minimum length validation fails (defaults to "The minimum length for this field is {minLength}")
+ */
+ minLengthText : "The minimum length for this field is {0}",
+ /**
+ * @cfg {String} maxLengthText Error text to display if the maximum length validation fails (defaults to "The maximum length for this field is {maxLength}")
+ */
+ maxLengthText : "The maximum length for this field is {0}",
+ /**
+ * @cfg {Boolean} selectOnFocus True to automatically select any existing field text when the field receives input focus (defaults to false)
+ */
+ selectOnFocus : false,
+ /**
+ * @cfg {String} blankText Error text to display if the allow blank validation fails (defaults to "This field is required")
+ */
+ blankText : "This field is required",
+ /**
+ * @cfg {Function} validator A custom validation function to be called during field validation (defaults to null).
+ * If available, this function will be called only after the basic validators all return true, and 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.
+ */
+ validator : null,
+ /**
+ * @cfg {RegExp} regex A JavaScript RegExp object to be tested against the field value during validation (defaults to null).
+ * If available, this regex will be evaluated only after the basic validators all return true, and will be passed the
+ * current field value. If the test fails, the field will be marked invalid using {@link #regexText}.
+ */
+ regex : null,
+ /**
+ * @cfg {String} regexText The error text to display if {@link #regex} is used and the test fails during validation (defaults to "")
+ */
+ regexText : "",
+ /**
+ * @cfg {String} emptyText The default text to display in an empty field (defaults to null).
+ */
+ emptyText : null,
+ /**
+ * @cfg {String} emptyClass The CSS class to apply to an empty field to style the {@link #emptyText} (defaults to
+ * 'x-form-empty-field'). This class is automatically added and removed as needed depending on the current field value.
+ */
+ emptyClass : 'x-form-empty-field',
+
+ // private
+ initEvents : function(){
+ Roo.form.TextField.superclass.initEvents.call(this);
+ if(this.validationEvent == 'keyup'){
+ this.validationTask = new Roo.util.DelayedTask(this.validate, this);
+ this.el.on('keyup', this.filterValidation, this);
+ }
+ else if(this.validationEvent !== false){
+ this.el.on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
+ }
+ if(this.selectOnFocus || this.emptyText){
+ this.on("focus", this.preFocus, this);
+ if(this.emptyText){
+ this.on('blur', this.postBlur, this);
+ this.applyEmptyText();
+ }
+ }
+ if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
+ this.el.on("keypress", this.filterKeys, this);
+ }
+ if(this.grow){
+ this.el.on("keyup", this.onKeyUp, this, {buffer:50});
+ this.el.on("click", this.autoSize, this);
+ }
+ },
+
+ processValue : function(value){
+ if(this.stripCharsRe){
+ var newValue = value.replace(this.stripCharsRe, '');
+ if(newValue !== value){
+ this.setRawValue(newValue);
+ return newValue;
+ }
+ }
+ return value;
+ },
+
+ filterValidation : function(e){
+ if(!e.isNavKeyPress()){
+ this.validationTask.delay(this.validationDelay);
+ }
+ },
+
+ // private
+ onKeyUp : function(e){
+ if(!e.isNavKeyPress()){
+ this.autoSize();
+ }
+ },
+
+ /**
+ * Resets the current field value to the originally-loaded value and clears any validation messages.
+ * Also adds emptyText and emptyClass if the original value was blank.
+ */
+ reset : function(){
+ Roo.form.TextField.superclass.reset.call(this);
+ this.applyEmptyText();
+ },
+
+ applyEmptyText : function(){
+ if(this.rendered && this.emptyText && this.getRawValue().length < 1){
+ this.setRawValue(this.emptyText);
+ this.el.addClass(this.emptyClass);
+ }
+ },
+
+ // private
+ preFocus : function(){
+ if(this.emptyText){
+ if(this.el.dom.value == this.emptyText){
+ this.setRawValue('');
+ }
+ this.el.removeClass(this.emptyClass);
+ }
+ if(this.selectOnFocus){
+ this.el.dom.select();
+ }
+ },
+
+ // private
+ postBlur : function(){
+ this.applyEmptyText();
+ },
+
+ // private
+ filterKeys : function(e){
+ var k = e.getKey();
+ if(!Roo.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
+ return;
+ }
+ var c = e.getCharCode(), cc = String.fromCharCode(c);
+ if(Roo.isIE && (e.isSpecialKey() || !cc)){
+ return;
+ }
+ if(!this.maskRe.test(cc)){
+ e.stopEvent();
+ }
+ },
+
+ setValue : function(v){
+ if(this.emptyText && this.el && v !== undefined && v !== null && v !== ''){
+ this.el.removeClass(this.emptyClass);
+ }
+ Roo.form.TextField.superclass.setValue.apply(this, arguments);
+ this.applyEmptyText();
+ this.autoSize();
+ },
+
+ /**
+ * 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
+ */
+ validateValue : function(value){
+ 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 < this.minLength){
+ this.markInvalid(String.format(this.minLengthText, this.minLength));
+ return false;
+ }
+ if(value.length > this.maxLength){
+ this.markInvalid(String.format(this.maxLengthText, this.maxLength));
+ return false;
+ }
+ if(this.vtype){
+ var vt = Roo.form.VTypes;
+ if(!vt[this.vtype](value, this)){
+ this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
+ return false;
+ }
+ }
+ if(typeof this.validator == "function"){
+ var msg = this.validator(value);
+ if(msg !== true){
+ this.markInvalid(msg);
+ return false;
+ }
+ }
+ if(this.regex && !this.regex.test(value)){
+ this.markInvalid(this.regexText);
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * Selects text in this field
+ * @param {Number} start (optional) The index where the selection should start (defaults to 0)
+ * @param {Number} end (optional) The index where the selection should end (defaults to the text length)
+ */
+ selectText : function(start, end){
+ var v = this.getRawValue();
+ if(v.length > 0){
+ start = start === undefined ? 0 : start;
+ end = end === undefined ? v.length : end;
+ var d = this.el.dom;
+ if(d.setSelectionRange){
+ d.setSelectionRange(start, end);
+ }else if(d.createTextRange){
+ var range = d.createTextRange();
+ range.moveStart("character", start);
+ range.moveEnd("character", v.length-end);
+ range.select();
+ }
+ }
+ },
+
+ /**
+ * Automatically grows the field to accomodate the width of the text up to the maximum field width allowed.
+ * This only takes effect if grow = true, and fires the autosize event.
+ */
+ autoSize : function(){
+ if(!this.grow || !this.rendered){
+ return;
+ }
+ if(!this.metrics){
+ this.metrics = Roo.util.TextMetrics.createInstance(this.el);
+ }
+ var el = this.el;
+ var v = el.dom.value;
+ var d = document.createElement('div');
+ d.appendChild(document.createTextNode(v));
+ v = d.innerHTML;
+ 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);
+ this.fireEvent("autosize", this, w);
+ }
});
\ No newline at end of file