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> |
---|
24 | xtype Class |
---|
25 | ------------- ------------------ |
---|
26 | box {@link Ext.BoxComponent} |
---|
27 | button {@link Ext.Button} |
---|
28 | buttongroup {@link Ext.ButtonGroup} |
---|
29 | colorpalette {@link Ext.ColorPalette} |
---|
30 | component {@link Ext.Component} |
---|
31 | container {@link Ext.Container} |
---|
32 | cycle {@link Ext.CycleButton} |
---|
33 | dataview {@link Ext.DataView} |
---|
34 | datepicker {@link Ext.DatePicker} |
---|
35 | editor {@link Ext.Editor} |
---|
36 | editorgrid {@link Ext.grid.EditorGridPanel} |
---|
37 | flash {@link Ext.FlashComponent} |
---|
38 | grid {@link Ext.grid.GridPanel} |
---|
39 | listview {@link Ext.ListView} |
---|
40 | panel {@link Ext.Panel} |
---|
41 | progress {@link Ext.ProgressBar} |
---|
42 | propertygrid {@link Ext.grid.PropertyGrid} |
---|
43 | slider {@link Ext.Slider} |
---|
44 | spacer {@link Ext.Spacer} |
---|
45 | splitbutton {@link Ext.SplitButton} |
---|
46 | tabpanel {@link Ext.TabPanel} |
---|
47 | treepanel {@link Ext.tree.TreePanel} |
---|
48 | viewport {@link Ext.ViewPort} |
---|
49 | window {@link Ext.Window} |
---|
50 | |
---|
51 | Toolbar components |
---|
52 | --------------------------------------- |
---|
53 | paging {@link Ext.PagingToolbar} |
---|
54 | toolbar {@link Ext.Toolbar} |
---|
55 | tbbutton {@link Ext.Toolbar.Button} (deprecated; use button) |
---|
56 | tbfill {@link Ext.Toolbar.Fill} |
---|
57 | tbitem {@link Ext.Toolbar.Item} |
---|
58 | tbseparator {@link Ext.Toolbar.Separator} |
---|
59 | tbspacer {@link Ext.Toolbar.Spacer} |
---|
60 | tbsplit {@link Ext.Toolbar.SplitButton} (deprecated; use splitbutton) |
---|
61 | tbtext {@link Ext.Toolbar.TextItem} |
---|
62 | |
---|
63 | Menu components |
---|
64 | --------------------------------------- |
---|
65 | menu {@link Ext.menu.Menu} |
---|
66 | colormenu {@link Ext.menu.ColorMenu} |
---|
67 | datemenu {@link Ext.menu.DateMenu} |
---|
68 | menubaseitem {@link Ext.menu.BaseItem} |
---|
69 | menucheckitem {@link Ext.menu.CheckItem} |
---|
70 | menuitem {@link Ext.menu.Item} |
---|
71 | menuseparator {@link Ext.menu.Separator} |
---|
72 | menutextitem {@link Ext.menu.TextItem} |
---|
73 | |
---|
74 | Form components |
---|
75 | --------------------------------------- |
---|
76 | form {@link Ext.FormPanel} |
---|
77 | checkbox {@link Ext.form.Checkbox} |
---|
78 | checkboxgroup {@link Ext.form.CheckboxGroup} |
---|
79 | combo {@link Ext.form.ComboBox} |
---|
80 | datefield {@link Ext.form.DateField} |
---|
81 | displayfield {@link Ext.form.DisplayField} |
---|
82 | field {@link Ext.form.Field} |
---|
83 | fieldset {@link Ext.form.FieldSet} |
---|
84 | hidden {@link Ext.form.Hidden} |
---|
85 | htmleditor {@link Ext.form.HtmlEditor} |
---|
86 | label {@link Ext.form.Label} |
---|
87 | numberfield {@link Ext.form.NumberField} |
---|
88 | radio {@link Ext.form.Radio} |
---|
89 | radiogroup {@link Ext.form.RadioGroup} |
---|
90 | textarea {@link Ext.form.TextArea} |
---|
91 | textfield {@link Ext.form.TextField} |
---|
92 | timefield {@link Ext.form.TimeField} |
---|
93 | trigger {@link Ext.form.TriggerField} |
---|
94 | |
---|
95 | Chart components |
---|
96 | --------------------------------------- |
---|
97 | chart {@link Ext.chart.Chart} |
---|
98 | barchart {@link Ext.chart.BarChart} |
---|
99 | cartesianchart {@link Ext.chart.CartesianChart} |
---|
100 | columnchart {@link Ext.chart.ColumnChart} |
---|
101 | linechart {@link Ext.chart.LineChart} |
---|
102 | piechart {@link Ext.chart.PieChart} |
---|
103 | |
---|
104 | Store xtypes |
---|
105 | --------------------------------------- |
---|
106 | arraystore {@link Ext.data.ArrayStore} |
---|
107 | directstore {@link Ext.data.DirectStore} |
---|
108 | groupingstore {@link Ext.data.GroupingStore} |
---|
109 | jsonstore {@link Ext.data.JsonStore} |
---|
110 | simplestore {@link Ext.data.SimpleStore} (deprecated; use arraystore) |
---|
111 | store {@link Ext.data.Store} |
---|
112 | xmlstore {@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 | */ |
---|
125 | Ext.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 |
---|
292 | Ext.Component.AUTO_ID = 1000; |
---|
293 | |
---|
294 | Ext.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> |
---|
304 | new 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> |
---|
322 | new 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> |
---|
347 | new 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> |
---|
373 | new 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 | <style> |
---|
406 | .required .x-form-item-label {font-weight:bold;color:red;} |
---|
407 | </style> |
---|
408 | |
---|
409 | new 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> |
---|
459 | var 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 | }) |
---|
476 | p1 = c.{@link Ext.Container#getComponent getComponent}('p1'); // not the same as {@link Ext#getCmp Ext.getCmp()} |
---|
477 | p2 = 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> |
---|
524 | new 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> |
---|
628 | Ext.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 <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> |
---|
747 | new Ext.Panel({ |
---|
748 | title: 'The Clickable Panel', |
---|
749 | listeners: { |
---|
750 | render: function(p) { |
---|
751 | // Append the Panel to the click handler'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: |
---|
813 | Ext.Foo = function(config){ |
---|
814 | // call superclass constructor: |
---|
815 | Ext.Foo.superclass.constructor.call(this, config); |
---|
816 | |
---|
817 | this.addEvents({ |
---|
818 | // add events |
---|
819 | }); |
---|
820 | }; |
---|
821 | Ext.extend(Ext.Foo, Ext.Bar, { |
---|
822 | // class body |
---|
823 | } |
---|
824 | |
---|
825 | // initComponent replaces the constructor: |
---|
826 | Ext.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> |
---|
927 | var 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 <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> |
---|
1131 | new Ext.Panel({ |
---|
1132 | title: 'The Clickable Panel', |
---|
1133 | listeners: { |
---|
1134 | render: function(p) { |
---|
1135 | // Append the Panel to the click handler'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> |
---|
1339 | var t = new Ext.form.TextField(); |
---|
1340 | alert(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> |
---|
1356 | var t = new Ext.form.TextField(); |
---|
1357 | var isText = t.isXType('textfield'); // true |
---|
1358 | var isBoxSubclass = t.isXType('box'); // true, descended from BoxComponent |
---|
1359 | var 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> |
---|
1384 | var t = new Ext.form.TextField(); |
---|
1385 | alert(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 | |
---|
1540 | Ext.reg('component', Ext.Component); |
---|