Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / Labelable.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-Labelable'>/**
19 </span> * A mixin which allows a component to be configured and decorated with a label and/or error message as is
20  * common for form fields. This is used by e.g. Ext.form.field.Base and Ext.form.FieldContainer
21  * to let them be managed by the Field layout.
22  *
23  * NOTE: This mixin is mainly for internal library use and most users should not need to use it directly. It
24  * is more likely you will want to use one of the component classes that import this mixin, such as
25  * Ext.form.field.Base or Ext.form.FieldContainer.
26  *
27  * Use of this mixin does not make a component a field in the logical sense, meaning it does not provide any
28  * logic or state related to values or validation; that is handled by the related Ext.form.field.Field
29  * mixin. These two mixins may be used separately (for example Ext.form.FieldContainer is Labelable but not a
30  * Field), or in combination (for example Ext.form.field.Base implements both and has logic for connecting the
31  * two.)
32  *
33  * Component classes which use this mixin should use the Field layout
34  * or a derivation thereof to properly size and position the label and message according to the component config.
35  * They must also call the {@link #initLabelable} method during component initialization to ensure the mixin gets
36  * set up correctly.
37  *
38  * @docauthor Jason Johnston &lt;jason@sencha.com&gt;
39  */
40 Ext.define(&quot;Ext.form.Labelable&quot;, {
41     requires: ['Ext.XTemplate'],
42
43 <span id='Ext-form-Labelable-cfg-labelableRenderTpl'>    /**
44 </span>     * @cfg {String/String[]/Ext.XTemplate} labelableRenderTpl
45      * The rendering template for the field decorations. Component classes using this mixin should include
46      * logic to use this as their {@link Ext.AbstractComponent#renderTpl renderTpl}, and implement the
47      * {@link #getSubTplMarkup} method to generate the field body content.
48      */
49     labelableRenderTpl: [
50         '&lt;tpl if=&quot;!hideLabel &amp;&amp; !(!fieldLabel &amp;&amp; hideEmptyLabel)&quot;&gt;',
51             '&lt;label id=&quot;{id}-labelEl&quot;&lt;tpl if=&quot;inputId&quot;&gt; for=&quot;{inputId}&quot;&lt;/tpl&gt; class=&quot;{labelCls}&quot;',
52                 '&lt;tpl if=&quot;labelStyle&quot;&gt; style=&quot;{labelStyle}&quot;&lt;/tpl&gt;&gt;',
53                 '&lt;tpl if=&quot;fieldLabel&quot;&gt;{fieldLabel}{labelSeparator}&lt;/tpl&gt;',
54             '&lt;/label&gt;',
55         '&lt;/tpl&gt;',
56         '&lt;div class=&quot;{baseBodyCls} {fieldBodyCls}&quot; id=&quot;{id}-bodyEl&quot; role=&quot;presentation&quot;&gt;{subTplMarkup}&lt;/div&gt;',
57         '&lt;div id=&quot;{id}-errorEl&quot; class=&quot;{errorMsgCls}&quot; style=&quot;display:none&quot;&gt;&lt;/div&gt;',
58         '&lt;div class=&quot;{clearCls}&quot; role=&quot;presentation&quot;&gt;&lt;!-- --&gt;&lt;/div&gt;',
59         {
60             compiled: true,
61             disableFormats: true
62         }
63     ],
64
65 <span id='Ext-form-Labelable-cfg-activeErrorsTpl'>    /**
66 </span>     * @cfg {Ext.XTemplate} activeErrorsTpl
67      * The template used to format the Array of error messages passed to {@link #setActiveErrors}
68      * into a single HTML string. By default this renders each message as an item in an unordered list.
69      */
70     activeErrorsTpl: [
71         '&lt;tpl if=&quot;errors &amp;&amp; errors.length&quot;&gt;',
72             '&lt;ul&gt;&lt;tpl for=&quot;errors&quot;&gt;&lt;li&lt;tpl if=&quot;xindex == xcount&quot;&gt; class=&quot;last&quot;&lt;/tpl&gt;&gt;{.}&lt;/li&gt;&lt;/tpl&gt;&lt;/ul&gt;',
73         '&lt;/tpl&gt;'
74     ],
75
76 <span id='Ext-form-Labelable-property-isFieldLabelable'>    /**
77 </span>     * @property isFieldLabelable
78      * @type Boolean
79      * Flag denoting that this object is labelable as a field. Always true.
80      */
81     isFieldLabelable: true,
82
83 <span id='Ext-form-Labelable-cfg-formItemCls'>    /**
84 </span>     * @cfg {String} [formItemCls='x-form-item']
85      * A CSS class to be applied to the outermost element to denote that it is participating in the form
86      * field layout.
87      */
88     formItemCls: Ext.baseCSSPrefix + 'form-item',
89
90 <span id='Ext-form-Labelable-cfg-labelCls'>    /**
91 </span>     * @cfg {String} [labelCls='x-form-item-label']
92      * The CSS class to be applied to the label element.
93      * This (single) CSS class is used to formulate the renderSelector and drives the field
94      * layout where it is concatenated with a hyphen ('-') and {@link #labelAlign}. To add
95      * additional classes, use {@link #labelClsExtra}.
96      */
97     labelCls: Ext.baseCSSPrefix + 'form-item-label',
98
99 <span id='Ext-form-Labelable-cfg-labelClsExtra'>    /**
100 </span>     * @cfg {String} labelClsExtra
101      * An optional string of one or more additional CSS classes to add to the label element.
102      * Defaults to empty.
103      */
104
105 <span id='Ext-form-Labelable-cfg-errorMsgCls'>    /**
106 </span>     * @cfg {String} [errorMsgCls='x-form-error-msg']
107      * The CSS class to be applied to the error message element.
108      */
109     errorMsgCls: Ext.baseCSSPrefix + 'form-error-msg',
110
111 <span id='Ext-form-Labelable-cfg-baseBodyCls'>    /**
112 </span>     * @cfg {String} [baseBodyCls='x-form-item-body']
113      * The CSS class to be applied to the body content element.
114      */
115     baseBodyCls: Ext.baseCSSPrefix + 'form-item-body',
116
117 <span id='Ext-form-Labelable-cfg-fieldBodyCls'>    /**
118 </span>     * @cfg {String} fieldBodyCls
119      * An extra CSS class to be applied to the body content element in addition to {@link #fieldBodyCls}.
120      */
121     fieldBodyCls: '',
122
123 <span id='Ext-form-Labelable-cfg-clearCls'>    /**
124 </span>     * @cfg {String} [clearCls='x-clear']
125      * The CSS class to be applied to the special clearing div rendered directly after the field
126      * contents wrapper to provide field clearing.
127      */
128     clearCls: Ext.baseCSSPrefix + 'clear',
129
130 <span id='Ext-form-Labelable-cfg-invalidCls'>    /**
131 </span>     * @cfg {String} [invalidCls='x-form-invalid']
132      * The CSS class to use when marking the component invalid.
133      */
134     invalidCls : Ext.baseCSSPrefix + 'form-invalid',
135
136 <span id='Ext-form-Labelable-cfg-fieldLabel'>    /**
137 </span>     * @cfg {String} fieldLabel
138      * The label for the field. It gets appended with the {@link #labelSeparator}, and its position
139      * and sizing is determined by the {@link #labelAlign}, {@link #labelWidth}, and {@link #labelPad}
140      * configs.
141      */
142     fieldLabel: undefined,
143
144 <span id='Ext-form-Labelable-cfg-labelAlign'>    /**
145 </span>     * @cfg {String} labelAlign
146      * &lt;p&gt;Controls the position and alignment of the {@link #fieldLabel}. Valid values are:&lt;/p&gt;
147      * &lt;ul&gt;
148      * &lt;li&gt;&lt;tt&gt;&quot;left&quot;&lt;/tt&gt; (the default) - The label is positioned to the left of the field, with its text
149      * aligned to the left. Its width is determined by the {@link #labelWidth} config.&lt;/li&gt;
150      * &lt;li&gt;&lt;tt&gt;&quot;top&quot;&lt;/tt&gt; - The label is positioned above the field.&lt;/li&gt;
151      * &lt;li&gt;&lt;tt&gt;&quot;right&quot;&lt;/tt&gt; - The label is positioned to the left of the field, with its text aligned
152      * to the right. Its width is determined by the {@link #labelWidth} config.&lt;/li&gt;
153      * &lt;/ul&gt;
154      */
155     labelAlign : 'left',
156
157 <span id='Ext-form-Labelable-cfg-labelWidth'>    /**
158 </span>     * @cfg {Number} labelWidth
159      * The width of the {@link #fieldLabel} in pixels. Only applicable if the {@link #labelAlign} is set
160      * to &quot;left&quot; or &quot;right&quot;.
161      */
162     labelWidth: 100,
163
164 <span id='Ext-form-Labelable-cfg-labelPad'>    /**
165 </span>     * @cfg {Number} labelPad
166      * The amount of space in pixels between the {@link #fieldLabel} and the input field.
167      */
168     labelPad : 5,
169
170 <span id='Ext-form-Labelable-cfg-labelSeparator'>    /**
171 </span>     * @cfg {String} labelSeparator
172      * Character(s) to be inserted at the end of the {@link #fieldLabel label text}.
173      */
174     labelSeparator : ':',
175
176 <span id='Ext-form-Labelable-cfg-labelStyle'>    /**
177 </span>     * @cfg {String} labelStyle
178      * A CSS style specification string to apply directly to this field's label.
179      */
180
181 <span id='Ext-form-Labelable-cfg-hideLabel'>    /**
182 </span>     * @cfg {Boolean} hideLabel
183      * Set to true to completely hide the label element ({@link #fieldLabel} and {@link #labelSeparator}).
184      * Also see {@link #hideEmptyLabel}, which controls whether space will be reserved for an empty fieldLabel.
185      */
186     hideLabel: false,
187
188 <span id='Ext-form-Labelable-cfg-hideEmptyLabel'>    /**
189 </span>     * @cfg {Boolean} hideEmptyLabel
190      * &lt;p&gt;When set to &lt;tt&gt;true&lt;/tt&gt;, the label element ({@link #fieldLabel} and {@link #labelSeparator}) will be
191      * automatically hidden if the {@link #fieldLabel} is empty. Setting this to &lt;tt&gt;false&lt;/tt&gt; will cause the empty
192      * label element to be rendered and space to be reserved for it; this is useful if you want a field without a label
193      * to line up with other labeled fields in the same form.&lt;/p&gt;
194      * &lt;p&gt;If you wish to unconditionall hide the label even if a non-empty fieldLabel is configured, then set
195      * the {@link #hideLabel} config to &lt;tt&gt;true&lt;/tt&gt;.&lt;/p&gt;
196      */
197     hideEmptyLabel: true,
198
199 <span id='Ext-form-Labelable-cfg-preventMark'>    /**
200 </span>     * @cfg {Boolean} preventMark
201      * &lt;tt&gt;true&lt;/tt&gt; to disable displaying any {@link #setActiveError error message} set on this object.
202      */
203     preventMark: false,
204
205 <span id='Ext-form-Labelable-cfg-autoFitErrors'>    /**
206 </span>     * @cfg {Boolean} autoFitErrors
207      * Whether to adjust the component's body area to make room for 'side' or 'under'
208      * {@link #msgTarget error messages}.
209      */
210     autoFitErrors: true,
211
212 <span id='Ext-form-Labelable-cfg-msgTarget'>    /**
213 </span>     * @cfg {String} msgTarget &lt;p&gt;The location where the error message text should display.
214      * Must be one of the following values:&lt;/p&gt;
215      * &lt;div class=&quot;mdetail-params&quot;&gt;&lt;ul&gt;
216      * &lt;li&gt;&lt;code&gt;qtip&lt;/code&gt; Display a quick tip containing the message when the user hovers over the field. This is the default.
217      * &lt;div class=&quot;subdesc&quot;&gt;&lt;b&gt;{@link Ext.tip.QuickTipManager#init Ext.tip.QuickTipManager.init} must have been called for this setting to work.&lt;/b&gt;&lt;/div&gt;&lt;/li&gt;
218      * &lt;li&gt;&lt;code&gt;title&lt;/code&gt; Display the message in a default browser title attribute popup.&lt;/li&gt;
219      * &lt;li&gt;&lt;code&gt;under&lt;/code&gt; Add a block div beneath the field containing the error message.&lt;/li&gt;
220      * &lt;li&gt;&lt;code&gt;side&lt;/code&gt; Add an error icon to the right of the field, displaying the message in a popup on hover.&lt;/li&gt;
221      * &lt;li&gt;&lt;code&gt;none&lt;/code&gt; Don't display any error message. This might be useful if you are implementing custom error display.&lt;/li&gt;
222      * &lt;li&gt;&lt;code&gt;[element id]&lt;/code&gt; Add the error message directly to the innerHTML of the specified element.&lt;/li&gt;
223      * &lt;/ul&gt;&lt;/div&gt;
224      */
225     msgTarget: 'qtip',
226
227 <span id='Ext-form-Labelable-cfg-activeError'>    /**
228 </span>     * @cfg {String} activeError
229      * If specified, then the component will be displayed with this value as its active error when
230      * first rendered. Use {@link #setActiveError} or {@link #unsetActiveError} to
231      * change it after component creation.
232      */
233
234
235 <span id='Ext-form-Labelable-method-initLabelable'>    /**
236 </span>     * Performs initialization of this mixin. Component classes using this mixin should call this method
237      * during their own initialization.
238      */
239     initLabelable: function() {
240         this.addCls(this.formItemCls);
241
242         this.addEvents(
243 <span id='Ext-form-Labelable-event-errorchange'>            /**
244 </span>             * @event errorchange
245              * Fires when the active error message is changed via {@link #setActiveError}.
246              * @param {Ext.form.Labelable} this
247              * @param {String} error The active error message
248              */
249             'errorchange'
250         );
251     },
252
253 <span id='Ext-form-Labelable-method-getFieldLabel'>    /**
254 </span>     * Returns the label for the field. Defaults to simply returning the {@link #fieldLabel} config. Can be
255      * overridden to provide
256      * @return {String} The configured field label, or empty string if not defined
257      */
258     getFieldLabel: function() {
259         return this.fieldLabel || '';
260     },
261
262 <span id='Ext-form-Labelable-method-getLabelableRenderData'>    /**
263 </span>     * @protected
264      * Generates the arguments for the field decorations {@link #labelableRenderTpl rendering template}.
265      * @return {Object} The template arguments
266      */
267     getLabelableRenderData: function() {
268         var me = this,
269             labelAlign = me.labelAlign,
270             labelCls = me.labelCls,
271             labelClsExtra = me.labelClsExtra,
272             labelPad = me.labelPad,
273             labelStyle;
274
275         // Calculate label styles up front rather than in the Field layout for speed; this
276         // is safe because label alignment/width/pad are not expected to change.
277         if (labelAlign === 'top') {
278             labelStyle = 'margin-bottom:' + labelPad + 'px;';
279         } else {
280             labelStyle = 'margin-right:' + labelPad + 'px;';
281             // Add the width for border-box browsers; will be set by the Field layout for content-box
282             if (Ext.isBorderBox) {
283                 labelStyle += 'width:' + me.labelWidth + 'px;';
284             }
285         }
286
287         return Ext.copyTo(
288             {
289                 inputId: me.getInputId(),
290                 fieldLabel: me.getFieldLabel(),
291                 labelCls: labelClsExtra ? labelCls + ' ' + labelClsExtra : labelCls,
292                 labelStyle: labelStyle + (me.labelStyle || ''),
293                 subTplMarkup: me.getSubTplMarkup()
294             },
295             me,
296             'hideLabel,hideEmptyLabel,fieldBodyCls,baseBodyCls,errorMsgCls,clearCls,labelSeparator',
297             true
298         );
299     },
300
301     onLabelableRender: function () {
302         this.addChildEls(
303 <span id='Ext-form-Labelable-property-labelEl'>            /**
304 </span>             * @property labelEl
305              * @type Ext.Element
306              * The label Element for this component. Only available after the component has been rendered.
307              */
308             'labelEl',
309
310 <span id='Ext-form-Labelable-property-bodyEl'>            /**
311 </span>             * @property bodyEl
312              * @type Ext.Element
313              * The div Element wrapping the component's contents. Only available after the component has been rendered.
314              */
315             'bodyEl',
316
317 <span id='Ext-form-Labelable-property-errorEl'>            /**
318 </span>             * @property errorEl
319              * @type Ext.Element
320              * The div Element that will contain the component's error message(s). Note that depending on the
321              * configured {@link #msgTarget}, this element may be hidden in favor of some other form of
322              * presentation, but will always be present in the DOM for use by assistive technologies.
323              */
324             'errorEl'
325         );
326     },
327
328 <span id='Ext-form-Labelable-method-getSubTplMarkup'>    /**
329 </span>     * @protected
330      * Gets the markup to be inserted into the outer template's bodyEl. Defaults to empty string, should
331      * be implemented by classes including this mixin as needed.
332      * @return {String} The markup to be inserted
333      */
334     getSubTplMarkup: function() {
335         return '';
336     },
337
338 <span id='Ext-form-Labelable-method-getInputId'>    /**
339 </span>     * Get the input id, if any, for this component. This is used as the &quot;for&quot; attribute on the label element.
340      * Implementing subclasses may also use this as e.g. the id for their own &lt;tt&gt;input&lt;/tt&gt; element.
341      * @return {String} The input id
342      */
343     getInputId: function() {
344         return '';
345     },
346
347 <span id='Ext-form-Labelable-method-getActiveError'>    /**
348 </span>     * Gets the active error message for this component, if any. This does not trigger
349      * validation on its own, it merely returns any message that the component may already hold.
350      * @return {String} The active error message on the component; if there is no error, an empty string is returned.
351      */
352     getActiveError : function() {
353         return this.activeError || '';
354     },
355
356 <span id='Ext-form-Labelable-method-hasActiveError'>    /**
357 </span>     * Tells whether the field currently has an active error message. This does not trigger
358      * validation on its own, it merely looks for any message that the component may already hold.
359      * @return {Boolean}
360      */
361     hasActiveError: function() {
362         return !!this.getActiveError();
363     },
364
365 <span id='Ext-form-Labelable-method-setActiveError'>    /**
366 </span>     * Sets the active error message to the given string. This replaces the entire error message
367      * contents with the given string. Also see {@link #setActiveErrors} which accepts an Array of
368      * messages and formats them according to the {@link #activeErrorsTpl}.
369      *
370      * Note that this only updates the error message element's text and attributes, you'll have
371      * to call doComponentLayout to actually update the field's layout to match. If the field extends
372      * {@link Ext.form.field.Base} you should call {@link Ext.form.field.Base#markInvalid markInvalid} instead.
373      *
374      * @param {String} msg The error message
375      */
376     setActiveError: function(msg) {
377         this.activeError = msg;
378         this.activeErrors = [msg];
379         this.renderActiveError();
380     },
381
382 <span id='Ext-form-Labelable-method-getActiveErrors'>    /**
383 </span>     * Gets an Array of any active error messages currently applied to the field. This does not trigger
384      * validation on its own, it merely returns any messages that the component may already hold.
385      * @return {String[]} The active error messages on the component; if there are no errors, an empty Array is returned.
386      */
387     getActiveErrors: function() {
388         return this.activeErrors || [];
389     },
390
391 <span id='Ext-form-Labelable-method-setActiveErrors'>    /**
392 </span>     * Set the active error message to an Array of error messages. The messages are formatted into
393      * a single message string using the {@link #activeErrorsTpl}. Also see {@link #setActiveError}
394      * which allows setting the entire error contents with a single string.
395      *
396      * Note that this only updates the error message element's text and attributes, you'll have
397      * to call doComponentLayout to actually update the field's layout to match. If the field extends
398      * {@link Ext.form.field.Base} you should call {@link Ext.form.field.Base#markInvalid markInvalid} instead.
399      *
400      * @param {String[]} errors The error messages
401      */
402     setActiveErrors: function(errors) {
403         this.activeErrors = errors;
404         this.activeError = this.getTpl('activeErrorsTpl').apply({errors: errors});
405         this.renderActiveError();
406     },
407
408 <span id='Ext-form-Labelable-method-unsetActiveError'>    /**
409 </span>     * Clears the active error message(s).
410      *
411      * Note that this only clears the error message element's text and attributes, you'll have
412      * to call doComponentLayout to actually update the field's layout to match. If the field extends
413      * {@link Ext.form.field.Base} you should call {@link Ext.form.field.Base#clearInvalid clearInvalid} instead.
414      */
415     unsetActiveError: function() {
416         delete this.activeError;
417         delete this.activeErrors;
418         this.renderActiveError();
419     },
420
421 <span id='Ext-form-Labelable-method-renderActiveError'>    /**
422 </span>     * @private
423      * Updates the rendered DOM to match the current activeError. This only updates the content and
424      * attributes, you'll have to call doComponentLayout to actually update the display.
425      */
426     renderActiveError: function() {
427         var me = this,
428             activeError = me.getActiveError(),
429             hasError = !!activeError;
430
431         if (activeError !== me.lastActiveError) {
432             me.fireEvent('errorchange', me, activeError);
433             me.lastActiveError = activeError;
434         }
435
436         if (me.rendered &amp;&amp; !me.isDestroyed &amp;&amp; !me.preventMark) {
437             // Add/remove invalid class
438             me.el[hasError ? 'addCls' : 'removeCls'](me.invalidCls);
439
440             // Update the aria-invalid attribute
441             me.getActionEl().dom.setAttribute('aria-invalid', hasError);
442
443             // Update the errorEl with the error message text
444             me.errorEl.dom.innerHTML = activeError;
445         }
446     },
447
448 <span id='Ext-form-Labelable-method-setFieldDefaults'>    /**
449 </span>     * Applies a set of default configuration values to this Labelable instance. For each of the
450      * properties in the given object, check if this component hasOwnProperty that config; if not
451      * then it's inheriting a default value from its prototype and we should apply the default value.
452      * @param {Object} defaults The defaults to apply to the object.
453      */
454     setFieldDefaults: function(defaults) {
455         var me = this;
456         Ext.iterate(defaults, function(key, val) {
457             if (!me.hasOwnProperty(key)) {
458                 me[key] = val;
459             }
460         });
461     },
462
463 <span id='Ext-form-Labelable-method-getBodyNaturalWidth'>    /**
464 </span>     * @protected Calculate and return the natural width of the bodyEl. Override to provide custom logic.
465      * Note for implementors: if at all possible this method should be overridden with a custom implementation
466      * that can avoid anything that would cause the browser to reflow, e.g. querying offsetWidth.
467      */
468     getBodyNaturalWidth: function() {
469         return this.bodyEl.getWidth();
470     }
471
472 });
473 </pre>
474 </body>
475 </html>