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; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-form-FieldContainer'>/**
19 </span> * @class Ext.form.FieldContainer
20 * @extends Ext.container.Container
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.
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'`.
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.
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}
43 Ext.create('Ext.form.Panel', {
44 title: 'FieldContainer Example',
49 xtype: 'fieldcontainer',
50 fieldLabel: 'Last Three Jobs',
53 // The body area will contain three text fields, arranged
54 // horizontally, separated by draggable splitters.
71 renderTo: Ext.getBody()
74 __Usage of {@link #fieldDefaults}:__
75 {@img Ext.form.FieldContainer/Ext.form.FieldContainer2.png Ext.form.FieldContainer component}
77 Ext.create('Ext.form.Panel', {
78 title: 'FieldContainer Example',
83 xtype: 'fieldcontainer',
84 fieldLabel: 'Your Name',
86 defaultType: 'textfield',
88 // Arrange fields vertically, stretched to full width
94 // These config values will be applied to both sub-fields, except
95 // for Last Name which will use its own msgTarget.
102 fieldLabel: 'First Name',
105 fieldLabel: 'Last Name',
110 renderTo: Ext.getBody()
115 * @docauthor Jason Johnston <jason@sencha.com>
117 Ext.define('Ext.form.FieldContainer', {
118 extend: 'Ext.container.Container',
120 labelable: 'Ext.form.Labelable',
121 fieldAncestor: 'Ext.form.FieldAncestor'
123 alias: 'widget.fieldcontainer',
125 componentLayout: 'field',
127 <span id='Ext-form-FieldContainer-cfg-combineLabels'> /**
128 </span> * @cfg {Boolean} combineLabels
129 * If set to true, and there is no defined {@link #fieldLabel}, the field container will automatically
130 * generate its label by combining the labels of all the fields it contains. Defaults to false.
132 combineLabels: false,
134 <span id='Ext-form-FieldContainer-cfg-labelConnector'> /**
135 </span> * @cfg {String} labelConnector
136 * The string to use when joining the labels of individual sub-fields, when {@link #combineLabels} is
137 * set to true. Defaults to ', '.
139 labelConnector: ', ',
141 <span id='Ext-form-FieldContainer-cfg-combineErrors'> /**
142 </span> * @cfg {Boolean} combineErrors
143 * If set to true, the field container will automatically combine and display the validation errors from
144 * all the fields it contains as a single error on the container, according to the configured
145 * {@link #msgTarget}. Defaults to false.
147 combineErrors: false,
149 maskOnDisable: false,
151 initComponent: function() {
153 onSubCmpAddOrRemove = me.onSubCmpAddOrRemove;
157 me.initFieldAncestor();
162 <span id='Ext-form-FieldContainer-method-onLabelableAdded'> /**
163 </span> * @protected Called when a {@link Ext.form.Labelable} instance is added to the container's subtree.
164 * @param {Ext.form.Labelable} labelable The instance that was added
166 onLabelableAdded: function(labelable) {
168 me.mixins.fieldAncestor.onLabelableAdded.call(this, labelable);
172 <span id='Ext-form-FieldContainer-method-onLabelableRemoved'> /**
173 </span> * @protected Called when a {@link Ext.form.Labelable} instance is removed from the container's subtree.
174 * @param {Ext.form.Labelable} labelable The instance that was removed
176 onLabelableRemoved: function(labelable) {
178 me.mixins.fieldAncestor.onLabelableRemoved.call(this, labelable);
182 onRender: function() {
184 renderSelectors = me.renderSelectors,
185 applyIf = Ext.applyIf;
187 applyIf(renderSelectors, me.getLabelableSelectors());
189 me.callParent(arguments);
192 initRenderTpl: function() {
194 if (!me.hasOwnProperty('renderTpl')) {
195 me.renderTpl = me.getTpl('labelableRenderTpl');
197 return me.callParent();
200 initRenderData: function() {
201 return Ext.applyIf(this.callParent(), this.getLabelableRenderData());
204 <span id='Ext-form-FieldContainer-method-getFieldLabel'> /**
205 </span> * Returns the combined field label if {@link #combineLabels} is set to true and if there is no
206 * set {@link #fieldLabel}. Otherwise returns the fieldLabel like normal. You can also override
207 * this method to provide a custom generated label.
209 getFieldLabel: function() {
210 var label = this.fieldLabel || '';
211 if (!label && this.combineLabels) {
212 label = Ext.Array.map(this.query('[isFieldLabelable]'), function(field) {
213 return field.getFieldLabel();
214 }).join(this.labelConnector);
219 <span id='Ext-form-FieldContainer-method-updateLabel'> /**
220 </span> * @private Updates the content of the labelEl if it is rendered
222 updateLabel: function() {
226 label.update(me.getFieldLabel());
231 <span id='Ext-form-FieldContainer-method-onFieldErrorChange'> /**
232 </span> * @private Fired when the error message of any field within the container changes, and updates the
233 * combined error message to match.
235 onFieldErrorChange: function(field, activeError) {
236 if (this.combineErrors) {
238 oldError = me.getActiveError(),
239 invalidFields = Ext.Array.filter(me.query('[isFormField]'), function(field) {
240 return field.hasActiveError();
242 newErrors = me.getCombinedErrors(invalidFields);
245 me.setActiveErrors(newErrors);
247 me.unsetActiveError();
250 if (oldError !== me.getActiveError()) {
251 me.doComponentLayout();
256 <span id='Ext-form-FieldContainer-method-getCombinedErrors'> /**
257 </span> * Takes an Array of invalid {@link Ext.form.field.Field} objects and builds a combined list of error
258 * messages from them. Defaults to prepending each message by the field name and a colon. This
259 * can be overridden to provide custom combined error message handling, for instance changing
260 * the format of each message or sorting the array (it is sorted in order of appearance by default).
261 * @param {Array} invalidFields An Array of the sub-fields which are currently invalid.
262 * @return {Array} The combined list of error messages
264 getCombinedErrors: function(invalidFields) {
265 var forEach = Ext.Array.forEach,
267 forEach(invalidFields, function(field) {
268 forEach(field.getActiveErrors(), function(error) {
269 var label = field.getFieldLabel();
270 errors.push((label ? label + ': ' : '') + error);
276 getTargetEl: function() {
277 return this.bodyEl || this.callParent();