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