1 | /* |
---|
2 | * Ext JS Library 2.2.1 |
---|
3 | * Copyright(c) 2006-2009, Ext JS, LLC. |
---|
4 | * licensing@extjs.com |
---|
5 | * |
---|
6 | * http://extjs.com/license |
---|
7 | */ |
---|
8 | |
---|
9 | /** |
---|
10 | * @class Ext.Component |
---|
11 | * @extends Ext.util.Observable |
---|
12 | * <p>Base class for all Ext components. All subclasses of Component can automatically participate in the standard |
---|
13 | * Ext component lifecycle of creation, rendering and destruction. They also have automatic support for basic hide/show |
---|
14 | * and enable/disable behavior. Component allows any subclass to be lazy-rendered into any {@link Ext.Container} and |
---|
15 | * to be automatically registered with the {@link Ext.ComponentMgr} so that it can be referenced at any time via |
---|
16 | * {@link Ext#getCmp}. All visual widgets that require rendering into a layout should subclass Component (or |
---|
17 | * {@link Ext.BoxComponent} if managed box model handling is required).</p> |
---|
18 | * <p>Every component has a specific xtype, which is its Ext-specific type name, along with methods for checking the |
---|
19 | * xtype like {@link #getXType} and {@link #isXType}. This is the list of all valid xtypes:</p> |
---|
20 | * <pre> |
---|
21 | xtype Class |
---|
22 | ------------- ------------------ |
---|
23 | box Ext.BoxComponent |
---|
24 | button Ext.Button |
---|
25 | colorpalette Ext.ColorPalette |
---|
26 | component Ext.Component |
---|
27 | container Ext.Container |
---|
28 | cycle Ext.CycleButton |
---|
29 | dataview Ext.DataView |
---|
30 | datepicker Ext.DatePicker |
---|
31 | editor Ext.Editor |
---|
32 | editorgrid Ext.grid.EditorGridPanel |
---|
33 | grid Ext.grid.GridPanel |
---|
34 | paging Ext.PagingToolbar |
---|
35 | panel Ext.Panel |
---|
36 | progress Ext.ProgressBar |
---|
37 | propertygrid Ext.grid.PropertyGrid |
---|
38 | slider Ext.Slider |
---|
39 | splitbutton Ext.SplitButton |
---|
40 | statusbar Ext.StatusBar |
---|
41 | tabpanel Ext.TabPanel |
---|
42 | treepanel Ext.tree.TreePanel |
---|
43 | viewport Ext.Viewport |
---|
44 | window Ext.Window |
---|
45 | |
---|
46 | Toolbar components |
---|
47 | --------------------------------------- |
---|
48 | toolbar Ext.Toolbar |
---|
49 | tbbutton Ext.Toolbar.Button |
---|
50 | tbfill Ext.Toolbar.Fill |
---|
51 | tbitem Ext.Toolbar.Item |
---|
52 | tbseparator Ext.Toolbar.Separator |
---|
53 | tbspacer Ext.Toolbar.Spacer |
---|
54 | tbsplit Ext.Toolbar.SplitButton |
---|
55 | tbtext Ext.Toolbar.TextItem |
---|
56 | |
---|
57 | Form components |
---|
58 | --------------------------------------- |
---|
59 | form Ext.FormPanel |
---|
60 | checkbox Ext.form.Checkbox |
---|
61 | combo Ext.form.ComboBox |
---|
62 | datefield Ext.form.DateField |
---|
63 | field Ext.form.Field |
---|
64 | fieldset Ext.form.FieldSet |
---|
65 | hidden Ext.form.Hidden |
---|
66 | htmleditor Ext.form.HtmlEditor |
---|
67 | label Ext.form.Label |
---|
68 | numberfield Ext.form.NumberField |
---|
69 | radio Ext.form.Radio |
---|
70 | textarea Ext.form.TextArea |
---|
71 | textfield Ext.form.TextField |
---|
72 | timefield Ext.form.TimeField |
---|
73 | trigger Ext.form.TriggerField |
---|
74 | </pre> |
---|
75 | * @constructor |
---|
76 | * @param {Ext.Element/String/Object} config The configuration options. If an element is passed, it is set as the internal |
---|
77 | * element and its id used as the component id. If a string is passed, it is assumed to be the id of an existing element |
---|
78 | * and is used as the component id. Otherwise, it is assumed to be a standard config object and is applied to the component. |
---|
79 | */ |
---|
80 | Ext.Component = function(config){ |
---|
81 | config = config || {}; |
---|
82 | if(config.initialConfig){ |
---|
83 | if(config.isAction){ // actions |
---|
84 | this.baseAction = config; |
---|
85 | } |
---|
86 | config = config.initialConfig; // component cloning / action set up |
---|
87 | }else if(config.tagName || config.dom || typeof config == "string"){ // element object |
---|
88 | config = {applyTo: config, id: config.id || config}; |
---|
89 | } |
---|
90 | |
---|
91 | /** |
---|
92 | * This Component's initial configuration specification. Read-only. |
---|
93 | * @type Object |
---|
94 | * @property initialConfig |
---|
95 | */ |
---|
96 | this.initialConfig = config; |
---|
97 | |
---|
98 | Ext.apply(this, config); |
---|
99 | this.addEvents( |
---|
100 | /** |
---|
101 | * @event disable |
---|
102 | * Fires after the component is disabled. |
---|
103 | * @param {Ext.Component} this |
---|
104 | */ |
---|
105 | 'disable', |
---|
106 | /** |
---|
107 | * @event enable |
---|
108 | * Fires after the component is enabled. |
---|
109 | * @param {Ext.Component} this |
---|
110 | */ |
---|
111 | 'enable', |
---|
112 | /** |
---|
113 | * @event beforeshow |
---|
114 | * Fires before the component is shown. Return false to stop the show. |
---|
115 | * @param {Ext.Component} this |
---|
116 | */ |
---|
117 | 'beforeshow', |
---|
118 | /** |
---|
119 | * @event show |
---|
120 | * Fires after the component is shown. |
---|
121 | * @param {Ext.Component} this |
---|
122 | */ |
---|
123 | 'show', |
---|
124 | /** |
---|
125 | * @event beforehide |
---|
126 | * Fires before the component is hidden. Return false to stop the hide. |
---|
127 | * @param {Ext.Component} this |
---|
128 | */ |
---|
129 | 'beforehide', |
---|
130 | /** |
---|
131 | * @event hide |
---|
132 | * Fires after the component is hidden. |
---|
133 | * @param {Ext.Component} this |
---|
134 | */ |
---|
135 | 'hide', |
---|
136 | /** |
---|
137 | * @event beforerender |
---|
138 | * Fires before the component is rendered. Return false to stop the render. |
---|
139 | * @param {Ext.Component} this |
---|
140 | */ |
---|
141 | 'beforerender', |
---|
142 | /** |
---|
143 | * @event render |
---|
144 | * Fires after the component is rendered. |
---|
145 | * @param {Ext.Component} this |
---|
146 | */ |
---|
147 | 'render', |
---|
148 | /** |
---|
149 | * @event beforedestroy |
---|
150 | * Fires before the component is destroyed. Return false to stop the destroy. |
---|
151 | * @param {Ext.Component} this |
---|
152 | */ |
---|
153 | 'beforedestroy', |
---|
154 | /** |
---|
155 | * @event destroy |
---|
156 | * Fires after the component is destroyed. |
---|
157 | * @param {Ext.Component} this |
---|
158 | */ |
---|
159 | 'destroy', |
---|
160 | /** |
---|
161 | * @event beforestaterestore |
---|
162 | * Fires before the state of the component is restored. Return false to stop the restore. |
---|
163 | * @param {Ext.Component} this |
---|
164 | * @param {Object} state The hash of state values |
---|
165 | */ |
---|
166 | 'beforestaterestore', |
---|
167 | /** |
---|
168 | * @event staterestore |
---|
169 | * Fires after the state of the component is restored. |
---|
170 | * @param {Ext.Component} this |
---|
171 | * @param {Object} state The hash of state values |
---|
172 | */ |
---|
173 | 'staterestore', |
---|
174 | /** |
---|
175 | * @event beforestatesave |
---|
176 | * Fires before the state of the component is saved to the configured state provider. Return false to stop the save. |
---|
177 | * @param {Ext.Component} this |
---|
178 | * @param {Object} state The hash of state values |
---|
179 | */ |
---|
180 | 'beforestatesave', |
---|
181 | /** |
---|
182 | * @event statesave |
---|
183 | * Fires after the state of the component is saved to the configured state provider. |
---|
184 | * @param {Ext.Component} this |
---|
185 | * @param {Object} state The hash of state values |
---|
186 | */ |
---|
187 | 'statesave' |
---|
188 | ); |
---|
189 | this.getId(); |
---|
190 | Ext.ComponentMgr.register(this); |
---|
191 | Ext.Component.superclass.constructor.call(this); |
---|
192 | |
---|
193 | if(this.baseAction){ |
---|
194 | this.baseAction.addComponent(this); |
---|
195 | } |
---|
196 | |
---|
197 | this.initComponent(); |
---|
198 | |
---|
199 | if(this.plugins){ |
---|
200 | if(Ext.isArray(this.plugins)){ |
---|
201 | for(var i = 0, len = this.plugins.length; i < len; i++){ |
---|
202 | this.plugins[i] = this.initPlugin(this.plugins[i]); |
---|
203 | } |
---|
204 | }else{ |
---|
205 | this.plugins = this.initPlugin(this.plugins); |
---|
206 | } |
---|
207 | } |
---|
208 | |
---|
209 | if(this.stateful !== false){ |
---|
210 | this.initState(config); |
---|
211 | } |
---|
212 | |
---|
213 | if(this.applyTo){ |
---|
214 | this.applyToMarkup(this.applyTo); |
---|
215 | delete this.applyTo; |
---|
216 | }else if(this.renderTo){ |
---|
217 | this.render(this.renderTo); |
---|
218 | delete this.renderTo; |
---|
219 | } |
---|
220 | }; |
---|
221 | |
---|
222 | // private |
---|
223 | Ext.Component.AUTO_ID = 1000; |
---|
224 | |
---|
225 | Ext.extend(Ext.Component, Ext.util.Observable, { |
---|
226 | // Configs below are used for all Components when rendered by FormLayout. |
---|
227 | /** |
---|
228 | * @cfg {String} fieldLabel The label text to display next to this Component (defaults to '') |
---|
229 | * <p><b>This config is only used when this Component is rendered by a Container which has been |
---|
230 | * configured to use the {@link Ext.form.FormLayout FormLayout} layout manager.</b></p> |
---|
231 | * Example use:<pre><code> |
---|
232 | new Ext.FormPanel({ |
---|
233 | height: 100, |
---|
234 | renderTo: Ext.getBody(), |
---|
235 | items: [{ |
---|
236 | xtype: 'textfield', |
---|
237 | fieldLabel: 'Name' |
---|
238 | }] |
---|
239 | }); |
---|
240 | </code></pre> |
---|
241 | */ |
---|
242 | /** |
---|
243 | * @cfg {String} labelStyle A CSS style specification to apply directly to this field's label (defaults to the |
---|
244 | * container's labelStyle value if set, or '').<code></code>. |
---|
245 | * <p><b>This config is only used when this Component is rendered by a Container which has been |
---|
246 | * configured to use the {@link Ext.form.FormLayout FormLayout} layout manager.</b></p> |
---|
247 | * Example use:<pre><code> |
---|
248 | new Ext.FormPanel({ |
---|
249 | height: 100, |
---|
250 | renderTo: Ext.getBody(), |
---|
251 | items: [{ |
---|
252 | xtype: 'textfield', |
---|
253 | fieldLabel: 'Name', |
---|
254 | labelStyle: 'font-weight:bold;' |
---|
255 | }] |
---|
256 | }); |
---|
257 | </code></pre> |
---|
258 | */ |
---|
259 | /** |
---|
260 | * @cfg {String} labelSeparator The standard separator to display after the text of each form label (defaults |
---|
261 | * to the value of {@link Ext.layout.FormLayout#labelSeparator}, which is a colon ':' by default). To display |
---|
262 | * no separator for this field's label specify empty string ''. |
---|
263 | * <p><b>This config is only used when this Component is rendered by a Container which has been |
---|
264 | * configured to use the {@link Ext.form.FormLayout FormLayout} layout manager.</b></p> |
---|
265 | * Example use:<pre><code> |
---|
266 | new Ext.FormPanel({ |
---|
267 | height: 100, |
---|
268 | renderTo: Ext.getBody(), |
---|
269 | items: [{ |
---|
270 | xtype: 'textfield', |
---|
271 | fieldLabel: 'Name', |
---|
272 | labelSeparator: '...' |
---|
273 | }] |
---|
274 | }); |
---|
275 | </code></pre> |
---|
276 | */ |
---|
277 | /** |
---|
278 | * @cfg {Boolean} hideLabel True to completely hide the label element (defaults to false). By default, even if |
---|
279 | * you do not specify a {@link fieldLabel} the space will still be reserved so that the field will line up with |
---|
280 | * other fields that do have labels. Setting this to true will cause the field to not reserve that space. |
---|
281 | * <p><b>This config is only used when this Component is rendered by a Container which has been |
---|
282 | * configured to use the {@link Ext.form.FormLayout FormLayout} layout manager.</b></p> |
---|
283 | * Example use:<pre><code> |
---|
284 | new Ext.FormPanel({ |
---|
285 | height: 100, |
---|
286 | renderTo: Ext.getBody(), |
---|
287 | items: [{ |
---|
288 | xtype: 'textfield' |
---|
289 | hideLabel: true |
---|
290 | }] |
---|
291 | }); |
---|
292 | </code></pre> |
---|
293 | */ |
---|
294 | /** |
---|
295 | * @cfg {String} clearCls The CSS class used to provide field clearing (defaults to 'x-form-clear-left'). |
---|
296 | * <p><b>This config is only used when this Component is rendered by a Container which has been |
---|
297 | * configured to use the {@link Ext.form.FormLayout FormLayout} layout manager.</b></p> |
---|
298 | */ |
---|
299 | /** |
---|
300 | * @cfg {String} itemCls An additional CSS class to apply to the wrapper's form item element of this field (defaults |
---|
301 | * to the container's itemCls value if set, or ''). Since it is applied to the item wrapper, it allows you to write |
---|
302 | * standard CSS rules that can apply to the field, the label (if specified) or any other element within the markup for |
---|
303 | * the field. |
---|
304 | * <p><b>This config is only used when this Component is rendered by a Container which has been |
---|
305 | * configured to use the {@link Ext.form.FormLayout FormLayout} layout manager.</b></p> |
---|
306 | * Example use:<pre><code> |
---|
307 | // Apply a style to the field's label: |
---|
308 | <style> |
---|
309 | .required .x-form-item-label {font-weight:bold;color:red;} |
---|
310 | </style> |
---|
311 | |
---|
312 | new Ext.FormPanel({ |
---|
313 | height: 100, |
---|
314 | renderTo: Ext.getBody(), |
---|
315 | items: [{ |
---|
316 | xtype: 'textfield', |
---|
317 | fieldLabel: 'Name', |
---|
318 | itemCls: 'required' //this label will be styled |
---|
319 | },{ |
---|
320 | xtype: 'textfield', |
---|
321 | fieldLabel: 'Favorite Color' |
---|
322 | }] |
---|
323 | }); |
---|
324 | </code></pre> |
---|
325 | */ |
---|
326 | |
---|
327 | /** |
---|
328 | * @cfg {String} id |
---|
329 | * The unique id of this component (defaults to an auto-assigned id). You should assign an id if you need to |
---|
330 | * be able to access the component later and you do not have an object reference available (e.g., using |
---|
331 | * {@link Ext.ComponentMgr#getCmp}). Note that this id will also be used as the element id for the containing |
---|
332 | * HTML element that is rendered to the page for this component. This allows you to write id-based CSS rules to |
---|
333 | * style the specific instance of this component uniquely, and also to select sub-elements using this |
---|
334 | * component's id as the parent. |
---|
335 | */ |
---|
336 | /** |
---|
337 | * @cfg {String/Object} autoEl |
---|
338 | * A tag name or DomHelper spec to create an element with. This is intended to create shorthand |
---|
339 | * utility components inline via JSON. It should not be used for higher level components which already create |
---|
340 | * their own elements. Example usage: |
---|
341 | * <pre><code> |
---|
342 | {xtype:'box', autoEl: 'div', cls:'my-class'} |
---|
343 | {xtype:'box', autoEl: {tag:'blockquote', html:'autoEl is cool!'}} // with DomHelper |
---|
344 | </code></pre> |
---|
345 | */ |
---|
346 | /** |
---|
347 | * @cfg {String} xtype |
---|
348 | * The registered xtype to create. This config option is not used when passing |
---|
349 | * a config object into a constructor. This config option is used only when |
---|
350 | * lazy instantiation is being used, and a child item of a Container is being |
---|
351 | * specified not as a fully instantiated Component, but as a <i>Component config |
---|
352 | * object</i>. The xtype will be looked up at render time up to determine what |
---|
353 | * type of child Component to create.<br><br> |
---|
354 | * The predefined xtypes are listed {@link Ext.Component here}. |
---|
355 | * <br><br> |
---|
356 | * If you subclass Components to create your own Components, you may register |
---|
357 | * them using {@link Ext.ComponentMgr#registerType} in order to be able to |
---|
358 | * take advantage of lazy instantiation and rendering. |
---|
359 | */ |
---|
360 | /** |
---|
361 | * @cfg {String} cls |
---|
362 | * An optional extra CSS class that will be added to this component's Element (defaults to ''). This can be |
---|
363 | * useful for adding customized styles to the component or any of its children using standard CSS rules. |
---|
364 | */ |
---|
365 | /** |
---|
366 | * @cfg {String} overCls |
---|
367 | * An optional extra CSS class that will be added to this component's Element when the mouse moves |
---|
368 | * over the Element, and removed when the mouse moves out. (defaults to ''). This can be |
---|
369 | * useful for adding customized "active" or "hover" styles to the component or any of its children using standard CSS rules. |
---|
370 | */ |
---|
371 | /** |
---|
372 | * @cfg {String} style |
---|
373 | * A custom style specification to be applied to this component's Element. Should be a valid argument to |
---|
374 | * {@link Ext.Element#applyStyles}. |
---|
375 | */ |
---|
376 | /** |
---|
377 | * @cfg {String} ctCls |
---|
378 | * An optional extra CSS class that will be added to this component's container (defaults to ''). This can be |
---|
379 | * useful for adding customized styles to the container or any of its children using standard CSS rules. |
---|
380 | */ |
---|
381 | /** |
---|
382 | * @cfg {Boolean} disabled |
---|
383 | * Render this component disabled (default is false). |
---|
384 | */ |
---|
385 | /** |
---|
386 | * @cfg {Boolean} hidden |
---|
387 | * Render this component hidden (default is false). |
---|
388 | */ |
---|
389 | /** |
---|
390 | * @cfg {Object/Array} plugins |
---|
391 | * An object or array of objects that will provide custom functionality for this component. The only |
---|
392 | * requirement for a valid plugin is that it contain an init method that accepts a reference of type Ext.Component. |
---|
393 | * When a component is created, if any plugins are available, the component will call the init method on each |
---|
394 | * plugin, passing a reference to itself. Each plugin can then call methods or respond to events on the |
---|
395 | * component as needed to provide its functionality. |
---|
396 | */ |
---|
397 | /** |
---|
398 | * @cfg {Mixed} applyTo |
---|
399 | * The id of the node, a DOM node or an existing Element corresponding to a DIV that is already present in |
---|
400 | * the document that specifies some structural markup for this component. When applyTo is used, constituent parts of |
---|
401 | * the component can also be specified by id or CSS class name within the main element, and the component being created |
---|
402 | * may attempt to create its subcomponents from that markup if applicable. Using this config, a call to render() is |
---|
403 | * not required. If applyTo is specified, any value passed for {@link #renderTo} will be ignored and the target |
---|
404 | * element's parent node will automatically be used as the component's container. |
---|
405 | */ |
---|
406 | /** |
---|
407 | * @cfg {Mixed} renderTo |
---|
408 | * The id of the node, a DOM node or an existing Element that will be the container to render this component into. |
---|
409 | * Using this config, a call to render() is not required. |
---|
410 | */ |
---|
411 | |
---|
412 | /** |
---|
413 | * @cfg {Boolean} stateful |
---|
414 | * <p>A flag which causes the Component to attempt to restore the state of internal properties |
---|
415 | * from a saved state on startup. The component must have either a {@link #stateId} or {@link #id} |
---|
416 | * assigned for state to be managed. Auto-generated ids are not guaranteed to be stable across page |
---|
417 | * loads and cannot be relied upon to save and restore the same state for a component.<p> |
---|
418 | * For state saving to work, the state manager's provider must have been set to an implementation |
---|
419 | * of {@link Ext.state.Provider} which overrides the {@link Ext.state.Provider#set set} |
---|
420 | * and {@link Ext.state.Provider#get get} methods to save and recall name/value pairs. |
---|
421 | * A built-in implementation, {@link Ext.state.CookieProvider} is available.</p> |
---|
422 | * <p>To set the state provider for the current page:</p> |
---|
423 | * <pre><code> |
---|
424 | Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); |
---|
425 | </code></pre> |
---|
426 | * <p>Components attempt to save state when one of the events listed in the {@link #stateEvents} |
---|
427 | * configuration fires.</p> |
---|
428 | * <p>You can perform extra processing on state save and restore by attaching handlers to the |
---|
429 | * {@link #beforestaterestore}, {@link #staterestore}, {@link #beforestatesave} and {@link #statesave} events</p> |
---|
430 | */ |
---|
431 | /** |
---|
432 | * @cfg {String} stateId |
---|
433 | * The unique id for this component to use for state management purposes (defaults to the component id if one was |
---|
434 | * set, otherwise null if the component is using a generated id). |
---|
435 | * <p>See {@link #stateful} for an explanation of saving and restoring Component state.</p> |
---|
436 | */ |
---|
437 | /* //internal - to be set by subclasses |
---|
438 | * @cfg {Array} stateEvents |
---|
439 | * An array of events that, when fired, should trigger this component to save its state (defaults to none). |
---|
440 | * These can be any types of events supported by this component, including browser or custom events (e.g., |
---|
441 | * ['click', 'customerchange']). |
---|
442 | * <p>See {@link #stateful} for an explanation of saving and restoring Component state.</p> |
---|
443 | */ |
---|
444 | |
---|
445 | /** |
---|
446 | * @cfg {String} disabledClass |
---|
447 | * CSS class added to the component when it is disabled (defaults to "x-item-disabled"). |
---|
448 | */ |
---|
449 | disabledClass : "x-item-disabled", |
---|
450 | /** |
---|
451 | * @cfg {Boolean} allowDomMove |
---|
452 | * Whether the component can move the Dom node when rendering (defaults to true). |
---|
453 | */ |
---|
454 | allowDomMove : true, |
---|
455 | /** |
---|
456 | * @cfg {Boolean} autoShow |
---|
457 | * True if the component should check for hidden classes (e.g. 'x-hidden' or 'x-hide-display') and remove |
---|
458 | * them on render (defaults to false). |
---|
459 | */ |
---|
460 | autoShow : false, |
---|
461 | /** |
---|
462 | * @cfg {String} hideMode |
---|
463 | * <p>How this component should be hidden. Supported values are "visibility" (css visibility), "offsets" (negative |
---|
464 | * offset position) and "display" (css display) - defaults to "display".</p> |
---|
465 | * <p>For Containers which may be hidden and shown as part of a {@link Ext.layout.CardLayout card layout} Container such as a |
---|
466 | * {@link Ext.TabPanel TabPanel}, it is recommended that hideMode is configured as "offsets". This ensures |
---|
467 | * that hidden Components still have height and width so that layout managers can perform measurements when |
---|
468 | * calculating layouts.</p> |
---|
469 | */ |
---|
470 | hideMode: 'display', |
---|
471 | /** |
---|
472 | * @cfg {Boolean} hideParent |
---|
473 | * True to hide and show the component's container when hide/show is called on the component, false to hide |
---|
474 | * and show the component itself (defaults to false). For example, this can be used as a shortcut for a hide |
---|
475 | * button on a window by setting hide:true on the button when adding it to its parent container. |
---|
476 | */ |
---|
477 | hideParent: false, |
---|
478 | |
---|
479 | /** |
---|
480 | * The component's owner {@link Ext.Container} (defaults to undefined, and is set automatically when |
---|
481 | * the component is added to a container). Read-only. |
---|
482 | * @type Ext.Container |
---|
483 | * @property ownerCt |
---|
484 | */ |
---|
485 | /** |
---|
486 | * True if this component is hidden. Read-only. |
---|
487 | * @type Boolean |
---|
488 | * @property |
---|
489 | */ |
---|
490 | hidden : false, |
---|
491 | /** |
---|
492 | * True if this component is disabled. Read-only. |
---|
493 | * @type Boolean |
---|
494 | * @property |
---|
495 | */ |
---|
496 | disabled : false, |
---|
497 | /** |
---|
498 | * True if this component has been rendered. Read-only. |
---|
499 | * @type Boolean |
---|
500 | * @property |
---|
501 | */ |
---|
502 | rendered : false, |
---|
503 | |
---|
504 | // private |
---|
505 | ctype : "Ext.Component", |
---|
506 | |
---|
507 | // private |
---|
508 | actionMode : "el", |
---|
509 | |
---|
510 | // private |
---|
511 | getActionEl : function(){ |
---|
512 | return this[this.actionMode]; |
---|
513 | }, |
---|
514 | |
---|
515 | initPlugin : function(p){ |
---|
516 | p.init(this); |
---|
517 | return p; |
---|
518 | }, |
---|
519 | |
---|
520 | /* // protected |
---|
521 | * Function to be implemented by Component subclasses to be part of standard component initialization flow (it is empty by default). |
---|
522 | * <pre><code> |
---|
523 | // Traditional constructor: |
---|
524 | Ext.Foo = function(config){ |
---|
525 | // call superclass constructor: |
---|
526 | Ext.Foo.superclass.constructor.call(this, config); |
---|
527 | |
---|
528 | this.addEvents({ |
---|
529 | // add events |
---|
530 | }); |
---|
531 | }; |
---|
532 | Ext.extend(Ext.Foo, Ext.Bar, { |
---|
533 | // class body |
---|
534 | } |
---|
535 | |
---|
536 | // initComponent replaces the constructor: |
---|
537 | Ext.Foo = Ext.extend(Ext.Bar, { |
---|
538 | initComponent : function(){ |
---|
539 | // call superclass initComponent |
---|
540 | Ext.Container.superclass.initComponent.call(this); |
---|
541 | |
---|
542 | this.addEvents({ |
---|
543 | // add events |
---|
544 | }); |
---|
545 | } |
---|
546 | } |
---|
547 | </code></pre> |
---|
548 | */ |
---|
549 | initComponent : Ext.emptyFn, |
---|
550 | |
---|
551 | /** |
---|
552 | * <p>Render this Component into the passed HTML element.</p> |
---|
553 | * <p><b>If you are using a {@link Ext.Container Container} object to house this Component, then |
---|
554 | * do not use the render method.</b></p> |
---|
555 | * <p>A Container's child Components are rendered by that Container's |
---|
556 | * {@link Ext.Container#layout layout} manager when the Container is first rendered.</p> |
---|
557 | * <p>Certain layout managers allow dynamic addition of child components. Those that do |
---|
558 | * include {@link Ext.layout.CardLayout}, {@link Ext.layout.AnchorLayout}, |
---|
559 | * {@link Ext.layout.FormLayout}, {@link Ext.layout.TableLayout}.</p> |
---|
560 | * <p>If the Container is already rendered when a new child Component is added, you may need to call |
---|
561 | * the Container's {@link Ext.Container#doLayout doLayout} to refresh the view which causes any |
---|
562 | * unrendered child Components to be rendered. This is required so that you can add multiple |
---|
563 | * child components if needed while only refreshing the layout once.</p> |
---|
564 | * <p>When creating complex UIs, it is important to remember that sizing and positioning |
---|
565 | * of child items is the responsibility of the Container's {@link Ext.Container#layout layout} manager. |
---|
566 | * If you expect child items to be sized in response to user interactions, you must |
---|
567 | * configure the Container with a layout manager which creates and manages the type of layout you |
---|
568 | * have in mind.</p> |
---|
569 | * <p><b>Omitting the Container's {@link Ext.Container#layout layout} config means that a basic |
---|
570 | * layout manager is used which does nothing but render child components sequentially into the |
---|
571 | * Container. No sizing or positioning will be performed in this situation.</b></p> |
---|
572 | * @param {Element/HTMLElement/String} container (optional) The element this Component should be |
---|
573 | * rendered into. If it is being created from existing markup, this should be omitted. |
---|
574 | * @param {String/Number} position (optional) The element ID or DOM node index within the container <b>before</b> |
---|
575 | * which this component will be inserted (defaults to appending to the end of the container) |
---|
576 | */ |
---|
577 | render : function(container, position){ |
---|
578 | if(!this.rendered && this.fireEvent("beforerender", this) !== false){ |
---|
579 | if(!container && this.el){ |
---|
580 | this.el = Ext.get(this.el); |
---|
581 | container = this.el.dom.parentNode; |
---|
582 | this.allowDomMove = false; |
---|
583 | } |
---|
584 | this.container = Ext.get(container); |
---|
585 | if(this.ctCls){ |
---|
586 | this.container.addClass(this.ctCls); |
---|
587 | } |
---|
588 | this.rendered = true; |
---|
589 | if(position !== undefined){ |
---|
590 | if(typeof position == 'number'){ |
---|
591 | position = this.container.dom.childNodes[position]; |
---|
592 | }else{ |
---|
593 | position = Ext.getDom(position); |
---|
594 | } |
---|
595 | } |
---|
596 | this.onRender(this.container, position || null); |
---|
597 | if(this.autoShow){ |
---|
598 | this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]); |
---|
599 | } |
---|
600 | if(this.cls){ |
---|
601 | this.el.addClass(this.cls); |
---|
602 | delete this.cls; |
---|
603 | } |
---|
604 | if(this.style){ |
---|
605 | this.el.applyStyles(this.style); |
---|
606 | delete this.style; |
---|
607 | } |
---|
608 | if(this.overCls){ |
---|
609 | this.el.addClassOnOver(this.overCls); |
---|
610 | } |
---|
611 | this.fireEvent("render", this); |
---|
612 | this.afterRender(this.container); |
---|
613 | if(this.hidden){ |
---|
614 | this.hide(); |
---|
615 | } |
---|
616 | if(this.disabled){ |
---|
617 | this.disable(); |
---|
618 | } |
---|
619 | |
---|
620 | if(this.stateful !== false){ |
---|
621 | this.initStateEvents(); |
---|
622 | } |
---|
623 | } |
---|
624 | return this; |
---|
625 | }, |
---|
626 | |
---|
627 | // private |
---|
628 | initState : function(config){ |
---|
629 | if(Ext.state.Manager){ |
---|
630 | var id = this.getStateId(); |
---|
631 | if(id){ |
---|
632 | var state = Ext.state.Manager.get(id); |
---|
633 | if(state){ |
---|
634 | if(this.fireEvent('beforestaterestore', this, state) !== false){ |
---|
635 | this.applyState(state); |
---|
636 | this.fireEvent('staterestore', this, state); |
---|
637 | } |
---|
638 | } |
---|
639 | } |
---|
640 | } |
---|
641 | }, |
---|
642 | |
---|
643 | // private |
---|
644 | getStateId : function(){ |
---|
645 | return this.stateId || ((this.id.indexOf('ext-comp-') == 0 || this.id.indexOf('ext-gen') == 0) ? null : this.id); |
---|
646 | }, |
---|
647 | |
---|
648 | // private |
---|
649 | initStateEvents : function(){ |
---|
650 | if(this.stateEvents){ |
---|
651 | for(var i = 0, e; e = this.stateEvents[i]; i++){ |
---|
652 | this.on(e, this.saveState, this, {delay:100}); |
---|
653 | } |
---|
654 | } |
---|
655 | }, |
---|
656 | |
---|
657 | // private |
---|
658 | applyState : function(state, config){ |
---|
659 | if(state){ |
---|
660 | Ext.apply(this, state); |
---|
661 | } |
---|
662 | }, |
---|
663 | |
---|
664 | // private |
---|
665 | getState : function(){ |
---|
666 | return null; |
---|
667 | }, |
---|
668 | |
---|
669 | // private |
---|
670 | saveState : function(){ |
---|
671 | if(Ext.state.Manager){ |
---|
672 | var id = this.getStateId(); |
---|
673 | if(id){ |
---|
674 | var state = this.getState(); |
---|
675 | if(this.fireEvent('beforestatesave', this, state) !== false){ |
---|
676 | Ext.state.Manager.set(id, state); |
---|
677 | this.fireEvent('statesave', this, state); |
---|
678 | } |
---|
679 | } |
---|
680 | } |
---|
681 | }, |
---|
682 | |
---|
683 | /** |
---|
684 | * Apply this component to existing markup that is valid. With this function, no call to render() is required. |
---|
685 | * @param {String/HTMLElement} el |
---|
686 | */ |
---|
687 | applyToMarkup : function(el){ |
---|
688 | this.allowDomMove = false; |
---|
689 | this.el = Ext.get(el); |
---|
690 | this.render(this.el.dom.parentNode); |
---|
691 | }, |
---|
692 | |
---|
693 | /** |
---|
694 | * Adds a CSS class to the component's underlying element. |
---|
695 | * @param {string} cls The CSS class name to add |
---|
696 | */ |
---|
697 | addClass : function(cls){ |
---|
698 | if(this.el){ |
---|
699 | this.el.addClass(cls); |
---|
700 | }else{ |
---|
701 | this.cls = this.cls ? this.cls + ' ' + cls : cls; |
---|
702 | } |
---|
703 | }, |
---|
704 | |
---|
705 | /** |
---|
706 | * Removes a CSS class from the component's underlying element. |
---|
707 | * @param {string} cls The CSS class name to remove |
---|
708 | */ |
---|
709 | removeClass : function(cls){ |
---|
710 | if(this.el){ |
---|
711 | this.el.removeClass(cls); |
---|
712 | }else if(this.cls){ |
---|
713 | this.cls = this.cls.split(' ').remove(cls).join(' '); |
---|
714 | } |
---|
715 | }, |
---|
716 | |
---|
717 | // private |
---|
718 | // default function is not really useful |
---|
719 | onRender : function(ct, position){ |
---|
720 | if(this.autoEl){ |
---|
721 | if(typeof this.autoEl == 'string'){ |
---|
722 | this.el = document.createElement(this.autoEl); |
---|
723 | }else{ |
---|
724 | var div = document.createElement('div'); |
---|
725 | Ext.DomHelper.overwrite(div, this.autoEl); |
---|
726 | this.el = div.firstChild; |
---|
727 | } |
---|
728 | if (!this.el.id) { |
---|
729 | this.el.id = this.getId(); |
---|
730 | } |
---|
731 | } |
---|
732 | if(this.el){ |
---|
733 | this.el = Ext.get(this.el); |
---|
734 | if(this.allowDomMove !== false){ |
---|
735 | ct.dom.insertBefore(this.el.dom, position); |
---|
736 | } |
---|
737 | } |
---|
738 | }, |
---|
739 | |
---|
740 | // private |
---|
741 | getAutoCreate : function(){ |
---|
742 | var cfg = typeof this.autoCreate == "object" ? |
---|
743 | this.autoCreate : Ext.apply({}, this.defaultAutoCreate); |
---|
744 | if(this.id && !cfg.id){ |
---|
745 | cfg.id = this.id; |
---|
746 | } |
---|
747 | return cfg; |
---|
748 | }, |
---|
749 | |
---|
750 | // private |
---|
751 | afterRender : Ext.emptyFn, |
---|
752 | |
---|
753 | /** |
---|
754 | * Destroys this component by purging any event listeners, removing the component's element from the DOM, |
---|
755 | * removing the component from its {@link Ext.Container} (if applicable) and unregistering it from |
---|
756 | * {@link Ext.ComponentMgr}. Destruction is generally handled automatically by the framework and this method |
---|
757 | * should usually not need to be called directly. |
---|
758 | */ |
---|
759 | destroy : function(){ |
---|
760 | if(this.fireEvent("beforedestroy", this) !== false){ |
---|
761 | this.beforeDestroy(); |
---|
762 | if(this.rendered){ |
---|
763 | this.el.removeAllListeners(); |
---|
764 | this.el.remove(); |
---|
765 | if(this.actionMode == "container"){ |
---|
766 | this.container.remove(); |
---|
767 | } |
---|
768 | } |
---|
769 | this.onDestroy(); |
---|
770 | Ext.ComponentMgr.unregister(this); |
---|
771 | this.fireEvent("destroy", this); |
---|
772 | this.purgeListeners(); |
---|
773 | } |
---|
774 | }, |
---|
775 | |
---|
776 | // private |
---|
777 | beforeDestroy : Ext.emptyFn, |
---|
778 | |
---|
779 | // private |
---|
780 | onDestroy : Ext.emptyFn, |
---|
781 | |
---|
782 | /** |
---|
783 | * Returns the underlying {@link Ext.Element}. |
---|
784 | * @return {Ext.Element} The element |
---|
785 | */ |
---|
786 | getEl : function(){ |
---|
787 | return this.el; |
---|
788 | }, |
---|
789 | |
---|
790 | /** |
---|
791 | * Returns the id of this component. |
---|
792 | * @return {String} |
---|
793 | */ |
---|
794 | getId : function(){ |
---|
795 | return this.id || (this.id = "ext-comp-" + (++Ext.Component.AUTO_ID)); |
---|
796 | }, |
---|
797 | |
---|
798 | /** |
---|
799 | * Returns the item id of this component. |
---|
800 | * @return {String} |
---|
801 | */ |
---|
802 | getItemId : function(){ |
---|
803 | return this.itemId || this.getId(); |
---|
804 | }, |
---|
805 | |
---|
806 | /** |
---|
807 | * Try to focus this component. |
---|
808 | * @param {Boolean} selectText (optional) If applicable, true to also select the text in this component |
---|
809 | * @param {Boolean/Number} delay (optional) Delay the focus this number of milliseconds (true for 10 milliseconds) |
---|
810 | * @return {Ext.Component} this |
---|
811 | */ |
---|
812 | focus : function(selectText, delay){ |
---|
813 | if(delay){ |
---|
814 | this.focus.defer(typeof delay == 'number' ? delay : 10, this, [selectText, false]); |
---|
815 | return; |
---|
816 | } |
---|
817 | if(this.rendered){ |
---|
818 | this.el.focus(); |
---|
819 | if(selectText === true){ |
---|
820 | this.el.dom.select(); |
---|
821 | } |
---|
822 | } |
---|
823 | return this; |
---|
824 | }, |
---|
825 | |
---|
826 | // private |
---|
827 | blur : function(){ |
---|
828 | if(this.rendered){ |
---|
829 | this.el.blur(); |
---|
830 | } |
---|
831 | return this; |
---|
832 | }, |
---|
833 | |
---|
834 | /** |
---|
835 | * Disable this component. |
---|
836 | * @return {Ext.Component} this |
---|
837 | */ |
---|
838 | disable : function(){ |
---|
839 | if(this.rendered){ |
---|
840 | this.onDisable(); |
---|
841 | } |
---|
842 | this.disabled = true; |
---|
843 | this.fireEvent("disable", this); |
---|
844 | return this; |
---|
845 | }, |
---|
846 | |
---|
847 | // private |
---|
848 | onDisable : function(){ |
---|
849 | this.getActionEl().addClass(this.disabledClass); |
---|
850 | this.el.dom.disabled = true; |
---|
851 | }, |
---|
852 | |
---|
853 | /** |
---|
854 | * Enable this component. |
---|
855 | * @return {Ext.Component} this |
---|
856 | */ |
---|
857 | enable : function(){ |
---|
858 | if(this.rendered){ |
---|
859 | this.onEnable(); |
---|
860 | } |
---|
861 | this.disabled = false; |
---|
862 | this.fireEvent("enable", this); |
---|
863 | return this; |
---|
864 | }, |
---|
865 | |
---|
866 | // private |
---|
867 | onEnable : function(){ |
---|
868 | this.getActionEl().removeClass(this.disabledClass); |
---|
869 | this.el.dom.disabled = false; |
---|
870 | }, |
---|
871 | |
---|
872 | /** |
---|
873 | * Convenience function for setting disabled/enabled by boolean. |
---|
874 | * @param {Boolean} disabled |
---|
875 | */ |
---|
876 | setDisabled : function(disabled){ |
---|
877 | this[disabled ? "disable" : "enable"](); |
---|
878 | }, |
---|
879 | |
---|
880 | /** |
---|
881 | * Show this component. |
---|
882 | * @return {Ext.Component} this |
---|
883 | */ |
---|
884 | show: function(){ |
---|
885 | if(this.fireEvent("beforeshow", this) !== false){ |
---|
886 | this.hidden = false; |
---|
887 | if(this.autoRender){ |
---|
888 | this.render(typeof this.autoRender == 'boolean' ? Ext.getBody() : this.autoRender); |
---|
889 | } |
---|
890 | if(this.rendered){ |
---|
891 | this.onShow(); |
---|
892 | } |
---|
893 | this.fireEvent("show", this); |
---|
894 | } |
---|
895 | return this; |
---|
896 | }, |
---|
897 | |
---|
898 | // private |
---|
899 | onShow : function(){ |
---|
900 | if(this.hideParent){ |
---|
901 | this.container.removeClass('x-hide-' + this.hideMode); |
---|
902 | }else{ |
---|
903 | this.getActionEl().removeClass('x-hide-' + this.hideMode); |
---|
904 | } |
---|
905 | |
---|
906 | }, |
---|
907 | |
---|
908 | /** |
---|
909 | * Hide this component. |
---|
910 | * @return {Ext.Component} this |
---|
911 | */ |
---|
912 | hide: function(){ |
---|
913 | if(this.fireEvent("beforehide", this) !== false){ |
---|
914 | this.hidden = true; |
---|
915 | if(this.rendered){ |
---|
916 | this.onHide(); |
---|
917 | } |
---|
918 | this.fireEvent("hide", this); |
---|
919 | } |
---|
920 | return this; |
---|
921 | }, |
---|
922 | |
---|
923 | // private |
---|
924 | onHide : function(){ |
---|
925 | if(this.hideParent){ |
---|
926 | this.container.addClass('x-hide-' + this.hideMode); |
---|
927 | }else{ |
---|
928 | this.getActionEl().addClass('x-hide-' + this.hideMode); |
---|
929 | } |
---|
930 | }, |
---|
931 | |
---|
932 | /** |
---|
933 | * Convenience function to hide or show this component by boolean. |
---|
934 | * @param {Boolean} visible True to show, false to hide |
---|
935 | * @return {Ext.Component} this |
---|
936 | */ |
---|
937 | setVisible: function(visible){ |
---|
938 | if(visible) { |
---|
939 | this.show(); |
---|
940 | }else{ |
---|
941 | this.hide(); |
---|
942 | } |
---|
943 | return this; |
---|
944 | }, |
---|
945 | |
---|
946 | /** |
---|
947 | * Returns true if this component is visible. |
---|
948 | */ |
---|
949 | isVisible : function(){ |
---|
950 | return this.rendered && this.getActionEl().isVisible(); |
---|
951 | }, |
---|
952 | |
---|
953 | /** |
---|
954 | * Clone the current component using the original config values passed into this instance by default. |
---|
955 | * @param {Object} overrides A new config containing any properties to override in the cloned version. |
---|
956 | * An id property can be passed on this object, otherwise one will be generated to avoid duplicates. |
---|
957 | * @return {Ext.Component} clone The cloned copy of this component |
---|
958 | */ |
---|
959 | cloneConfig : function(overrides){ |
---|
960 | overrides = overrides || {}; |
---|
961 | var id = overrides.id || Ext.id(); |
---|
962 | var cfg = Ext.applyIf(overrides, this.initialConfig); |
---|
963 | cfg.id = id; // prevent dup id |
---|
964 | return new this.constructor(cfg); |
---|
965 | }, |
---|
966 | |
---|
967 | /** |
---|
968 | * Gets the xtype for this component as registered with {@link Ext.ComponentMgr}. For a list of all |
---|
969 | * available xtypes, see the {@link Ext.Component} header. Example usage: |
---|
970 | * <pre><code> |
---|
971 | var t = new Ext.form.TextField(); |
---|
972 | alert(t.getXType()); // alerts 'textfield' |
---|
973 | </code></pre> |
---|
974 | * @return {String} The xtype |
---|
975 | */ |
---|
976 | getXType : function(){ |
---|
977 | return this.constructor.xtype; |
---|
978 | }, |
---|
979 | |
---|
980 | /** |
---|
981 | * <p>Tests whether or not this Component is of a specific xtype. This can test whether this Component is descended |
---|
982 | * from the xtype (default) or whether it is directly of the xtype specified (shallow = true).</p> |
---|
983 | * <p><b>If using your own subclasses, be aware that a Component must register its own xtype |
---|
984 | * to participate in determination of inherited xtypes.</b></p> |
---|
985 | * <p>For a list of all available xtypes, see the {@link Ext.Component} header.</p> |
---|
986 | * <p>Example usage:</p> |
---|
987 | * <pre><code> |
---|
988 | var t = new Ext.form.TextField(); |
---|
989 | var isText = t.isXType('textfield'); // true |
---|
990 | var isBoxSubclass = t.isXType('box'); // true, descended from BoxComponent |
---|
991 | var isBoxInstance = t.isXType('box', true); // false, not a direct BoxComponent instance |
---|
992 | </code></pre> |
---|
993 | * @param {String} xtype The xtype to check for this Component |
---|
994 | * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is |
---|
995 | * the default), or true to check whether this Component is directly of the specified xtype. |
---|
996 | */ |
---|
997 | isXType : function(xtype, shallow){ |
---|
998 | //assume a string by default |
---|
999 | if (typeof xtype == 'function'){ |
---|
1000 | xtype = xtype.xtype; //handle being passed the class, eg. Ext.Component |
---|
1001 | }else if (typeof xtype == 'object'){ |
---|
1002 | xtype = xtype.constructor.xtype; //handle being passed an instance |
---|
1003 | } |
---|
1004 | |
---|
1005 | return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype; |
---|
1006 | }, |
---|
1007 | |
---|
1008 | /** |
---|
1009 | * <p>Returns this Component's xtype hierarchy as a slash-delimited string. For a list of all |
---|
1010 | * available xtypes, see the {@link Ext.Component} header.</p> |
---|
1011 | * <p><b>If using your own subclasses, be aware that a Component must register its own xtype |
---|
1012 | * to participate in determination of inherited xtypes.</b></p> |
---|
1013 | * <p>Example usage:</p> |
---|
1014 | * <pre><code> |
---|
1015 | var t = new Ext.form.TextField(); |
---|
1016 | alert(t.getXTypes()); // alerts 'component/box/field/textfield' |
---|
1017 | </pre></code> |
---|
1018 | * @return {String} The xtype hierarchy string |
---|
1019 | */ |
---|
1020 | getXTypes : function(){ |
---|
1021 | var tc = this.constructor; |
---|
1022 | if(!tc.xtypes){ |
---|
1023 | var c = [], sc = this; |
---|
1024 | while(sc && sc.constructor.xtype){ |
---|
1025 | c.unshift(sc.constructor.xtype); |
---|
1026 | sc = sc.constructor.superclass; |
---|
1027 | } |
---|
1028 | tc.xtypeChain = c; |
---|
1029 | tc.xtypes = c.join('/'); |
---|
1030 | } |
---|
1031 | return tc.xtypes; |
---|
1032 | }, |
---|
1033 | |
---|
1034 | /** |
---|
1035 | * Find a container above this component at any level by a custom function. If the passed function returns |
---|
1036 | * true, the container will be returned. The passed function is called with the arguments (container, this component). |
---|
1037 | * @param {Function} fcn |
---|
1038 | * @param {Object} scope (optional) |
---|
1039 | * @return {Ext.Container} The first Container for which the custom function returns true |
---|
1040 | */ |
---|
1041 | findParentBy: function(fn) { |
---|
1042 | for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt); |
---|
1043 | return p || null; |
---|
1044 | }, |
---|
1045 | |
---|
1046 | /** |
---|
1047 | * Find a container above this component at any level by xtype or class |
---|
1048 | * @param {String/Class} xtype The xtype string for a component, or the class of the component directly |
---|
1049 | * @return {Ext.Container} The first Container which matches the given xtype or class |
---|
1050 | */ |
---|
1051 | findParentByType: function(xtype) { |
---|
1052 | return typeof xtype == 'function' ? |
---|
1053 | this.findParentBy(function(p){ |
---|
1054 | return p.constructor === xtype; |
---|
1055 | }) : |
---|
1056 | this.findParentBy(function(p){ |
---|
1057 | return p.constructor.xtype === xtype; |
---|
1058 | }); |
---|
1059 | }, |
---|
1060 | |
---|
1061 | // internal function for auto removal of assigned event handlers on destruction |
---|
1062 | mon : function(item, ename, fn, scope, opt){ |
---|
1063 | if(!this.mons){ |
---|
1064 | this.mons = []; |
---|
1065 | this.on('beforedestroy', function(){ |
---|
1066 | for(var i= 0, len = this.mons.length; i < len; i++){ |
---|
1067 | var m = this.mons[i]; |
---|
1068 | m.item.un(m.ename, m.fn, m.scope); |
---|
1069 | } |
---|
1070 | }, this); |
---|
1071 | } |
---|
1072 | this.mons.push({ |
---|
1073 | item: item, ename: ename, fn: fn, scope: scope |
---|
1074 | }); |
---|
1075 | item.on(ename, fn, scope, opt); |
---|
1076 | } |
---|
1077 | }); |
---|
1078 | |
---|
1079 | Ext.reg('component', Ext.Component); |
---|