Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / docs / source / FieldAncestor.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.FieldAncestor'>/**
2 </span> * @class Ext.form.FieldAncestor
3
4 A mixin for {@link Ext.container.Container} components that are likely to have form fields in their
5 items subtree. Adds the following capabilities:
6
7 - Methods for handling the addition and removal of {@link Ext.form.Labelable} and {@link Ext.form.field.Field}
8   instances at any depth within the container.
9 - Events ({@link #fieldvaliditychange} and {@link #fielderrorchange}) for handling changes to the state
10   of individual fields at the container level.
11 - Automatic application of {@link #fieldDefaults} config properties to each field added within the
12   container, to facilitate uniform configuration of all fields.
13
14 This mixin is primarily for internal use by {@link Ext.form.Panel} and {@link Ext.form.FieldContainer},
15 and should not normally need to be used directly.
16
17  * @markdown
18  * @docauthor Jason Johnston &lt;jason@sencha.com&gt;
19  */
20 Ext.define('Ext.form.FieldAncestor', {
21
22 <span id='Ext-form.FieldAncestor-cfg-fieldDefaults'>    /**
23 </span>     * @cfg {Object} fieldDefaults
24      * &lt;p&gt;If specified, the properties in this object are used as default config values for each
25      * {@link Ext.form.Labelable} instance (e.g. {@link Ext.form.field.Base} or {@link Ext.form.FieldContainer})
26      * that is added as a descendant of this container. Corresponding values specified in an individual field's
27      * own configuration, or from the {@link Ext.container.Container#defaults defaults config} of its parent container,
28      * will take precedence. See the documentation for {@link Ext.form.Labelable} to see what config
29      * options may be specified in the &lt;tt&gt;fieldDefaults&lt;/tt&gt;.&lt;/p&gt;
30      * &lt;p&gt;Example:&lt;/p&gt;
31      * &lt;pre&gt;&lt;code&gt;new Ext.form.Panel({
32     fieldDefaults: {
33         labelAlign: 'left',
34         labelWidth: 100
35     },
36     items: [{
37         xtype: 'fieldset',
38         defaults: {
39             labelAlign: 'top'
40         },
41         items: [{
42             name: 'field1'
43         }, {
44             name: 'field2'
45         }]
46     }, {
47         xtype: 'fieldset',
48         items: [{
49             name: 'field3',
50             labelWidth: 150
51         }, {
52             name: 'field4'
53         }]
54     }]
55 });&lt;/code&gt;&lt;/pre&gt;
56      * &lt;p&gt;In this example, field1 and field2 will get labelAlign:'top' (from the fieldset's &lt;tt&gt;defaults&lt;/tt&gt;)
57      * and labelWidth:100 (from &lt;tt&gt;fieldDefaults&lt;/tt&gt;), field3 and field4 will both get labelAlign:'left' (from
58      * &lt;tt&gt;fieldDefaults&lt;/tt&gt; and field3 will use the labelWidth:150 from its own config.&lt;/p&gt;
59      */
60
61
62 <span id='Ext-form.FieldAncestor-method-initFieldAncestor'>    /**
63 </span>     * @protected Initializes the FieldAncestor's state; this must be called from the initComponent method
64      * of any components importing this mixin.
65      */
66     initFieldAncestor: function() {
67         var me = this,
68             onSubtreeChange = me.onFieldAncestorSubtreeChange;
69
70         me.addEvents(
71 <span id='Ext-form.FieldAncestor-event-fielderrorchange'>            /**
72 </span>             * @event fielderrorchange
73              * Fires when the validity state of any one of the {@link Ext.form.field.Field} instances within this
74              * container changes.
75              * @param {Ext.form.FieldAncestor} this
76              * @param {Ext.form.Labelable} The Field instance whose validity changed
77              * @param {String} isValid The field's new validity state
78              */
79             'fieldvaliditychange',
80
81 <span id='Ext-form.FieldAncestor-event-fielderrorchange'>            /**
82 </span>             * @event fielderrorchange
83              * Fires when the active error message is changed for any one of the {@link Ext.form.Labelable}
84              * instances within this container.
85              * @param {Ext.form.FieldAncestor} this
86              * @param {Ext.form.Labelable} The Labelable instance whose active error was changed
87              * @param {String} error The active error message
88              */
89             'fielderrorchange'
90         );
91
92         // Catch addition and removal of descendant fields
93         me.on('add', onSubtreeChange, me);
94         me.on('remove', onSubtreeChange, me);
95
96         me.initFieldDefaults();
97     },
98
99 <span id='Ext-form.FieldAncestor-method-initFieldDefaults'>    /**
100 </span>     * @private Initialize the {@link #fieldDefaults} object
101      */
102     initFieldDefaults: function() {
103         if (!this.fieldDefaults) {
104             this.fieldDefaults = {};
105         }
106     },
107
108 <span id='Ext-form.FieldAncestor-method-onFieldAncestorSubtreeChange'>    /**
109 </span>     * @private
110      * Handle the addition and removal of components in the FieldAncestor component's child tree.
111      */
112     onFieldAncestorSubtreeChange: function(parent, child) {
113         var me = this,
114             isAdding = !!child.ownerCt;
115
116         function handleCmp(cmp) {
117             var isLabelable = cmp.isFieldLabelable,
118                 isField = cmp.isFormField;
119             if (isLabelable || isField) {
120                 if (isLabelable) {
121                     me['onLabelable' + (isAdding ? 'Added' : 'Removed')](cmp);
122                 }
123                 if (isField) {
124                     me['onField' + (isAdding ? 'Added' : 'Removed')](cmp);
125                 }
126             }
127             else if (cmp.isContainer) {
128                 Ext.Array.forEach(cmp.getRefItems(), handleCmp);
129             }
130         }
131         handleCmp(child);
132     },
133
134 <span id='Ext-form.FieldAncestor-method-onLabelableAdded'>    /**
135 </span>     * @protected Called when a {@link Ext.form.Labelable} instance is added to the container's subtree.
136      * @param {Ext.form.Labelable} labelable The instance that was added
137      */
138     onLabelableAdded: function(labelable) {
139         var me = this;
140
141         // buffer slightly to avoid excessive firing while sub-fields are changing en masse
142         me.mon(labelable, 'errorchange', me.handleFieldErrorChange, me, {buffer: 10});
143
144         labelable.setFieldDefaults(me.fieldDefaults);
145     },
146
147 <span id='Ext-form.FieldAncestor-method-onFieldAdded'>    /**
148 </span>     * @protected Called when a {@link Ext.form.field.Field} instance is added to the container's subtree.
149      * @param {Ext.form.field.Field} field The field which was added
150      */
151     onFieldAdded: function(field) {
152         var me = this;
153         me.mon(field, 'validitychange', me.handleFieldValidityChange, me);
154     },
155
156 <span id='Ext-form.FieldAncestor-method-onLabelableRemoved'>    /**
157 </span>     * @protected Called when a {@link Ext.form.Labelable} instance is removed from the container's subtree.
158      * @param {Ext.form.Labelable} labelable The instance that was removed
159      */
160     onLabelableRemoved: function(labelable) {
161         var me = this;
162         me.mun(labelable, 'errorchange', me.handleFieldErrorChange, me);
163     },
164
165 <span id='Ext-form.FieldAncestor-method-onFieldRemoved'>    /**
166 </span>     * @protected Called when a {@link Ext.form.field.Field} instance is removed from the container's subtree.
167      * @param {Ext.form.field.Field} field The field which was removed
168      */
169     onFieldRemoved: function(field) {
170         var me = this;
171         me.mun(field, 'validitychange', me.handleFieldValidityChange, me);
172     },
173
174 <span id='Ext-form.FieldAncestor-method-handleFieldValidityChange'>    /**
175 </span>     * @private Handle validitychange events on sub-fields; invoke the aggregated event and method
176      */
177     handleFieldValidityChange: function(field, isValid) {
178         var me = this;
179         me.fireEvent('fieldvaliditychange', me, field, isValid);
180         me.onFieldValidityChange();
181     },
182
183 <span id='Ext-form.FieldAncestor-method-handleFieldErrorChange'>    /**
184 </span>     * @private Handle errorchange events on sub-fields; invoke the aggregated event and method
185      */
186     handleFieldErrorChange: function(labelable, activeError) {
187         var me = this;
188         me.fireEvent('fielderrorchange', me, labelable, activeError);
189         me.onFieldErrorChange();
190     },
191
192 <span id='Ext-form.FieldAncestor-property-onFieldValidityChange'>    /**
193 </span>     * @protected Fired when the validity of any field within the container changes.
194      * @param {Ext.form.field.Field} The sub-field whose validity changed
195      * @param {String} The new validity state
196      */
197     onFieldValidityChange: Ext.emptyFn,
198
199 <span id='Ext-form.FieldAncestor-property-onFieldErrorChange'>    /**
200 </span>     * @protected Fired when the error message of any field within the container changes.
201      * @param {Ext.form.Labelable} The sub-field whose active error changed
202      * @param {String} The new active error message
203      */
204     onFieldErrorChange: Ext.emptyFn
205
206 });</pre></pre></body></html>