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