Component.js
/**
* @class Ext.ComponentMgr
* Provides a common registry of all components on a page so that they can be easily accessed by component id (see {@link Ext.getCmp}).
* @singleton
*/
Ext.ComponentMgr = function(){
var all = new Ext.util.MixedCollection();
return {
/**
* Registers a component.
* @param {Ext.Component} c The component
*/
register : function(c){
all.add(c);
},
/**
* Unregisters a component.
* @param {Ext.Component} c The component
*/
unregister : function(c){
all.remove(c);
},
/**
* Returns a component by id
* @param {String} id The component id
*/
get : function(id){
return all.get(id);
},
/**
* Registers a function that will be called when a specified component is added to ComponentMgr
* @param {String} id The component id
* @param {Funtction} fn The callback function
* @param {Object} scope The scope of the callback
*/
onAvailable : function(id, fn, scope){
all.on("add", function(index, o){
if(o.id == id){
fn.call(scope || o, o);
all.un("add", fn, scope);
}
});
}
};
}();
/**
* @class Ext.Component
* @extends Ext.util.Observable
* Base class for all major Ext components. All subclasses of Component can automatically participate in the standard
* Ext component lifecycle of creation, rendering and destruction. They also have automatic support for basic hide/show
* and enable/disable behavior. Component allows any subclass to be lazy-rendered into any {@link Ext.Container} and
* to be automatically registered with the {@link Ext.ComponentMgr} so that it can be referenced at any time via {@link Ext.getCmp}.
* All visual components (widgets) that require rendering into a layout should subclass Component.
* @constructor
* @param {Ext.Element/String/Object} config The configuration options. If an element is passed, it is set as the internal
* 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
* and is used as the component id. Otherwise, it is assumed to be a standard config object and is applied to the component.
*/
Ext.Component = function(config){
config = config || {};
if(config.tagName || config.dom || typeof config == "string"){ // element object
config = {el: config, id: config.id || config};
}
this.initialConfig = config;
Ext.apply(this, config);
this.addEvents({
/**
* @event disable
* Fires after the component is disabled.
* @param {Ext.Component} this
*/
disable : true,
/**
* @event enable
* Fires after the component is enabled.
* @param {Ext.Component} this
*/
enable : true,
/**
* @event beforeshow
* Fires before the component is shown. Return false to stop the show.
* @param {Ext.Component} this
*/
beforeshow : true,
/**
* @event show
* Fires after the component is shown.
* @param {Ext.Component} this
*/
show : true,
/**
* @event beforehide
* Fires before the component is hidden. Return false to stop the hide.
* @param {Ext.Component} this
*/
beforehide : true,
/**
* @event hide
* Fires after the component is hidden.
* @param {Ext.Component} this
*/
hide : true,
/**
* @event beforerender
* Fires before the component is rendered. Return false to stop the render.
* @param {Ext.Component} this
*/
beforerender : true,
/**
* @event render
* Fires after the component is rendered.
* @param {Ext.Component} this
*/
render : true,
/**
* @event beforedestroy
* Fires before the component is destroyed. Return false to stop the destroy.
* @param {Ext.Component} this
*/
beforedestroy : true,
/**
* @event destroy
* Fires after the component is destroyed.
* @param {Ext.Component} this
*/
destroy : true
});
if(!this.id){
this.id = "ext-comp-" + (++Ext.Component.AUTO_ID);
}
Ext.ComponentMgr.register(this);
Ext.Component.superclass.constructor.call(this);
this.initComponent();
if(this.renderTo){ // not supported by all components yet. use at your own risk!
this.render(this.renderTo);
delete this.renderTo;
}
};
// private
Ext.Component.AUTO_ID = 1000;
Ext.extend(Ext.Component, Ext.util.Observable, {
/**
* true if this component is hidden. Read-only.
*/
hidden : false,
/**
* true if this component is disabled. Read-only.
*/
disabled : false,
/**
* true if this component has been rendered. Read-only.
*/
rendered : false,
/** @cfg {String} disableClass
* CSS class added to the component when it is disabled (defaults to "x-item-disabled").
*/
disabledClass : "x-item-disabled",
/** @cfg {Boolean} allowDomMove
* Whether the component can move the Dom node when rendering (defaults to true).
*/
allowDomMove : true,
/** @cfg {String} hideMode
* How this component should hidden. Supported values are
* "visibility" (css visibility), "offsets" (negative offset position) and
* "display" (css display) - defaults to "display".
*/
hideMode: 'display',
// private
ctype : "Ext.Component",
// private
actionMode : "el",
// private
getActionEl : function(){
return this[this.actionMode];
},
initComponent : Ext.emptyFn,
/**
* If this is a lazy rendering component, render it to its container element.
* @param {String/HTMLElement/Element} container (optional) The element this component should be rendered into. If it is being applied to existing markup, this should be left off.
*/
render : function(container, position){
if(!this.rendered && this.fireEvent("beforerender", this) !== false){
if(!container && this.el){
this.el = Ext.get(this.el);
container = this.el.dom.parentNode;
this.allowDomMove = false;
}
this.container = Ext.get(container);
this.rendered = true;
if(position !== undefined){
if(typeof position == 'number'){
position = this.container.dom.childNodes[position];
}else{
position = Ext.getDom(position);
}
}
this.onRender(this.container, position || null);
if(this.cls){
this.el.addClass(this.cls);
delete this.cls;
}
if(this.style){
this.el.applyStyles(this.style);
delete this.style;
}
this.fireEvent("render", this);
this.afterRender(this.container);
if(this.hidden){
this.hide();
}
if(this.disabled){
this.disable();
}
}
return this;
},
// private
// default function is not really useful
onRender : function(ct, position){
if(this.el){
this.el = Ext.get(this.el);
if(this.allowDomMove !== false){
ct.dom.insertBefore(this.el.dom, position);
}
}
},
// private
getAutoCreate : function(){
var cfg = typeof this.autoCreate == "object" ?
this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
if(this.id && !cfg.id){
cfg.id = this.id;
}
return cfg;
},
// private
afterRender : Ext.emptyFn,
/**
* Destroys this component by purging any event listeners, removing the component's element from the DOM,
* removing the component from its {@link Ext.Container} (if applicable) and unregistering it from {@link Ext.ComponentMgr}.
*/
destroy : function(){
if(this.fireEvent("beforedestroy", this) !== false){
this.purgeListeners();
this.beforeDestroy();
if(this.rendered){
this.el.removeAllListeners();
this.el.remove();
if(this.actionMode == "container"){
this.container.remove();
}
}
this.onDestroy();
Ext.ComponentMgr.unregister(this);
this.fireEvent("destroy", this);
}
},
// private
beforeDestroy : function(){
},
// private
onDestroy : function(){
},
/**
* Returns the underlying {@link Ext.Element}.
* @return {Ext.Element} The element
*/
getEl : function(){
return this.el;
},
/**
* Returns the id of this component.
* @return {String}
*/
getId : function(){
return this.id;
},
/**
* Try to focus this component.
* @param {Boolean} selectText True to also select the text in this component (if applicable)
* @return {Ext.Component} this
*/
focus : function(selectText){
if(this.rendered){
this.el.focus();
if(selectText === true){
this.el.dom.select();
}
}
return this;
},
// private
blur : function(){
if(this.rendered){
this.el.blur();
}
return this;
},
/**
* Disable this component.
* @return {Ext.Component} this
*/
disable : function(){
if(this.rendered){
this.onDisable();
}
this.disabled = true;
this.fireEvent("disable", this);
return this;
},
// private
onDisable : function(){
this.getActionEl().addClass(this.disabledClass);
this.el.dom.disabled = true;
},
/**
* Enable this component.
* @return {Ext.Component} this
*/
enable : function(){
if(this.rendered){
this.onEnable();
}
this.disabled = false;
this.fireEvent("enable", this);
return this;
},
// private
onEnable : function(){
this.getActionEl().removeClass(this.disabledClass);
this.el.dom.disabled = false;
},
/**
* Convenience function for setting disabled/enabled by boolean.
* @param {Boolean} disabled
*/
setDisabled : function(disabled){
this[disabled ? "disable" : "enable"]();
},
/**
* Show this component.
* @return {Ext.Component} this
*/
show: function(){
if(this.fireEvent("beforeshow", this) !== false){
this.hidden = false;
if(this.rendered){
this.onShow();
}
this.fireEvent("show", this);
}
return this;
},
// private
onShow : function(){
var ae = this.getActionEl();
if(this.hideMode == 'visibility'){
ae.dom.style.visibility = "visible";
}else if(this.hideMode == 'offsets'){
ae.removeClass('x-hidden');
}else{
ae.dom.style.display = "";
}
},
/**
* Hide this component.
* @return {Ext.Component} this
*/
hide: function(){
if(this.fireEvent("beforehide", this) !== false){
this.hidden = true;
if(this.rendered){
this.onHide();
}
this.fireEvent("hide", this);
}
return this;
},
// private
onHide : function(){
var ae = this.getActionEl();
if(this.hideMode == 'visibility'){
ae.dom.style.visibility = "hidden";
}else if(this.hideMode == 'offsets'){
ae.addClass('x-hidden');
}else{
ae.dom.style.display = "none";
}
},
/**
* Convenience function to hide or show this component by boolean.
* @param {Boolean} visible True to show, false to hide
* @return {Ext.Component} this
*/
setVisible: function(visible){
if(visible) {
this.show();
}else{
this.hide();
}
return this;
},
/**
* Returns true if this component is visible.
*/
isVisible : function(){
return this.getActionEl().isVisible();
},
cloneConfig : function(overrides){
overrides = overrides || {};
var id = overrides.id || Ext.id();
var cfg = Ext.applyIf(overrides, this.initialConfig);
cfg.id = id; // prevent dup id
return new this.constructor(cfg);
}
});
Ext - Copyright © 2006-2007 Ext JS, LLC
All rights reserved.