PDA

View Full Version : [2.0b1] Ext.form.PlainTextArea



punkrider
24 Oct 2007, 5:15 PM
I was needing the resizing functionality of Ext.form.TextArea, but with a few tweaks. Here is what I have created so far.

Constructive criticism and questions are appreciated.



/**
* @class Ext.form.PlainTextArea
* @extends Ext.form.TextArea
* Multiline text field. Can be used as a direct replacement for traditional textarea fields, plus adds
* support for better auto-sizing than Ext.form.TextArea.
* @constructor
* Creates a new PlainTextArea
* @param {Object} config Configuration options
*/
Ext.form.PlainTextArea = Ext.extend(Ext.form.TextArea, {
autoHeight: true,
grow: true,
preventScrollbars: true,
growAppend : '.',
growMax : 30000,
growMin : 15,
growPad : 15,
/**
* @cfg {String/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to
* {tag: "textarea", style: "width:100px;height:60px;", autocomplete: "off"})
*/

// private
onRender : function(ct, position){
Ext.form.PlainTextArea.superclass.onRender.call(this, ct, position);

if(this.grow && this.el && this.textSizeEl)
Ext.get(this.textSizeEl).setStyle(this.el.getStyles('padding-top', 'padding-left', 'padding-bottom', 'padding-top', 'font-size','font-style', 'font-weight', 'font-family','line-height'));
},

/**
* Automatically grows the field to accomodate the height of the text up to the maximum field height allowed.
* This only takes effect if grow = true, and fires the autosize event if the height changes.
*/
autoSize : function(){
if(!this.grow || !this.textSizeEl){
return;
}

var v = this.el.dom.value;
var ts = this.textSizeEl;
ts.innerHTML = '';
if(Ext.isIE){
v = v.replace(/\n/g, '');
}
v += this.growAppend;

ts.appendChild(document.createTextNode(v));

Ext.fly(ts).setWidth(this.el.getWidth());
var curHeight = ts.offsetHeight;

var h = Math.min(this.growMax, Math.max(curHeight, this.growMin)+this.growPad);
if(h != this.lastHeight){
this.lastHeight = h;
this.el.setHeight(h);
this.fireEvent("autosize", this, h);
}
}
});
Ext.reg('plaintextarea', Ext.form.PlainTextArea);


I do find it interesting that Ext.form.TextArea doesn't use the Ext.util.TextMetrics class to size itself. As far as I can tell it's due to needing to use createTextNode versus createElement for correct sizing within the TEXTAREA element, as it similarly doesn't render HTML markup.

I'll continue posting to this thread as I clean it up more.

Enjoy ;)


Example usage:


new Ext.form.PlainTextArea({ applyTo: 'myTextArea' });

Grimsk
26 Oct 2007, 6:25 AM
any chance for a live demo? :">

brian.moeskau
26 Oct 2007, 1:02 PM
FYI, you should be using the ux namespace to avoid any potential future clashes with something Ext might come out with (e.g., Ext.ux.PlainTextArea). Also, maybe a different name than PlainTextArea? I'm not sure what makes it "plain" :-/

Maybe something more like FitTextArea, or something that otherwise implies the sizing aspect of the extension?

KRavEN
4 Dec 2007, 5:35 AM
I needed this as preventScrollbars on Ext.form.TextArea doesn't prevent them in IE6.
Redone with Brian's suggestions:


/**
* @class Ext.ux.FitTextArea
* @extends Ext.ux.FitTextArea
* Multiline text field. Can be used as a direct replacement for traditional textarea fields, plus adds
* support for better auto-sizing than Ext.ux.FitTextArea.
* @constructor
* Creates a new FitTextArea
* @param {Object} config Configuration options
*/
Ext.ux.FitTextArea = Ext.extend(Ext.form.TextArea, {
autoHeight: true,
grow: true,
preventScrollbars: true,
growAppend : '.',
growMax : 30000,
growMin : 15,
growPad : 15,
/**
* @cfg {String/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to
* {tag: "textarea", style: "width:100px;height:60px;", autocomplete: "off"})
*/

// private
onRender : function(ct, position){
Ext.ux.FitTextArea.superclass.onRender.call(this, ct, position);

if(this.grow && this.el && this.textSizeEl)
Ext.get(this.textSizeEl).setStyle(this.el.getStyles('padding-top', 'padding-left', 'padding-bottom', 'padding-top', 'font-size','font-style', 'font-weight', 'font-family','line-height'));
},

/**
* Automatically grows the field to accomodate the height of the text up to the maximum field height allowed.
* This only takes effect if grow = true, and fires the autosize event if the height changes.
*/
autoSize : function(){
if(!this.grow || !this.textSizeEl){
return;
}

var v = this.el.dom.value;
var ts = this.textSizeEl;
ts.innerHTML = '';
if(Ext.isIE){
v = v.replace(/\n/g, '');
}
v += this.growAppend;

ts.appendChild(document.createTextNode(v));

Ext.fly(ts).setWidth(this.el.getWidth());
var curHeight = ts.offsetHeight;

var h = Math.min(this.growMax, Math.max(curHeight, this.growMin)+this.growPad);
if(h != this.lastHeight){
this.lastHeight = h;
this.el.setHeight(h);
this.fireEvent("autosize", this, h);
}
}
});
Ext.reg('fittextarea', Ext.ux.FitTextArea);

Also use like any other form element:

new Ext.ux.FitTextArea({fieldLabel:'Shipping Address',name: 'siteshipping'})

KRavEN
4 Dec 2007, 5:52 AM
The only problem I see with it is the width is a few pixels wider than other form elements when using an anchor percentage in IE6. I'm sure it's the typical IE box model problem. This used to also effect the Ext.form.TextArea in Ext1.1.