Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / src / form / field / TextArea.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * @class Ext.form.field.TextArea
17  * @extends Ext.form.field.Text
18
19 This class creates a multiline text field, which can be used as a direct replacement for traditional 
20 textarea fields. In addition, it supports automatically {@link #grow growing} the height of the textarea to 
21 fit its content.
22
23 All of the configuration options from {@link Ext.form.field.Text} can be used on TextArea.
24 {@img Ext.form.TextArea/Ext.form.TextArea.png Ext.form.TextArea component}
25 Example usage:
26
27     Ext.create('Ext.form.FormPanel', {
28         title      : 'Sample TextArea',
29         width      : 400,
30         bodyPadding: 10,
31         renderTo   : Ext.getBody(),
32         items: [{
33             xtype     : 'textareafield',
34             grow      : true,
35             name      : 'message',
36             fieldLabel: 'Message',
37             anchor    : '100%'
38         }]
39     }); 
40
41 Some other useful configuration options when using {@link #grow} are {@link #growMin} and {@link #growMax}. These 
42 allow you to set the minimum and maximum grow heights for the textarea.
43
44  * @docauthor Robert Dougan <rob@sencha.com>
45  */
46 Ext.define('Ext.form.field.TextArea', {
47     extend:'Ext.form.field.Text',
48     alias: ['widget.textareafield', 'widget.textarea'],
49     alternateClassName: 'Ext.form.TextArea',
50     requires: ['Ext.XTemplate', 'Ext.layout.component.field.TextArea'],
51
52     fieldSubTpl: [
53         '<textarea id="{id}" ',
54             '<tpl if="name">name="{name}" </tpl>',
55             '<tpl if="rows">rows="{rows}" </tpl>',
56             '<tpl if="cols">cols="{cols}" </tpl>',
57             '<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
58             'class="{fieldCls} {typeCls}" ',
59             'autocomplete="off">',
60         '</textarea>',
61         {
62             compiled: true,
63             disableFormats: true
64         }
65     ],
66
67     /**
68      * @cfg {Number} growMin The minimum height to allow when <tt>{@link Ext.form.field.Text#grow grow}=true</tt>
69      * (defaults to <tt>60</tt>)
70      */
71     growMin: 60,
72
73     /**
74      * @cfg {Number} growMax The maximum height to allow when <tt>{@link Ext.form.field.Text#grow grow}=true</tt>
75      * (defaults to <tt>1000</tt>)
76      */
77     growMax: 1000,
78
79     /**
80      * @cfg {String} growAppend
81      * A string that will be appended to the field's current value for the purposes of calculating the target
82      * field size. Only used when the {@link #grow} config is <tt>true</tt>. Defaults to a newline for TextArea
83      * to ensure there is always a space below the current line.
84      */
85     growAppend: '\n-',
86
87     /**
88      * @cfg {Number} cols An initial value for the 'cols' attribute on the textarea element. This is only
89      * used if the component has no configured {@link #width} and is not given a width by its container's
90      * layout. Defaults to <tt>20</tt>.
91      */
92     cols: 20,
93
94     /**
95      * @cfg {Number} cols An initial value for the 'cols' attribute on the textarea element. This is only
96      * used if the component has no configured {@link #width} and is not given a width by its container's
97      * layout. Defaults to <tt>4</tt>.
98      */
99     rows: 4,
100
101     /**
102      * @cfg {Boolean} enterIsSpecial
103      * True if you want the enter key to be classed as a <tt>special</tt> key. Special keys are generally navigation
104      * keys (arrows, space, enter). Setting the config property to <tt>true</tt> would mean that you could not insert
105      * returns into the textarea.
106      * (defaults to <tt>false</tt>)
107      */
108     enterIsSpecial: false,
109
110     /**
111      * @cfg {Boolean} preventScrollbars <tt>true</tt> to prevent scrollbars from appearing regardless of how much text is
112      * in the field. This option is only relevant when {@link #grow} is <tt>true</tt>. Equivalent to setting overflow: hidden, defaults to
113      * <tt>false</tt>.
114      */
115     preventScrollbars: false,
116
117     // private
118     componentLayout: 'textareafield',
119
120     // private
121     onRender: function(ct, position) {
122         var me = this;
123         Ext.applyIf(me.subTplData, {
124             cols: me.cols,
125             rows: me.rows
126         });
127
128         me.callParent(arguments);
129     },
130
131     // private
132     afterRender: function(){
133         var me = this;
134
135         me.callParent(arguments);
136
137         if (me.grow) {
138             if (me.preventScrollbars) {
139                 me.inputEl.setStyle('overflow', 'hidden');
140             }
141             me.inputEl.setHeight(me.growMin);
142         }
143     },
144
145     // private
146     fireKey: function(e) {
147         if (e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() !== e.ENTER || e.hasModifier()))) {
148             this.fireEvent('specialkey', this, e);
149         }
150     },
151
152     /**
153      * Automatically grows the field to accomodate the height of the text up to the maximum field height allowed.
154      * This only takes effect if <tt>{@link #grow} = true</tt>, and fires the {@link #autosize} event if
155      * the height changes.
156      */
157     autoSize: function() {
158         var me = this,
159             height;
160
161         if (me.grow && me.rendered) {
162             me.doComponentLayout();
163             height = me.inputEl.getHeight();
164             if (height !== me.lastInputHeight) {
165                 me.fireEvent('autosize', height);
166                 me.lastInputHeight = height;
167             }
168         }
169     },
170
171     // private
172     initAria: function() {
173         this.callParent(arguments);
174         this.getActionEl().dom.setAttribute('aria-multiline', true);
175     },
176
177     /**
178      * @protected override
179      * To get the natural width of the textarea element, we do a simple calculation based on the
180      * 'cols' config. We use hard-coded numbers to approximate what browsers do natively,
181      * to avoid having to read any styles which would hurt performance.
182      */
183     getBodyNaturalWidth: function() {
184         return Math.round(this.cols * 6.5) + 20;
185     }
186
187 });
188
189