X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6a7e4474cba9d8be4b2ec445e10f1691f7277c50..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/docs/source/FieldAncestor.html diff --git a/docs/source/FieldAncestor.html b/docs/source/FieldAncestor.html new file mode 100644 index 00000000..32c84e80 --- /dev/null +++ b/docs/source/FieldAncestor.html @@ -0,0 +1,206 @@ +
\ No newline at end of file/** + * @class Ext.form.FieldAncestor + +A mixin for {@link Ext.container.Container} components that are likely to have form fields in their +items subtree. Adds the following capabilities: + +- Methods for handling the addition and removal of {@link Ext.form.Labelable} and {@link Ext.form.field.Field} + instances at any depth within the container. +- Events ({@link #fieldvaliditychange} and {@link #fielderrorchange}) for handling changes to the state + of individual fields at the container level. +- Automatic application of {@link #fieldDefaults} config properties to each field added within the + container, to facilitate uniform configuration of all fields. + +This mixin is primarily for internal use by {@link Ext.form.Panel} and {@link Ext.form.FieldContainer}, +and should not normally need to be used directly. + + * @markdown + * @docauthor Jason Johnston <jason@sencha.com> + */ +Ext.define('Ext.form.FieldAncestor', { + + /** + * @cfg {Object} fieldDefaults + * <p>If specified, the properties in this object are used as default config values for each + * {@link Ext.form.Labelable} instance (e.g. {@link Ext.form.field.Base} or {@link Ext.form.FieldContainer}) + * that is added as a descendant of this container. Corresponding values specified in an individual field's + * own configuration, or from the {@link Ext.container.Container#defaults defaults config} of its parent container, + * will take precedence. See the documentation for {@link Ext.form.Labelable} to see what config + * options may be specified in the <tt>fieldDefaults</tt>.</p> + * <p>Example:</p> + * <pre><code>new Ext.form.Panel({ + fieldDefaults: { + labelAlign: 'left', + labelWidth: 100 + }, + items: [{ + xtype: 'fieldset', + defaults: { + labelAlign: 'top' + }, + items: [{ + name: 'field1' + }, { + name: 'field2' + }] + }, { + xtype: 'fieldset', + items: [{ + name: 'field3', + labelWidth: 150 + }, { + name: 'field4' + }] + }] +});</code></pre> + * <p>In this example, field1 and field2 will get labelAlign:'top' (from the fieldset's <tt>defaults</tt>) + * and labelWidth:100 (from <tt>fieldDefaults</tt>), field3 and field4 will both get labelAlign:'left' (from + * <tt>fieldDefaults</tt> and field3 will use the labelWidth:150 from its own config.</p> + */ + + + /** + * @protected Initializes the FieldAncestor's state; this must be called from the initComponent method + * of any components importing this mixin. + */ + initFieldAncestor: function() { + var me = this, + onSubtreeChange = me.onFieldAncestorSubtreeChange; + + me.addEvents( + /** + * @event fielderrorchange + * Fires when the validity state of any one of the {@link Ext.form.field.Field} instances within this + * container changes. + * @param {Ext.form.FieldAncestor} this + * @param {Ext.form.Labelable} The Field instance whose validity changed + * @param {String} isValid The field's new validity state + */ + 'fieldvaliditychange', + + /** + * @event fielderrorchange + * Fires when the active error message is changed for any one of the {@link Ext.form.Labelable} + * instances within this container. + * @param {Ext.form.FieldAncestor} this + * @param {Ext.form.Labelable} The Labelable instance whose active error was changed + * @param {String} error The active error message + */ + 'fielderrorchange' + ); + + // Catch addition and removal of descendant fields + me.on('add', onSubtreeChange, me); + me.on('remove', onSubtreeChange, me); + + me.initFieldDefaults(); + }, + + /** + * @private Initialize the {@link #fieldDefaults} object + */ + initFieldDefaults: function() { + if (!this.fieldDefaults) { + this.fieldDefaults = {}; + } + }, + + /** + * @private + * Handle the addition and removal of components in the FieldAncestor component's child tree. + */ + onFieldAncestorSubtreeChange: function(parent, child) { + var me = this, + isAdding = !!child.ownerCt; + + function handleCmp(cmp) { + var isLabelable = cmp.isFieldLabelable, + isField = cmp.isFormField; + if (isLabelable || isField) { + if (isLabelable) { + me['onLabelable' + (isAdding ? 'Added' : 'Removed')](cmp); + } + if (isField) { + me['onField' + (isAdding ? 'Added' : 'Removed')](cmp); + } + } + else if (cmp.isContainer) { + Ext.Array.forEach(cmp.getRefItems(), handleCmp); + } + } + handleCmp(child); + }, + + /** + * @protected Called when a {@link Ext.form.Labelable} instance is added to the container's subtree. + * @param {Ext.form.Labelable} labelable The instance that was added + */ + onLabelableAdded: function(labelable) { + var me = this; + + // buffer slightly to avoid excessive firing while sub-fields are changing en masse + me.mon(labelable, 'errorchange', me.handleFieldErrorChange, me, {buffer: 10}); + + labelable.setFieldDefaults(me.fieldDefaults); + }, + + /** + * @protected Called when a {@link Ext.form.field.Field} instance is added to the container's subtree. + * @param {Ext.form.field.Field} field The field which was added + */ + onFieldAdded: function(field) { + var me = this; + me.mon(field, 'validitychange', me.handleFieldValidityChange, me); + }, + + /** + * @protected Called when a {@link Ext.form.Labelable} instance is removed from the container's subtree. + * @param {Ext.form.Labelable} labelable The instance that was removed + */ + onLabelableRemoved: function(labelable) { + var me = this; + me.mun(labelable, 'errorchange', me.handleFieldErrorChange, me); + }, + + /** + * @protected Called when a {@link Ext.form.field.Field} instance is removed from the container's subtree. + * @param {Ext.form.field.Field} field The field which was removed + */ + onFieldRemoved: function(field) { + var me = this; + me.mun(field, 'validitychange', me.handleFieldValidityChange, me); + }, + + /** + * @private Handle validitychange events on sub-fields; invoke the aggregated event and method + */ + handleFieldValidityChange: function(field, isValid) { + var me = this; + me.fireEvent('fieldvaliditychange', me, field, isValid); + me.onFieldValidityChange(); + }, + + /** + * @private Handle errorchange events on sub-fields; invoke the aggregated event and method + */ + handleFieldErrorChange: function(labelable, activeError) { + var me = this; + me.fireEvent('fielderrorchange', me, labelable, activeError); + me.onFieldErrorChange(); + }, + + /** + * @protected Fired when the validity of any field within the container changes. + * @param {Ext.form.field.Field} The sub-field whose validity changed + * @param {String} The new validity state + */ + onFieldValidityChange: Ext.emptyFn, + + /** + * @protected Fired when the error message of any field within the container changes. + * @param {Ext.form.Labelable} The sub-field whose active error changed + * @param {String} The new active error message + */ + onFieldErrorChange: Ext.emptyFn + +});