source: trunk/web/addons/job_monarch/lib/extjs-30/src/widgets/Component.js @ 625

Last change on this file since 625 was 625, checked in by ramonb, 15 years ago

lib/extjs-30:

  • new ExtJS 3.0
File size: 59.2 KB
Line 
1/*!
2 * Ext JS Library 3.0.0
3 * Copyright(c) 2006-2009 Ext JS, LLC
4 * licensing@extjs.com
5 * http://www.extjs.com/license
6 */
7/**
8 * @class Ext.Component
9 * @extends Ext.util.Observable
10 * <p>Base class for all Ext components.  All subclasses of Component may participate in the automated
11 * Ext component lifecycle of creation, rendering and destruction which is provided by the {@link Ext.Container Container} class.
12 * Components may be added to a Container through the {@link Ext.Container#items items} config option at the time the Container is created,
13 * or they may be added dynamically via the {@link Ext.Container#add add} method.</p>
14 * <p>The Component base class has built-in support for basic hide/show and enable/disable behavior.</p>
15 * <p>All Components are registered with the {@link Ext.ComponentMgr} on construction so that they can be referenced at any time via
16 * {@link Ext#getCmp}, passing the {@link #id}.</p>
17 * <p>All user-developed visual widgets that are required to participate in automated lifecycle and size management should subclass Component (or
18 * {@link Ext.BoxComponent} if managed box model handling is required, ie height and width management).</p>
19 * <p>See the <a href="http://extjs.com/learn/Tutorial:Creating_new_UI_controls">Creating new UI controls</a> tutorial for details on how
20 * and to either extend or augment ExtJs base classes to create custom Components.</p>
21 * <p>Every component has a specific xtype, which is its Ext-specific type name, along with methods for checking the
22 * xtype like {@link #getXType} and {@link #isXType}. This is the list of all valid xtypes:</p>
23 * <pre>
24xtype            Class
25-------------    ------------------
26box              {@link Ext.BoxComponent}
27button           {@link Ext.Button}
28buttongroup      {@link Ext.ButtonGroup}
29colorpalette     {@link Ext.ColorPalette}
30component        {@link Ext.Component}
31container        {@link Ext.Container}
32cycle            {@link Ext.CycleButton}
33dataview         {@link Ext.DataView}
34datepicker       {@link Ext.DatePicker}
35editor           {@link Ext.Editor}
36editorgrid       {@link Ext.grid.EditorGridPanel}
37flash            {@link Ext.FlashComponent}
38grid             {@link Ext.grid.GridPanel}
39listview         {@link Ext.ListView}
40panel            {@link Ext.Panel}
41progress         {@link Ext.ProgressBar}
42propertygrid     {@link Ext.grid.PropertyGrid}
43slider           {@link Ext.Slider}
44spacer           {@link Ext.Spacer}
45splitbutton      {@link Ext.SplitButton}
46tabpanel         {@link Ext.TabPanel}
47treepanel        {@link Ext.tree.TreePanel}
48viewport         {@link Ext.ViewPort}
49window           {@link Ext.Window}
50
51Toolbar components
52---------------------------------------
53paging           {@link Ext.PagingToolbar}
54toolbar          {@link Ext.Toolbar}
55tbbutton         {@link Ext.Toolbar.Button}        (deprecated; use button)
56tbfill           {@link Ext.Toolbar.Fill}
57tbitem           {@link Ext.Toolbar.Item}
58tbseparator      {@link Ext.Toolbar.Separator}
59tbspacer         {@link Ext.Toolbar.Spacer}
60tbsplit          {@link Ext.Toolbar.SplitButton}   (deprecated; use splitbutton)
61tbtext           {@link Ext.Toolbar.TextItem}
62
63Menu components
64---------------------------------------
65menu             {@link Ext.menu.Menu}
66colormenu        {@link Ext.menu.ColorMenu}
67datemenu         {@link Ext.menu.DateMenu}
68menubaseitem     {@link Ext.menu.BaseItem}
69menucheckitem    {@link Ext.menu.CheckItem}
70menuitem         {@link Ext.menu.Item}
71menuseparator    {@link Ext.menu.Separator}
72menutextitem     {@link Ext.menu.TextItem}
73
74Form components
75---------------------------------------
76form             {@link Ext.FormPanel}
77checkbox         {@link Ext.form.Checkbox}
78checkboxgroup    {@link Ext.form.CheckboxGroup}
79combo            {@link Ext.form.ComboBox}
80datefield        {@link Ext.form.DateField}
81displayfield     {@link Ext.form.DisplayField}
82field            {@link Ext.form.Field}
83fieldset         {@link Ext.form.FieldSet}
84hidden           {@link Ext.form.Hidden}
85htmleditor       {@link Ext.form.HtmlEditor}
86label            {@link Ext.form.Label}
87numberfield      {@link Ext.form.NumberField}
88radio            {@link Ext.form.Radio}
89radiogroup       {@link Ext.form.RadioGroup}
90textarea         {@link Ext.form.TextArea}
91textfield        {@link Ext.form.TextField}
92timefield        {@link Ext.form.TimeField}
93trigger          {@link Ext.form.TriggerField}
94
95Chart components
96---------------------------------------
97chart            {@link Ext.chart.Chart}
98barchart         {@link Ext.chart.BarChart}
99cartesianchart   {@link Ext.chart.CartesianChart}
100columnchart      {@link Ext.chart.ColumnChart}
101linechart        {@link Ext.chart.LineChart}
102piechart         {@link Ext.chart.PieChart}
103
104Store xtypes
105---------------------------------------
106arraystore       {@link Ext.data.ArrayStore}
107directstore      {@link Ext.data.DirectStore}
108groupingstore    {@link Ext.data.GroupingStore}
109jsonstore        {@link Ext.data.JsonStore}
110simplestore      {@link Ext.data.SimpleStore}      (deprecated; use arraystore)
111store            {@link Ext.data.Store}
112xmlstore         {@link Ext.data.XmlStore}
113</pre>
114 * @constructor
115 * @param {Ext.Element/String/Object} config The configuration options may be specified as either:
116 * <div class="mdetail-params"><ul>
117 * <li><b>an element</b> :
118 * <p class="sub-desc">it is set as the internal element and its id used as the component id</p></li>
119 * <li><b>a string</b> :
120 * <p class="sub-desc">it is assumed to be the id of an existing element and is used as the component id</p></li>
121 * <li><b>anything else</b> :
122 * <p class="sub-desc">it is assumed to be a standard config object and is applied to the component</p></li>
123 * </ul></div>
124 */
125Ext.Component = function(config){
126    config = config || {};
127    if(config.initialConfig){
128        if(config.isAction){           // actions
129            this.baseAction = config;
130        }
131        config = config.initialConfig; // component cloning / action set up
132    }else if(config.tagName || config.dom || Ext.isString(config)){ // element object
133        config = {applyTo: config, id: config.id || config};
134    }
135
136    /**
137     * This Component's initial configuration specification. Read-only.
138     * @type Object
139     * @property initialConfig
140     */
141    this.initialConfig = config;
142
143    Ext.apply(this, config);
144    this.addEvents(
145        /**
146         * @event disable
147         * Fires after the component is disabled.
148         * @param {Ext.Component} this
149         */
150        'disable',
151        /**
152         * @event enable
153         * Fires after the component is enabled.
154         * @param {Ext.Component} this
155         */
156        'enable',
157        /**
158         * @event beforeshow
159         * Fires before the component is shown by calling the {@link #show} method.
160         * Return false from an event handler to stop the show.
161         * @param {Ext.Component} this
162         */
163        'beforeshow',
164        /**
165         * @event show
166         * Fires after the component is shown when calling the {@link #show} method.
167         * @param {Ext.Component} this
168         */
169        'show',
170        /**
171         * @event beforehide
172         * Fires before the component is hidden by calling the {@link #hide} method.
173         * Return false from an event handler to stop the hide.
174         * @param {Ext.Component} this
175         */
176        'beforehide',
177        /**
178         * @event hide
179         * Fires after the component is hidden.
180         * Fires after the component is hidden when calling the {@link #hide} method.
181         * @param {Ext.Component} this
182         */
183        'hide',
184        /**
185         * @event beforerender
186         * Fires before the component is {@link #rendered}. Return false from an
187         * event handler to stop the {@link #render}.
188         * @param {Ext.Component} this
189         */
190        'beforerender',
191        /**
192         * @event render
193         * Fires after the component markup is {@link #rendered}.
194         * @param {Ext.Component} this
195         */
196        'render',
197        /**
198         * @event afterrender
199         * <p>Fires after the component rendering is finished.</p>
200         * <p>The afterrender event is fired after this Component has been {@link #rendered}, been postprocesed
201         * by any afterRender method defined for the Component, and, if {@link #stateful}, after state
202         * has been restored.</p>
203         * @param {Ext.Component} this
204         */
205        'afterrender',
206        /**
207         * @event beforedestroy
208         * Fires before the component is {@link #destroy}ed. Return false from an event handler to stop the {@link #destroy}.
209         * @param {Ext.Component} this
210         */
211        'beforedestroy',
212        /**
213         * @event destroy
214         * Fires after the component is {@link #destroy}ed.
215         * @param {Ext.Component} this
216         */
217        'destroy',
218        /**
219         * @event beforestaterestore
220         * Fires before the state of the component is restored. Return false from an event handler to stop the restore.
221         * @param {Ext.Component} this
222         * @param {Object} state The hash of state values returned from the StateProvider. If this
223         * event is not vetoed, then the state object is passed to <b><tt>applyState</tt></b>. By default,
224         * that simply copies property values into this Component. The method maybe overriden to
225         * provide custom state restoration.
226         */
227        'beforestaterestore',
228        /**
229         * @event staterestore
230         * Fires after the state of the component is restored.
231         * @param {Ext.Component} this
232         * @param {Object} state The hash of state values returned from the StateProvider. This is passed
233         * to <b><tt>applyState</tt></b>. By default, that simply copies property values into this
234         * Component. The method maybe overriden to provide custom state restoration.
235         */
236        'staterestore',
237        /**
238         * @event beforestatesave
239         * Fires before the state of the component is saved to the configured state provider. Return false to stop the save.
240         * @param {Ext.Component} this
241         * @param {Object} state The hash of state values. This is determined by calling
242         * <b><tt>getState()</tt></b> on the Component. This method must be provided by the
243         * developer to return whetever representation of state is required, by default, Ext.Component
244         * has a null implementation.
245         */
246        'beforestatesave',
247        /**
248         * @event statesave
249         * Fires after the state of the component is saved to the configured state provider.
250         * @param {Ext.Component} this
251         * @param {Object} state The hash of state values. This is determined by calling
252         * <b><tt>getState()</tt></b> on the Component. This method must be provided by the
253         * developer to return whetever representation of state is required, by default, Ext.Component
254         * has a null implementation.
255         */
256        'statesave'
257    );
258    this.getId();
259    Ext.ComponentMgr.register(this);
260    Ext.Component.superclass.constructor.call(this);
261
262    if(this.baseAction){
263        this.baseAction.addComponent(this);
264    }
265
266    this.initComponent();
267
268    if(this.plugins){
269        if(Ext.isArray(this.plugins)){
270            for(var i = 0, len = this.plugins.length; i < len; i++){
271                this.plugins[i] = this.initPlugin(this.plugins[i]);
272            }
273        }else{
274            this.plugins = this.initPlugin(this.plugins);
275        }
276    }
277
278    if(this.stateful !== false){
279        this.initState(config);
280    }
281
282    if(this.applyTo){
283        this.applyToMarkup(this.applyTo);
284        delete this.applyTo;
285    }else if(this.renderTo){
286        this.render(this.renderTo);
287        delete this.renderTo;
288    }
289};
290
291// private
292Ext.Component.AUTO_ID = 1000;
293
294Ext.extend(Ext.Component, Ext.util.Observable, {
295        // Configs below are used for all Components when rendered by FormLayout.
296    /**
297     * @cfg {String} fieldLabel <p>The label text to display next to this Component (defaults to '').</p>
298     * <br><p><b>Note</b>: this config is only used when this Component is rendered by a Container which
299     * has been configured to use the <b>{@link Ext.layout.FormLayout FormLayout}</b> layout manager (e.g.
300     * {@link Ext.form.FormPanel} or specifying <tt>layout:'form'</tt>).</p><br>
301     * <p>Also see <tt>{@link #hideLabel}</tt> and
302     * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</p>
303     * Example use:<pre><code>
304new Ext.FormPanel({
305    height: 100,
306    renderTo: Ext.getBody(),
307    items: [{
308        xtype: 'textfield',
309        fieldLabel: 'Name'
310    }]
311});
312</code></pre>
313     */
314    /**
315     * @cfg {String} labelStyle <p>A CSS style specification string to apply directly to this field's
316     * label.  Defaults to the container's labelStyle value if set (e.g.,
317     * <tt>{@link Ext.layout.FormLayout#labelStyle}</tt> , or '').</p>
318     * <br><p><b>Note</b>: see the note for <code>{@link #clearCls}</code>.</p><br>
319     * <p>Also see <code>{@link #hideLabel}</code> and
320     * <code>{@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</code></p>
321     * Example use:<pre><code>
322new Ext.FormPanel({
323    height: 100,
324    renderTo: Ext.getBody(),
325    items: [{
326        xtype: 'textfield',
327        fieldLabel: 'Name',
328        labelStyle: 'font-weight:bold;'
329    }]
330});
331</code></pre>
332     */
333    /**
334     * @cfg {String} labelSeparator <p>The separator to display after the text of each
335     * <tt>{@link #fieldLabel}</tt>.  This property may be configured at various levels.
336     * The order of precedence is:
337     * <div class="mdetail-params"><ul>
338     * <li>field / component level</li>
339     * <li>container level</li>
340     * <li>{@link Ext.layout.FormLayout#labelSeparator layout level} (defaults to colon <tt>':'</tt>)</li>
341     * </ul></div>
342     * To display no separator for this field's label specify empty string ''.</p>
343     * <br><p><b>Note</b>: see the note for <tt>{@link #clearCls}</tt>.</p><br>
344     * <p>Also see <tt>{@link #hideLabel}</tt> and
345     * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</p>
346     * Example use:<pre><code>
347new Ext.FormPanel({
348    height: 100,
349    renderTo: Ext.getBody(),
350    layoutConfig: {
351        labelSeparator: '~'   // layout config has lowest priority (defaults to ':')
352    },
353    {@link Ext.layout.FormLayout#labelSeparator labelSeparator}: '>>',     // config at container level
354    items: [{
355        xtype: 'textfield',
356        fieldLabel: 'Field 1',
357        labelSeparator: '...' // field/component level config supersedes others
358    },{
359        xtype: 'textfield',
360        fieldLabel: 'Field 2' // labelSeparator will be '='
361    }]
362});
363</code></pre>
364     */
365    /**
366     * @cfg {Boolean} hideLabel <p><tt>true</tt> to completely hide the label element
367     * ({@link #fieldLabel label} and {@link #labelSeparator separator}). Defaults to <tt>false</tt>.
368     * By default, even if you do not specify a <tt>{@link #fieldLabel}</tt> the space will still be
369     * reserved so that the field will line up with other fields that do have labels.
370     * Setting this to <tt>true</tt> will cause the field to not reserve that space.</p>
371     * <br><p><b>Note</b>: see the note for <tt>{@link #clearCls}</tt>.</p><br>
372     * Example use:<pre><code>
373new Ext.FormPanel({
374    height: 100,
375    renderTo: Ext.getBody(),
376    items: [{
377        xtype: 'textfield'
378        hideLabel: true
379    }]
380});
381</code></pre>
382     */
383    /**
384     * @cfg {String} clearCls <p>The CSS class used to to apply to the special clearing div rendered
385     * directly after each form field wrapper to provide field clearing (defaults to
386     * <tt>'x-form-clear-left'</tt>).</p>
387     * <br><p><b>Note</b>: this config is only used when this Component is rendered by a Container
388     * which has been configured to use the <b>{@link Ext.layout.FormLayout FormLayout}</b> layout
389     * manager (e.g. {@link Ext.form.FormPanel} or specifying <tt>layout:'form'</tt>) and either a
390     * <tt>{@link #fieldLabel}</tt> is specified or <tt>isFormField=true</tt> is specified.</p><br>
391     * <p>See {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl} also.</p>
392     */
393    /**
394     * @cfg {String} itemCls <p>An additional CSS class to apply to the div wrapping the form item
395     * element of this field.  If supplied, <tt>itemCls</tt> at the <b>field</b> level will override
396     * the default <tt>itemCls</tt> supplied at the <b>container</b> level. The value specified for
397     * <tt>itemCls</tt> will be added to the default class (<tt>'x-form-item'</tt>).</p>
398     * <p>Since it is applied to the item wrapper (see
399     * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}), it allows
400     * you to write standard CSS rules that can apply to the field, the label (if specified), or
401     * any other element within the markup for the field.</p>
402     * <br><p><b>Note</b>: see the note for <tt>{@link #fieldLabel}</tt>.</p><br>
403     * Example use:<pre><code>
404// Apply a style to the field's label:
405&lt;style>
406    .required .x-form-item-label {font-weight:bold;color:red;}
407&lt;/style>
408
409new Ext.FormPanel({
410        height: 100,
411        renderTo: Ext.getBody(),
412        items: [{
413                xtype: 'textfield',
414                fieldLabel: 'Name',
415                itemCls: 'required' //this label will be styled
416        },{
417                xtype: 'textfield',
418                fieldLabel: 'Favorite Color'
419        }]
420});
421</code></pre>
422     */
423
424        // Configs below are used for all Components when rendered by AnchorLayout.
425    /**
426     * @cfg {String} anchor <p><b>Note</b>: this config is only used when this Component is rendered
427     * by a Container which has been configured to use an <b>{@link Ext.layout.AnchorLayout AnchorLayout}</b>
428     * based layout manager, for example:<div class="mdetail-params"><ul>
429     * <li>{@link Ext.form.FormPanel}</li>
430     * <li>specifying <code>layout: 'anchor' // or 'form', or 'absolute'</code></li>
431     * </ul></div></p>
432     * <p>See {@link Ext.layout.AnchorLayout}.{@link Ext.layout.AnchorLayout#anchor anchor} also.</p>
433     */
434
435    /**
436     * @cfg {String} id
437     * <p>The <b>unique</b> id of this component (defaults to an {@link #getId auto-assigned id}).
438     * You should assign an id if you need to be able to access the component later and you do
439     * not have an object reference available (e.g., using {@link Ext}.{@link Ext#getCmp getCmp}).</p>
440     * <p>Note that this id will also be used as the element id for the containing HTML element
441     * that is rendered to the page for this component. This allows you to write id-based CSS
442     * rules to style the specific instance of this component uniquely, and also to select
443     * sub-elements using this component's id as the parent.</p>
444     * <p><b>Note</b>: to avoid complications imposed by a unique <tt>id</tt> also see
445     * <code>{@link #itemId}</code> and <code>{@link #ref}</code>.</p>
446     * <p><b>Note</b>: to access the container of an item see <code>{@link #ownerCt}</code>.</p>
447     */
448    /**
449     * @cfg {String} itemId
450     * <p>An <tt>itemId</tt> can be used as an alternative way to get a reference to a component
451     * when no object reference is available.  Instead of using an <code>{@link #id}</code> with
452     * {@link Ext}.{@link Ext#getCmp getCmp}, use <code>itemId</code> with
453     * {@link Ext.Container}.{@link Ext.Container#getComponent getComponent} which will retrieve
454     * <code>itemId</code>'s or <tt>{@link #id}</tt>'s. Since <code>itemId</code>'s are an index to the
455     * container's internal MixedCollection, the <code>itemId</code> is scoped locally to the container --
456     * avoiding potential conflicts with {@link Ext.ComponentMgr} which requires a <b>unique</b>
457     * <code>{@link #id}</code>.</p>
458     * <pre><code>
459var c = new Ext.Panel({ //
460    {@link Ext.BoxComponent#height height}: 300,
461    {@link #renderTo}: document.body,
462    {@link Ext.Container#layout layout}: 'auto',
463    {@link Ext.Container#items items}: [
464        {
465            itemId: 'p1',
466            {@link Ext.Panel#title title}: 'Panel 1',
467            {@link Ext.BoxComponent#height height}: 150
468        },
469        {
470            itemId: 'p2',
471            {@link Ext.Panel#title title}: 'Panel 2',
472            {@link Ext.BoxComponent#height height}: 150
473        }
474    ]
475})
476p1 = c.{@link Ext.Container#getComponent getComponent}('p1'); // not the same as {@link Ext#getCmp Ext.getCmp()}
477p2 = p1.{@link #ownerCt}.{@link Ext.Container#getComponent getComponent}('p2'); // reference via a sibling
478     * </code></pre>
479     * <p>Also see <tt>{@link #id}</tt> and <code>{@link #ref}</code>.</p>
480     * <p><b>Note</b>: to access the container of an item see <tt>{@link #ownerCt}</tt>.</p>
481     */
482    /**
483     * @cfg {String} xtype
484     * The registered <tt>xtype</tt> to create. This config option is not used when passing
485     * a config object into a constructor. This config option is used only when
486     * lazy instantiation is being used, and a child item of a Container is being
487     * specified not as a fully instantiated Component, but as a <i>Component config
488     * object</i>. The <tt>xtype</tt> will be looked up at render time up to determine what
489     * type of child Component to create.<br><br>
490     * The predefined xtypes are listed {@link Ext.Component here}.
491     * <br><br>
492     * If you subclass Components to create your own Components, you may register
493     * them using {@link Ext.ComponentMgr#registerType} in order to be able to
494     * take advantage of lazy instantiation and rendering.
495     */
496    /**
497     * @cfg {String} ptype
498     * The registered <tt>ptype</tt> to create. This config option is not used when passing
499     * a config object into a constructor. This config option is used only when
500     * lazy instantiation is being used, and a Plugin is being
501     * specified not as a fully instantiated Component, but as a <i>Component config
502     * object</i>. The <tt>ptype</tt> will be looked up at render time up to determine what
503     * type of Plugin to create.<br><br>
504     * If you create your own Plugins, you may register them using
505     * {@link Ext.ComponentMgr#registerPlugin} in order to be able to
506     * take advantage of lazy instantiation and rendering.
507     */
508    /**
509     * @cfg {String} cls
510     * An optional extra CSS class that will be added to this component's Element (defaults to '').  This can be
511     * useful for adding customized styles to the component or any of its children using standard CSS rules.
512     */
513    /**
514     * @cfg {String} overCls
515     * An optional extra CSS class that will be added to this component's Element when the mouse moves
516     * over the Element, and removed when the mouse moves out. (defaults to '').  This can be
517     * useful for adding customized 'active' or 'hover' styles to the component or any of its children using standard CSS rules.
518     */
519    /**
520     * @cfg {String} style
521     * A custom style specification to be applied to this component's Element.  Should be a valid argument to
522     * {@link Ext.Element#applyStyles}.
523     * <pre><code>
524new Ext.Panel({
525    title: 'Some Title',
526    renderTo: Ext.getBody(),
527    width: 400, height: 300,
528    layout: 'form',
529    items: [{
530        xtype: 'textarea',
531        style: {
532            width: '95%',
533            marginBottom: '10px'
534        }
535    },
536        new Ext.Button({
537            text: 'Send',
538            minWidth: '100',
539            style: {
540                marginBottom: '10px'
541            }
542        })
543    ]
544});
545     * </code></pre>
546     */
547    /**
548     * @cfg {String} ctCls
549     * <p>An optional extra CSS class that will be added to this component's container. This can be useful for
550     * adding customized styles to the container or any of its children using standard CSS rules.  See
551     * {@link Ext.layout.ContainerLayout}.{@link Ext.layout.ContainerLayout#extraCls extraCls} also.</p>
552     * <p><b>Note</b>: <tt>ctCls</tt> defaults to <tt>''</tt> except for the following class
553     * which assigns a value by default:
554     * <div class="mdetail-params"><ul>
555     * <li>{@link Ext.layout.Box Box Layout} : <tt>'x-box-layout-ct'</tt></li>
556     * </ul></div>
557     * To configure the above Class with an extra CSS class append to the default.  For example,
558     * for BoxLayout (Hbox and Vbox):<pre><code>
559     * ctCls: 'x-box-layout-ct custom-class'
560     * </code></pre>
561     * </p>
562     */
563    /**
564     * @cfg {Boolean} disabled
565     * Render this component disabled (default is false).
566     */
567    disabled : false,
568    /**
569     * @cfg {Boolean} hidden
570     * Render this component hidden (default is false). If <tt>true</tt>, the
571     * {@link #hide} method will be called internally.
572     */
573    hidden : false,
574    /**
575     * @cfg {Object/Array} plugins
576     * An object or array of objects that will provide custom functionality for this component.  The only
577     * requirement for a valid plugin is that it contain an init method that accepts a reference of type Ext.Component.
578     * When a component is created, if any plugins are available, the component will call the init method on each
579     * plugin, passing a reference to itself.  Each plugin can then call methods or respond to events on the
580     * component as needed to provide its functionality.
581     */
582    /**
583     * @cfg {Mixed} applyTo
584     * <p>Specify the id of the element, a DOM element or an existing Element corresponding to a DIV
585     * that is already present in the document that specifies some structural markup for this
586     * component.</p><div><ul>
587     * <li><b>Description</b> : <ul>
588     * <div class="sub-desc">When <tt>applyTo</tt> is used, constituent parts of the component can also be specified
589     * by id or CSS class name within the main element, and the component being created may attempt
590     * to create its subcomponents from that markup if applicable.</div>
591     * </ul></li>
592     * <li><b>Notes</b> : <ul>
593     * <div class="sub-desc">When using this config, a call to render() is not required.</div>
594     * <div class="sub-desc">If applyTo is specified, any value passed for {@link #renderTo} will be ignored and the target
595     * element's parent node will automatically be used as the component's container.</div>
596     * </ul></li>
597     * </ul></div>
598     */
599    /**
600     * @cfg {Mixed} renderTo
601     * <p>Specify the id of the element, a DOM element or an existing Element that this component
602     * will be rendered into.</p><div><ul>
603     * <li><b>Notes</b> : <ul>
604     * <div class="sub-desc">Do <u>not</u> use this option if the Component is to be a child item of
605     * a {@link Ext.Container Container}. It is the responsibility of the
606     * {@link Ext.Container Container}'s {@link Ext.Container#layout layout manager}
607     * to render and manage its child items.</div>
608     * <div class="sub-desc">When using this config, a call to render() is not required.</div>
609     * </ul></li>
610     * </ul></div>
611     * <p>See <tt>{@link #render}</tt> also.</p>
612     */
613    /**
614     * @cfg {Boolean} stateful
615     * <p>A flag which causes the Component to attempt to restore the state of
616     * internal properties from a saved state on startup. The component must have
617     * either a <code>{@link #stateId}</code> or <code>{@link #id}</code> assigned
618     * for state to be managed. Auto-generated ids are not guaranteed to be stable
619     * across page loads and cannot be relied upon to save and restore the same
620     * state for a component.<p>
621     * <p>For state saving to work, the state manager's provider must have been
622     * set to an implementation of {@link Ext.state.Provider} which overrides the
623     * {@link Ext.state.Provider#set set} and {@link Ext.state.Provider#get get}
624     * methods to save and recall name/value pairs. A built-in implementation,
625     * {@link Ext.state.CookieProvider} is available.</p>
626     * <p>To set the state provider for the current page:</p>
627     * <pre><code>
628Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
629    expires: new Date(new Date().getTime()+(1000*60*60*24*7)), //7 days from now
630}));
631     * </code></pre>
632     * <p>A stateful Component attempts to save state when one of the events
633     * listed in the <code>{@link #stateEvents}</code> configuration fires.</p>
634     * <p>To save state, a stateful Component first serializes its state by
635     * calling <b><code>getState</code></b>. By default, this function does
636     * nothing. The developer must provide an implementation which returns an
637     * object hash which represents the Component's restorable state.</p>
638     * <p>The value yielded by getState is passed to {@link Ext.state.Manager#set}
639     * which uses the configured {@link Ext.state.Provider} to save the object
640     * keyed by the Component's <code>{@link stateId}</code>, or, if that is not
641     * specified, its <code>{@link #id}</code>.</p>
642     * <p>During construction, a stateful Component attempts to <i>restore</i>
643     * its state by calling {@link Ext.state.Manager#get} passing the
644     * <code>{@link #stateId}</code>, or, if that is not specified, the
645     * <code>{@link #id}</code>.</p>
646     * <p>The resulting object is passed to <b><code>applyState</code></b>.
647     * The default implementation of <code>applyState</code> simply copies
648     * properties into the object, but a developer may override this to support
649     * more behaviour.</p>
650     * <p>You can perform extra processing on state save and restore by attaching
651     * handlers to the {@link #beforestaterestore}, {@link #staterestore},
652     * {@link #beforestatesave} and {@link #statesave} events.</p>
653     */
654    /**
655     * @cfg {String} stateId
656     * The unique id for this component to use for state management purposes
657     * (defaults to the component id if one was set, otherwise null if the
658     * component is using a generated id).
659     * <p>See <code>{@link #stateful}</code> for an explanation of saving and
660     * restoring Component state.</p>
661     */
662    /**
663     * @cfg {Array} stateEvents
664     * <p>An array of events that, when fired, should trigger this component to
665     * save its state (defaults to none). <code>stateEvents</code> may be any type
666     * of event supported by this component, including browser or custom events
667     * (e.g., <tt>['click', 'customerchange']</tt>).</p>
668     * <p>See <code>{@link #stateful}</code> for an explanation of saving and
669     * restoring Component state.</p>
670     */
671    /**
672     * @cfg {Mixed} autoEl
673     * <p>A tag name or {@link Ext.DomHelper DomHelper} spec used to create the {@link #getEl Element} which will
674     * encapsulate this Component.</p>
675     * <p>You do not normally need to specify this. For the base classes {@link Ext.Component}, {@link Ext.BoxComponent},
676     * and {@link Ext.Container}, this defaults to <b><tt>'div'</tt></b>. The more complex Ext classes use a more complex
677     * DOM structure created by their own onRender methods.</p>
678     * <p>This is intended to allow the developer to create application-specific utility Components encapsulated by
679     * different DOM elements. Example usage:</p><pre><code>
680{
681    xtype: 'box',
682    autoEl: {
683        tag: 'img',
684        src: 'http://www.example.com/example.jpg'
685    }
686}, {
687    xtype: 'box',
688    autoEl: {
689        tag: 'blockquote',
690        html: 'autoEl is cool!'
691    }
692}, {
693    xtype: 'container',
694    autoEl: 'ul',
695    cls: 'ux-unordered-list',
696    items: {
697        xtype: 'box',
698        autoEl: 'li',
699        html: 'First list item'
700    }
701}
702</code></pre>
703     */
704    autoEl : 'div',
705
706    /**
707     * @cfg {String} disabledClass
708     * CSS class added to the component when it is disabled (defaults to 'x-item-disabled').
709     */
710    disabledClass : 'x-item-disabled',
711    /**
712     * @cfg {Boolean} allowDomMove
713     * Whether the component can move the Dom node when rendering (defaults to true).
714     */
715    allowDomMove : true,
716    /**
717     * @cfg {Boolean} autoShow
718     * True if the component should check for hidden classes (e.g. 'x-hidden' or 'x-hide-display') and remove
719     * them on render (defaults to false).
720     */
721    autoShow : false,
722    /**
723     * @cfg {String} hideMode
724     * <p>How this component should be hidden. Supported values are <tt>'visibility'</tt>
725     * (css visibility), <tt>'offsets'</tt> (negative offset position) and <tt>'display'</tt>
726     * (css display).</p>
727     * <br><p><b>Note</b>: the default of <tt>'display'</tt> is generally preferred
728     * since items are automatically laid out when they are first shown (no sizing
729     * is done while hidden).</p>
730     */
731    hideMode : 'display',
732    /**
733     * @cfg {Boolean} hideParent
734     * True to hide and show the component's container when hide/show is called on the component, false to hide
735     * and show the component itself (defaults to false).  For example, this can be used as a shortcut for a hide
736     * button on a window by setting hide:true on the button when adding it to its parent container.
737     */
738    hideParent : false,
739    /**
740     * <p>The {@link Ext.Element} which encapsulates this Component. Read-only.</p>
741     * <p>This will <i>usually</i> be a &lt;DIV> element created by the class's onRender method, but
742     * that may be overridden using the <code>{@link #autoEl}</code> config.</p>
743     * <br><p><b>Note</b>: this element will not be available until this Component has been rendered.</p><br>
744     * <p>To add listeners for <b>DOM events</b> to this Component (as opposed to listeners
745     * for this Component's own Observable events), see the {@link Ext.util.Observable#listeners listeners}
746     * config for a suggestion, or use a render listener directly:</p><pre><code>
747new Ext.Panel({
748    title: 'The Clickable Panel',
749    listeners: {
750        render: function(p) {
751            // Append the Panel to the click handler&#39;s argument list.
752            p.getEl().on('click', handlePanelClick.createDelegate(null, [p], true));
753        },
754        single: true  // Remove the listener after first invocation
755    }
756});
757</code></pre>
758     * <p>See also <tt>{@link #getEl getEl}</p>
759     * @type Ext.Element
760     * @property el
761     */
762    /**
763     * The component's owner {@link Ext.Container} (defaults to undefined, and is set automatically when
764     * the component is added to a container).  Read-only.
765     * <p><b>Note</b>: to access items within the container see <tt>{@link #itemId}</tt>.</p>
766     * @type Ext.Container
767     * @property ownerCt
768     */
769    /**
770     * True if this component is hidden. Read-only.
771     * @type Boolean
772     * @property
773     */
774    /**
775     * True if this component is disabled. Read-only.
776     * @type Boolean
777     * @property
778     */
779    /**
780     * True if this component has been rendered. Read-only.
781     * @type Boolean
782     * @property
783     */
784    rendered : false,
785
786    // private
787    ctype : 'Ext.Component',
788
789    // private
790    actionMode : 'el',
791
792    // private
793    getActionEl : function(){
794        return this[this.actionMode];
795    },
796
797    initPlugin : function(p){
798        if(p.ptype && !Ext.isFunction(p.init)){
799            p = Ext.ComponentMgr.createPlugin(p);
800        }else if(Ext.isString(p)){
801            p = Ext.ComponentMgr.createPlugin({
802                ptype: p
803            });
804        }
805        p.init(this);
806        return p;
807    },
808
809    /* // protected
810     * Function to be implemented by Component subclasses to be part of standard component initialization flow (it is empty by default).
811     * <pre><code>
812// Traditional constructor:
813Ext.Foo = function(config){
814    // call superclass constructor:
815    Ext.Foo.superclass.constructor.call(this, config);
816
817    this.addEvents({
818        // add events
819    });
820};
821Ext.extend(Ext.Foo, Ext.Bar, {
822   // class body
823}
824
825// initComponent replaces the constructor:
826Ext.Foo = Ext.extend(Ext.Bar, {
827    initComponent : function(){
828        // call superclass initComponent
829        Ext.Container.superclass.initComponent.call(this);
830
831        this.addEvents({
832            // add events
833        });
834    }
835}
836</code></pre>
837     */
838    initComponent : Ext.emptyFn,
839
840    /**
841     * <p>Render this Component into the passed HTML element.</p>
842     * <p><b>If you are using a {@link Ext.Container Container} object to house this Component, then
843     * do not use the render method.</b></p>
844     * <p>A Container's child Components are rendered by that Container's
845     * {@link Ext.Container#layout layout} manager when the Container is first rendered.</p>
846     * <p>Certain layout managers allow dynamic addition of child components. Those that do
847     * include {@link Ext.layout.CardLayout}, {@link Ext.layout.AnchorLayout},
848     * {@link Ext.layout.FormLayout}, {@link Ext.layout.TableLayout}.</p>
849     * <p>If the Container is already rendered when a new child Component is added, you may need to call
850     * the Container's {@link Ext.Container#doLayout doLayout} to refresh the view which causes any
851     * unrendered child Components to be rendered. This is required so that you can add multiple
852     * child components if needed while only refreshing the layout once.</p>
853     * <p>When creating complex UIs, it is important to remember that sizing and positioning
854     * of child items is the responsibility of the Container's {@link Ext.Container#layout layout} manager.
855     * If you expect child items to be sized in response to user interactions, you must
856     * configure the Container with a layout manager which creates and manages the type of layout you
857     * have in mind.</p>
858     * <p><b>Omitting the Container's {@link Ext.Container#layout layout} config means that a basic
859     * layout manager is used which does nothing but render child components sequentially into the
860     * Container. No sizing or positioning will be performed in this situation.</b></p>
861     * @param {Element/HTMLElement/String} container (optional) The element this Component should be
862     * rendered into. If it is being created from existing markup, this should be omitted.
863     * @param {String/Number} position (optional) The element ID or DOM node index within the container <b>before</b>
864     * which this component will be inserted (defaults to appending to the end of the container)
865     */
866    render : function(container, position){
867        if(!this.rendered && this.fireEvent('beforerender', this) !== false){
868            if(!container && this.el){
869                this.el = Ext.get(this.el);
870                container = this.el.dom.parentNode;
871                this.allowDomMove = false;
872            }
873            this.container = Ext.get(container);
874            if(this.ctCls){
875                this.container.addClass(this.ctCls);
876            }
877            this.rendered = true;
878            if(position !== undefined){
879                if(Ext.isNumber(position)){
880                    position = this.container.dom.childNodes[position];
881                }else{
882                    position = Ext.getDom(position);
883                }
884            }
885            this.onRender(this.container, position || null);
886            if(this.autoShow){
887                this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
888            }
889            if(this.cls){
890                this.el.addClass(this.cls);
891                delete this.cls;
892            }
893            if(this.style){
894                this.el.applyStyles(this.style);
895                delete this.style;
896            }
897            if(this.overCls){
898                this.el.addClassOnOver(this.overCls);
899            }
900            this.fireEvent('render', this);
901            this.afterRender(this.container);
902            if(this.hidden){
903                // call this so we don't fire initial hide events.
904                this.doHide();
905            }
906            if(this.disabled){
907                // pass silent so the event doesn't fire the first time.
908                this.disable(true);
909            }
910
911            if(this.stateful !== false){
912                this.initStateEvents();
913            }
914            this.initRef();
915            this.fireEvent('afterrender', this);
916        }
917        return this;
918    },
919
920    initRef : function(){
921        /**
922         * @cfg {String} ref
923         * <p>A path specification, relative to the Component's {@link #ownerCt} specifying into which
924         * ancestor Container to place a named reference to this Component.</p>
925         * <p>The ancestor axis can be traversed by using '/' characters in the path.
926         * For example, to put a reference to a Toolbar Button into <i>the Panel which owns the Toolbar</i>:</p><pre><code>
927var myGrid = new Ext.grid.EditorGridPanel({
928    title: 'My EditorGridPanel',
929    store: myStore,
930    colModel: myColModel,
931    tbar: [{
932        text: 'Save',
933        handler: saveChanges,
934        disabled: true,
935        ref: '../saveButton'
936    }],
937    listeners: {
938        afteredit: function() {
939//          The button reference is in the GridPanel
940            myGrid.saveButton.enable();
941        }
942    }
943});
944</code></pre>
945         * <p>In the code above, if the ref had been <code>'saveButton'</code> the reference would
946         * have been placed into the Toolbar. Each '/' in the ref moves up one level from the
947         * Component's {@link #ownerCt}.</p>
948         */
949        if(this.ref){
950            var levels = this.ref.split('/');
951            var last = levels.length, i = 0;
952            var t = this;
953            while(i < last){
954                if(t.ownerCt){
955                    t = t.ownerCt;
956                }
957                i++;
958            }
959            t[levels[--i]] = this;
960        }
961    },
962
963    // private
964    initState : function(config){
965        if(Ext.state.Manager){
966            var id = this.getStateId();
967            if(id){
968                var state = Ext.state.Manager.get(id);
969                if(state){
970                    if(this.fireEvent('beforestaterestore', this, state) !== false){
971                        this.applyState(state);
972                        this.fireEvent('staterestore', this, state);
973                    }
974                }
975            }
976        }
977    },
978
979    // private
980    getStateId : function(){
981        return this.stateId || ((this.id.indexOf('ext-comp-') == 0 || this.id.indexOf('ext-gen') == 0) ? null : this.id);
982    },
983
984    // private
985    initStateEvents : function(){
986        if(this.stateEvents){
987            for(var i = 0, e; e = this.stateEvents[i]; i++){
988                this.on(e, this.saveState, this, {delay:100});
989            }
990        }
991    },
992
993    // private
994    applyState : function(state, config){
995        if(state){
996            Ext.apply(this, state);
997        }
998    },
999
1000    // private
1001    getState : function(){
1002        return null;
1003    },
1004
1005    // private
1006    saveState : function(){
1007        if(Ext.state.Manager && this.stateful !== false){
1008            var id = this.getStateId();
1009            if(id){
1010                var state = this.getState();
1011                if(this.fireEvent('beforestatesave', this, state) !== false){
1012                    Ext.state.Manager.set(id, state);
1013                    this.fireEvent('statesave', this, state);
1014                }
1015            }
1016        }
1017    },
1018
1019    /**
1020     * Apply this component to existing markup that is valid. With this function, no call to render() is required.
1021     * @param {String/HTMLElement} el
1022     */
1023    applyToMarkup : function(el){
1024        this.allowDomMove = false;
1025        this.el = Ext.get(el);
1026        this.render(this.el.dom.parentNode);
1027    },
1028
1029    /**
1030     * Adds a CSS class to the component's underlying element.
1031     * @param {string} cls The CSS class name to add
1032     * @return {Ext.Component} this
1033     */
1034    addClass : function(cls){
1035        if(this.el){
1036            this.el.addClass(cls);
1037        }else{
1038            this.cls = this.cls ? this.cls + ' ' + cls : cls;
1039        }
1040        return this;
1041    },
1042
1043    /**
1044     * Removes a CSS class from the component's underlying element.
1045     * @param {string} cls The CSS class name to remove
1046     * @return {Ext.Component} this
1047     */
1048    removeClass : function(cls){
1049        if(this.el){
1050            this.el.removeClass(cls);
1051        }else if(this.cls){
1052            this.cls = this.cls.split(' ').remove(cls).join(' ');
1053        }
1054        return this;
1055    },
1056
1057    // private
1058    // default function is not really useful
1059    onRender : function(ct, position){
1060        if(!this.el && this.autoEl){
1061            if(Ext.isString(this.autoEl)){
1062                this.el = document.createElement(this.autoEl);
1063            }else{
1064                var div = document.createElement('div');
1065                Ext.DomHelper.overwrite(div, this.autoEl);
1066                this.el = div.firstChild;
1067            }
1068            if (!this.el.id) {
1069                this.el.id = this.getId();
1070            }
1071        }
1072        if(this.el){
1073            this.el = Ext.get(this.el);
1074            if(this.allowDomMove !== false){
1075                ct.dom.insertBefore(this.el.dom, position);
1076            }
1077        }
1078    },
1079
1080    // private
1081    getAutoCreate : function(){
1082        var cfg = Ext.isObject(this.autoCreate) ?
1083                      this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
1084        if(this.id && !cfg.id){
1085            cfg.id = this.id;
1086        }
1087        return cfg;
1088    },
1089
1090    // private
1091    afterRender : Ext.emptyFn,
1092
1093    /**
1094     * Destroys this component by purging any event listeners, removing the component's element from the DOM,
1095     * removing the component from its {@link Ext.Container} (if applicable) and unregistering it from
1096     * {@link Ext.ComponentMgr}.  Destruction is generally handled automatically by the framework and this method
1097     * should usually not need to be called directly.
1098     *
1099     */
1100    destroy : function(){
1101        if(this.fireEvent('beforedestroy', this) !== false){
1102            this.beforeDestroy();
1103            if(this.rendered){
1104                this.el.removeAllListeners();
1105                this.el.remove();
1106                if(this.actionMode == 'container' || this.removeMode == 'container'){
1107                    this.container.remove();
1108                }
1109            }
1110            this.onDestroy();
1111            Ext.ComponentMgr.unregister(this);
1112            this.fireEvent('destroy', this);
1113            this.purgeListeners();
1114        }
1115    },
1116
1117    // private
1118    beforeDestroy : Ext.emptyFn,
1119
1120    // private
1121    onDestroy  : Ext.emptyFn,
1122
1123    /**
1124     * <p>Returns the {@link Ext.Element} which encapsulates this Component.</p>
1125     * <p>This will <i>usually</i> be a &lt;DIV> element created by the class's onRender method, but
1126     * that may be overridden using the {@link #autoEl} config.</p>
1127     * <br><p><b>Note</b>: this element will not be available until this Component has been rendered.</p><br>
1128     * <p>To add listeners for <b>DOM events</b> to this Component (as opposed to listeners
1129     * for this Component's own Observable events), see the {@link #listeners} config for a suggestion,
1130     * or use a render listener directly:</p><pre><code>
1131new Ext.Panel({
1132    title: 'The Clickable Panel',
1133    listeners: {
1134        render: function(p) {
1135            // Append the Panel to the click handler&#39;s argument list.
1136            p.getEl().on('click', handlePanelClick.createDelegate(null, [p], true));
1137        },
1138        single: true  // Remove the listener after first invocation
1139    }
1140});
1141</code></pre>
1142     * @return {Ext.Element} The Element which encapsulates this Component.
1143     */
1144    getEl : function(){
1145        return this.el;
1146    },
1147
1148    /**
1149     * Returns the <code>id</code> of this component or automatically generates and
1150     * returns an <code>id</code> if an <code>id</code> is not defined yet:<pre><code>
1151     * 'ext-comp-' + (++Ext.Component.AUTO_ID)
1152     * </code></pre>
1153     * @return {String} id
1154     */
1155    getId : function(){
1156        return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
1157    },
1158
1159    /**
1160     * Returns the <code>{@link #itemId}</code> of this component.  If an
1161     * <code>{@link #itemId}</code> was not assigned through configuration the
1162     * <code>id</code> is returned using <code>{@link #getId}</code>.
1163     * @return {String}
1164     */
1165    getItemId : function(){
1166        return this.itemId || this.getId();
1167    },
1168
1169    /**
1170     * Try to focus this component.
1171     * @param {Boolean} selectText (optional) If applicable, true to also select the text in this component
1172     * @param {Boolean/Number} delay (optional) Delay the focus this number of milliseconds (true for 10 milliseconds)
1173     * @return {Ext.Component} this
1174     */
1175    focus : function(selectText, delay){
1176        if(delay){
1177            this.focus.defer(Ext.isNumber(delay) ? delay : 10, this, [selectText, false]);
1178            return;
1179        }
1180        if(this.rendered){
1181            this.el.focus();
1182            if(selectText === true){
1183                this.el.dom.select();
1184            }
1185        }
1186        return this;
1187    },
1188
1189    // private
1190    blur : function(){
1191        if(this.rendered){
1192            this.el.blur();
1193        }
1194        return this;
1195    },
1196
1197    /**
1198     * Disable this component and fire the 'disable' event.
1199     * @return {Ext.Component} this
1200     */
1201    disable : function(/* private */ silent){
1202        if(this.rendered){
1203            this.onDisable();
1204        }
1205        this.disabled = true;
1206        if(silent !== true){
1207            this.fireEvent('disable', this);
1208        }
1209        return this;
1210    },
1211
1212    // private
1213    onDisable : function(){
1214        this.getActionEl().addClass(this.disabledClass);
1215        this.el.dom.disabled = true;
1216    },
1217
1218    /**
1219     * Enable this component and fire the 'enable' event.
1220     * @return {Ext.Component} this
1221     */
1222    enable : function(){
1223        if(this.rendered){
1224            this.onEnable();
1225        }
1226        this.disabled = false;
1227        this.fireEvent('enable', this);
1228        return this;
1229    },
1230
1231    // private
1232    onEnable : function(){
1233        this.getActionEl().removeClass(this.disabledClass);
1234        this.el.dom.disabled = false;
1235    },
1236
1237    /**
1238     * Convenience function for setting disabled/enabled by boolean.
1239     * @param {Boolean} disabled
1240     * @return {Ext.Component} this
1241     */
1242    setDisabled : function(disabled){
1243        return this[disabled ? 'disable' : 'enable']();
1244    },
1245
1246    /**
1247     * Show this component.  Listen to the '{@link #beforeshow}' event and return
1248     * <tt>false</tt> to cancel showing the component.  Fires the '{@link #show}'
1249     * event after showing the component.
1250     * @return {Ext.Component} this
1251     */
1252    show : function(){
1253        if(this.fireEvent('beforeshow', this) !== false){
1254            this.hidden = false;
1255            if(this.autoRender){
1256                this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
1257            }
1258            if(this.rendered){
1259                this.onShow();
1260            }
1261            this.fireEvent('show', this);
1262        }
1263        return this;
1264    },
1265
1266    // private
1267    onShow : function(){
1268        this.getVisibiltyEl().removeClass('x-hide-' + this.hideMode);
1269    },
1270
1271    /**
1272     * Hide this component.  Listen to the '{@link #beforehide}' event and return
1273     * <tt>false</tt> to cancel hiding the component.  Fires the '{@link #hide}'
1274     * event after hiding the component. Note this method is called internally if
1275     * the component is configured to be <code>{@link #hidden}</code>.
1276     * @return {Ext.Component} this
1277     */
1278    hide : function(){
1279        if(this.fireEvent('beforehide', this) !== false){
1280            this.doHide();
1281            this.fireEvent('hide', this);
1282        }
1283        return this;
1284    },
1285
1286    // private
1287    doHide: function(){
1288        this.hidden = true;
1289        if(this.rendered){
1290            this.onHide();
1291        }
1292    },
1293
1294    // private
1295    onHide : function(){
1296        this.getVisibiltyEl().addClass('x-hide-' + this.hideMode);
1297    },
1298
1299    // private
1300    getVisibiltyEl : function(){
1301        return this.hideParent ? this.container : this.getActionEl();
1302    },
1303
1304    /**
1305     * Convenience function to hide or show this component by boolean.
1306     * @param {Boolean} visible True to show, false to hide
1307     * @return {Ext.Component} this
1308     */
1309    setVisible : function(visible){
1310        return this[visible ? 'show' : 'hide']();
1311    },
1312
1313    /**
1314     * Returns true if this component is visible.
1315     * @return {Boolean} True if this component is visible, false otherwise.
1316     */
1317    isVisible : function(){
1318        return this.rendered && this.getVisibiltyEl().isVisible();
1319    },
1320
1321    /**
1322     * Clone the current component using the original config values passed into this instance by default.
1323     * @param {Object} overrides A new config containing any properties to override in the cloned version.
1324     * An id property can be passed on this object, otherwise one will be generated to avoid duplicates.
1325     * @return {Ext.Component} clone The cloned copy of this component
1326     */
1327    cloneConfig : function(overrides){
1328        overrides = overrides || {};
1329        var id = overrides.id || Ext.id();
1330        var cfg = Ext.applyIf(overrides, this.initialConfig);
1331        cfg.id = id; // prevent dup id
1332        return new this.constructor(cfg);
1333    },
1334
1335    /**
1336     * Gets the xtype for this component as registered with {@link Ext.ComponentMgr}. For a list of all
1337     * available xtypes, see the {@link Ext.Component} header. Example usage:
1338     * <pre><code>
1339var t = new Ext.form.TextField();
1340alert(t.getXType());  // alerts 'textfield'
1341</code></pre>
1342     * @return {String} The xtype
1343     */
1344    getXType : function(){
1345        return this.constructor.xtype;
1346    },
1347
1348    /**
1349     * <p>Tests whether or not this Component is of a specific xtype. This can test whether this Component is descended
1350     * from the xtype (default) or whether it is directly of the xtype specified (shallow = true).</p>
1351     * <p><b>If using your own subclasses, be aware that a Component must register its own xtype
1352     * to participate in determination of inherited xtypes.</b></p>
1353     * <p>For a list of all available xtypes, see the {@link Ext.Component} header.</p>
1354     * <p>Example usage:</p>
1355     * <pre><code>
1356var t = new Ext.form.TextField();
1357var isText = t.isXType('textfield');        // true
1358var isBoxSubclass = t.isXType('box');       // true, descended from BoxComponent
1359var isBoxInstance = t.isXType('box', true); // false, not a direct BoxComponent instance
1360</code></pre>
1361     * @param {String} xtype The xtype to check for this Component
1362     * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is
1363     * the default), or true to check whether this Component is directly of the specified xtype.
1364     * @return {Boolean} True if this component descends from the specified xtype, false otherwise.
1365     */
1366    isXType : function(xtype, shallow){
1367        //assume a string by default
1368        if (Ext.isFunction(xtype)){
1369            xtype = xtype.xtype; //handle being passed the class, e.g. Ext.Component
1370        }else if (Ext.isObject(xtype)){
1371            xtype = xtype.constructor.xtype; //handle being passed an instance
1372        }
1373
1374        return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
1375    },
1376
1377    /**
1378     * <p>Returns this Component's xtype hierarchy as a slash-delimited string. For a list of all
1379     * available xtypes, see the {@link Ext.Component} header.</p>
1380     * <p><b>If using your own subclasses, be aware that a Component must register its own xtype
1381     * to participate in determination of inherited xtypes.</b></p>
1382     * <p>Example usage:</p>
1383     * <pre><code>
1384var t = new Ext.form.TextField();
1385alert(t.getXTypes());  // alerts 'component/box/field/textfield'
1386</code></pre>
1387     * @return {String} The xtype hierarchy string
1388     */
1389    getXTypes : function(){
1390        var tc = this.constructor;
1391        if(!tc.xtypes){
1392            var c = [], sc = this;
1393            while(sc && sc.constructor.xtype){
1394                c.unshift(sc.constructor.xtype);
1395                sc = sc.constructor.superclass;
1396            }
1397            tc.xtypeChain = c;
1398            tc.xtypes = c.join('/');
1399        }
1400        return tc.xtypes;
1401    },
1402
1403    /**
1404     * Find a container above this component at any level by a custom function. If the passed function returns
1405     * true, the container will be returned.
1406     * @param {Function} fn The custom function to call with the arguments (container, this component).
1407     * @return {Ext.Container} The first Container for which the custom function returns true
1408     */
1409    findParentBy : function(fn) {
1410        for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
1411        return p || null;
1412    },
1413
1414    /**
1415     * Find a container above this component at any level by xtype or class
1416     * @param {String/Class} xtype The xtype string for a component, or the class of the component directly
1417     * @return {Ext.Container} The first Container which matches the given xtype or class
1418     */
1419    findParentByType : function(xtype) {
1420        return Ext.isFunction(xtype) ?
1421            this.findParentBy(function(p){
1422                return p.constructor === xtype;
1423            }) :
1424            this.findParentBy(function(p){
1425                return p.constructor.xtype === xtype;
1426            });
1427    },
1428
1429    getDomPositionEl : function(){
1430        return this.getPositionEl ? this.getPositionEl() : this.getEl();
1431    },
1432
1433    // private
1434    purgeListeners : function(){
1435        Ext.Component.superclass.purgeListeners.call(this);
1436        if(this.mons){
1437            this.on('beforedestroy', this.clearMons, this, {single: true});
1438        }
1439    },
1440
1441    // private
1442    clearMons : function(){
1443        Ext.each(this.mons, function(m){
1444            m.item.un(m.ename, m.fn, m.scope);
1445        }, this);
1446        this.mons = [];
1447    },
1448
1449    // internal function for auto removal of assigned event handlers on destruction
1450    mon : function(item, ename, fn, scope, opt){
1451        if(!this.mons){
1452            this.mons = [];
1453            this.on('beforedestroy', this.clearMons, this, {single: true});
1454        }
1455
1456        if(Ext.isObject(ename)){
1457                var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
1458
1459            var o = ename;
1460            for(var e in o){
1461                if(propRe.test(e)){
1462                    continue;
1463                }
1464                if(Ext.isFunction(o[e])){
1465                    // shared options
1466                                this.mons.push({
1467                                    item: item, ename: e, fn: o[e], scope: o.scope
1468                                });
1469                                item.on(e, o[e], o.scope, o);
1470                }else{
1471                    // individual options
1472                                this.mons.push({
1473                                    item: item, ename: e, fn: o[e], scope: o.scope
1474                                });
1475                                item.on(e, o[e]);
1476                }
1477            }
1478            return;
1479        }
1480
1481
1482        this.mons.push({
1483            item: item, ename: ename, fn: fn, scope: scope
1484        });
1485        item.on(ename, fn, scope, opt);
1486    },
1487
1488    // protected, opposite of mon
1489    mun : function(item, ename, fn, scope){
1490        var found, mon;
1491        for(var i = 0, len = this.mons.length; i < len; ++i){
1492            mon = this.mons[i];
1493            if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
1494                this.mons.splice(i, 1);
1495                item.un(ename, fn, scope);
1496                found = true;
1497                break;
1498            }
1499        }
1500        return found;
1501    },
1502
1503    /**
1504     * Returns the next component in the owning container
1505     * @return Ext.Component
1506     */
1507    nextSibling : function(){
1508        if(this.ownerCt){
1509            var index = this.ownerCt.items.indexOf(this);
1510            if(index != -1 && index+1 < this.ownerCt.items.getCount()){
1511                return this.ownerCt.items.itemAt(index+1);
1512            }
1513        }
1514        return null;
1515    },
1516
1517    /**
1518     * Returns the previous component in the owning container
1519     * @return Ext.Component
1520     */
1521    previousSibling : function(){
1522        if(this.ownerCt){
1523            var index = this.ownerCt.items.indexOf(this);
1524            if(index > 0){
1525                return this.ownerCt.items.itemAt(index-1);
1526            }
1527        }
1528        return null;
1529    },
1530
1531    /**
1532     * Provides the link for Observable's fireEvent method to bubble up the ownership hierarchy.
1533     * @return {Ext.Container} the Container which owns this Component.
1534     */
1535    getBubbleTarget : function(){
1536        return this.ownerCt;
1537    }
1538});
1539
1540Ext.reg('component', Ext.Component);
Note: See TracBrowser for help on using the repository browser.