Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / docs / source / FieldContainer.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-form-FieldContainer-method-constructor'><span id='Ext-form-FieldContainer'>/**
19 </span></span> * @class Ext.form.FieldContainer
20  * @extends Ext.container.Container
21
22 FieldContainer is a derivation of {@link Ext.container.Container Container} that implements the
23 {@link Ext.form.Labelable Labelable} mixin. This allows it to be configured so that it is rendered with
24 a {@link #fieldLabel field label} and optional {@link #msgTarget error message} around its sub-items.
25 This is useful for arranging a group of fields or other components within a single item in a form, so
26 that it lines up nicely with other fields. A common use is for grouping a set of related fields under
27 a single label in a form.
28
29 The container's configured {@link #items} will be layed out within the field body area according to the
30 configured {@link #layout} type. The default layout is `'autocontainer'`.
31
32 Like regular fields, FieldContainer can inherit its decoration configuration from the
33 {@link Ext.form.Panel#fieldDefaults fieldDefaults} of an enclosing FormPanel. In addition,
34 FieldContainer itself can pass {@link #fieldDefaults} to any {@link Ext.form.Labelable fields}
35 it may itself contain.
36
37 If you are grouping a set of {@link Ext.form.field.Checkbox Checkbox} or {@link Ext.form.field.Radio Radio}
38 fields in a single labeled container, consider using a {@link Ext.form.CheckboxGroup}
39 or {@link Ext.form.RadioGroup} instead as they are specialized for handling those types.
40 {@img Ext.form.FieldContainer/Ext.form.FieldContainer1.png Ext.form.FieldContainer component}
41 __Example usage:__
42
43     Ext.create('Ext.form.Panel', {
44         title: 'FieldContainer Example',
45         width: 550,
46         bodyPadding: 10,
47     
48         items: [{
49             xtype: 'fieldcontainer',
50             fieldLabel: 'Last Three Jobs',
51             labelWidth: 100,
52     
53             // The body area will contain three text fields, arranged
54             // horizontally, separated by draggable splitters.
55             layout: 'hbox',
56             items: [{
57                 xtype: 'textfield',
58                 flex: 1
59             }, {
60                 xtype: 'splitter'
61             }, {
62                 xtype: 'textfield',
63                 flex: 1
64             }, {
65                 xtype: 'splitter'
66             }, {
67                 xtype: 'textfield',
68                 flex: 1
69             }]
70         }],
71         renderTo: Ext.getBody()
72     });
73
74 __Usage of {@link #fieldDefaults}:__
75 {@img Ext.form.FieldContainer/Ext.form.FieldContainer2.png Ext.form.FieldContainer component}
76
77     Ext.create('Ext.form.Panel', {
78         title: 'FieldContainer Example',
79         width: 350,
80         bodyPadding: 10,
81     
82         items: [{
83             xtype: 'fieldcontainer',
84             fieldLabel: 'Your Name',
85             labelWidth: 75,
86             defaultType: 'textfield',
87     
88             // Arrange fields vertically, stretched to full width
89             layout: 'anchor',
90             defaults: {
91                 layout: '100%'
92             },
93     
94             // These config values will be applied to both sub-fields, except
95             // for Last Name which will use its own msgTarget.
96             fieldDefaults: {
97                 msgTarget: 'under',
98                 labelAlign: 'top'
99             },
100     
101             items: [{
102                 fieldLabel: 'First Name',
103                 name: 'firstName'
104             }, {
105                 fieldLabel: 'Last Name',
106                 name: 'lastName',
107                 msgTarget: 'under'
108             }]
109         }],
110         renderTo: Ext.getBody()
111     });
112
113
114  * @constructor
115  * Creates a new Ext.form.FieldContainer instance.
116  * @param {Object} config The component configuration.
117  *
118  * @xtype fieldcontainer
119  * @markdown
120  * @docauthor Jason Johnston &lt;jason@sencha.com&gt;
121  */
122 Ext.define('Ext.form.FieldContainer', {
123     extend: 'Ext.container.Container',
124     mixins: {
125         labelable: 'Ext.form.Labelable',
126         fieldAncestor: 'Ext.form.FieldAncestor'
127     },
128     alias: 'widget.fieldcontainer',
129
130     componentLayout: 'field',
131
132 <span id='Ext-form-FieldContainer-cfg-combineLabels'>    /**
133 </span>     * @cfg {Boolean} combineLabels
134      * If set to true, and there is no defined {@link #fieldLabel}, the field container will automatically
135      * generate its label by combining the labels of all the fields it contains. Defaults to false.
136      */
137     combineLabels: false,
138
139 <span id='Ext-form-FieldContainer-cfg-labelConnector'>    /**
140 </span>     * @cfg {String} labelConnector
141      * The string to use when joining the labels of individual sub-fields, when {@link #combineLabels} is
142      * set to true. Defaults to ', '.
143      */
144     labelConnector: ', ',
145
146 <span id='Ext-form-FieldContainer-cfg-combineErrors'>    /**
147 </span>     * @cfg {Boolean} combineErrors
148      * If set to true, the field container will automatically combine and display the validation errors from
149      * all the fields it contains as a single error on the container, according to the configured
150      * {@link #msgTarget}. Defaults to false.
151      */
152     combineErrors: false,
153     
154     maskOnDisable: false,
155
156     initComponent: function() {
157         var me = this,
158             onSubCmpAddOrRemove = me.onSubCmpAddOrRemove;
159
160         // Init mixins
161         me.initLabelable();
162         me.initFieldAncestor();
163
164         me.callParent();
165     },
166
167 <span id='Ext-form-FieldContainer-method-onLabelableAdded'>    /**
168 </span>     * @protected Called when a {@link Ext.form.Labelable} instance is added to the container's subtree.
169      * @param {Ext.form.Labelable} labelable The instance that was added
170      */
171     onLabelableAdded: function(labelable) {
172         var me = this;
173         me.mixins.fieldAncestor.onLabelableAdded.call(this, labelable);
174         me.updateLabel();
175     },
176
177 <span id='Ext-form-FieldContainer-method-onLabelableRemoved'>    /**
178 </span>     * @protected Called when a {@link Ext.form.Labelable} instance is removed from the container's subtree.
179      * @param {Ext.form.Labelable} labelable The instance that was removed
180      */
181     onLabelableRemoved: function(labelable) {
182         var me = this;
183         me.mixins.fieldAncestor.onLabelableRemoved.call(this, labelable);
184         me.updateLabel();
185     },
186
187     onRender: function() {
188         var me = this,
189             renderSelectors = me.renderSelectors,
190             applyIf = Ext.applyIf;
191
192         applyIf(renderSelectors, me.getLabelableSelectors());
193
194         me.callParent(arguments);
195     },
196
197     initRenderTpl: function() {
198         var me = this;
199         if (!me.hasOwnProperty('renderTpl')) {
200             me.renderTpl = me.getTpl('labelableRenderTpl');
201         }
202         return me.callParent();
203     },
204
205     initRenderData: function() {
206         return Ext.applyIf(this.callParent(), this.getLabelableRenderData());
207     },
208
209 <span id='Ext-form-FieldContainer-method-getFieldLabel'>    /**
210 </span>     * Returns the combined field label if {@link #combineLabels} is set to true and if there is no
211      * set {@link #fieldLabel}. Otherwise returns the fieldLabel like normal. You can also override
212      * this method to provide a custom generated label.
213      */
214     getFieldLabel: function() {
215         var label = this.fieldLabel || '';
216         if (!label &amp;&amp; this.combineLabels) {
217             label = Ext.Array.map(this.query('[isFieldLabelable]'), function(field) {
218                 return field.getFieldLabel();
219             }).join(this.labelConnector);
220         }
221         return label;
222     },
223
224 <span id='Ext-form-FieldContainer-method-updateLabel'>    /**
225 </span>     * @private Updates the content of the labelEl if it is rendered
226      */
227     updateLabel: function() {
228         var me = this,
229             label = me.labelEl;
230         if (label) {
231             label.update(me.getFieldLabel());
232         }
233     },
234
235
236 <span id='Ext-form-FieldContainer-method-onFieldErrorChange'>    /**
237 </span>     * @private Fired when the error message of any field within the container changes, and updates the
238      * combined error message to match.
239      */
240     onFieldErrorChange: function(field, activeError) {
241         if (this.combineErrors) {
242             var me = this,
243                 oldError = me.getActiveError(),
244                 invalidFields = Ext.Array.filter(me.query('[isFormField]'), function(field) {
245                     return field.hasActiveError();
246                 }),
247                 newErrors = me.getCombinedErrors(invalidFields);
248
249             if (newErrors) {
250                 me.setActiveErrors(newErrors);
251             } else {
252                 me.unsetActiveError();
253             }
254
255             if (oldError !== me.getActiveError()) {
256                 me.doComponentLayout();
257             }
258         }
259     },
260
261 <span id='Ext-form-FieldContainer-method-getCombinedErrors'>    /**
262 </span>     * Takes an Array of invalid {@link Ext.form.field.Field} objects and builds a combined list of error
263      * messages from them. Defaults to prepending each message by the field name and a colon. This
264      * can be overridden to provide custom combined error message handling, for instance changing
265      * the format of each message or sorting the array (it is sorted in order of appearance by default).
266      * @param {Array} invalidFields An Array of the sub-fields which are currently invalid.
267      * @return {Array} The combined list of error messages
268      */
269     getCombinedErrors: function(invalidFields) {
270         var forEach = Ext.Array.forEach,
271             errors = [];
272         forEach(invalidFields, function(field) {
273             forEach(field.getActiveErrors(), function(error) {
274                 var label = field.getFieldLabel();
275                 errors.push((label ? label + ': ' : '') + error);
276             });
277         });
278         return errors;
279     },
280
281     getTargetEl: function() {
282         return this.bodyEl || this.callParent();
283     }
284 });
285 </pre>
286 </body>
287 </html>