Adding Features to Ext JS

     Get Ext JS to do your bidding
Options



          ● Extend
          ● Override
          ● Plugin
          ● Sequence/Intercept
Extending

New component based on another

Inherits functionality

Somewhat lightweight (well come back to this)
Four step process
Basic Extending

Pick a class to start from (well come back to this)
CustomPanel = Ext.extend(Ext.Panel, {
    initComponent : function() {
       Ext.apply(this, { title: 'My Custom Panel' });
       CustomPanel.superclass.initComponent.call(this);
    },
    newMethod: function() {},
    overriddenMethod: function() {}
});

Ext.reg('custompanel', CustomPanel);
Basic Extending

Configure it with initComponent (well come back to this)
CustomPanel = Ext.extend(Ext.Panel, {
    initComponent : function() {
       Ext.apply(this, { title: 'My Custom Panel' });
       CustomPanel.superclass.initComponent.call(this);
    },
    newMethod: function() {},
    overriddenMethod: function() {}
});

Ext.reg('custompanel', CustomPanel);
Basic Extending

Add your own methods (or override existing)
CustomPanel = Ext.extend(Ext.Panel, {
    initComponent : function() {
       Ext.apply(this, { title: 'My Custom Panel' });
       CustomPanel.superclass.initComponent.call(this);
    },
    newMethod: function() {},
    overriddenMethod: function() {}
});

Ext.reg('custompanel', CustomPanel);
Basic Extending

Register it (for use as an xtype)
CustomPanel = Ext.extend(Ext.Panel, {
    initComponent : function() {
       Ext.apply(this, { title: 'My Custom Panel' });
       CustomPanel.superclass.initComponent.call(this);
    },
    newMethod: function() {},
    overriddenMethod: function() {
        CustomPanel.superclass.overriddenMethod.call(this);
    }
});

Ext.reg('custompanel', CustomPanel);
Basic Extending

Party (like it's 1999)

var myPanel = new CustomPanel({border: true});


...items: [{ xtype: 'custompanel', border: true }]
Extend From...

Classes that only need events should extend Ext.util.Observable

Classes that will serve as UI widgets should extend Ext.Component

Use Ext.BoxComponent if simple layout management will be necessary

Classes that can contain other components should extend Ext.Container

Classes that require a title bar, toolbar or other advanced display features should
extend Ext.Panel

Look at the docs to see the inheritance chain for classes (upper right corner)
How much overhead does extending add?
Overhead


Only as much code as you add
CustomPanel = Ext.extend(Ext.Panel, {
    initComponent : function() {
       Ext.apply(this, { title: 'My Custom Panel' });
       CustomPanel.superclass.initComponent.call(this);
    },
    newMethod: function() {},
    overriddenMethod: function() {}
});

Ext.reg('custompanel', CustomPanel);
Prototypical Inheritance




         Ugly word, great for memory usage
Extending does not copy, it creates memory pointers.


                  .constructor
Override

Overwrites existing library code

Used to change base functionality or fix bugs

Can be evil (don't let it become your crutch)

Keep separate from the your code (ie: overrides.js)
Basic Override

// Class definition
ExtClass = Ext.extend(Ext.Component, {
    existingMethod: function() {}
    overriddenMethod : function() {}
});

// Our override
Ext.override(ExtClass, {
    newMethod : function() {},
    overriddenMethod : function() {}
});
Basic Override

existingMethod remains
newMethod is added (does not exist yet)
overriddenMethod is completely replaced (exists already)
// Class definition
ExtClass = Ext.extend(Ext.Component, {
    existingMethod: function() {}
    overriddenMethod : function() {}
});

Ext.override(MyClass, {
    newMethod : function() {},
    overriddenMethod : function() {}
});
Plugins

Adds functionality to various classes

Can be used on any class that inherits from Ext.Component

Independent of base class (more on this later)
Basic Plugin

Extend a base class (usually a simple one)
Ext.ux.PluginName = Ext.extend(Ext.util.Observable, {
    constructor: function(config){
       Ext.apply(this,config);
       Ext.ux.PluginName.superclass.constructor.call(this, config);
    },
    init: function(cmp){
       // do stuff
    }
});
Ext.preg('plugin-name',Ext.ux.PluginName);
Basic Plugin

Process any plugin configuration (can be omitted)
Ext.ux.PluginName = Ext.extend(Ext.util.Observable, {
    constructor: function(config){
       Ext.apply(this,config);
       Ext.ux.PluginName.superclass.constructor.call(this, config);
    },
    init: function(cmp){
       // do stuff
    }
});
Ext.preg('plugin-name',Ext.ux.PluginName);
Basic Plugin

Do stuff on host class initialization
Ext.ux.PluginName = Ext.extend(Ext.util.Observable, {
    constructor: function(config){
       Ext.apply(this,config);
       Ext.ux.PluginName.superclass.constructor.call(this, config);
    },
    init: function(cmp){
       // do stuff
    }
});
Ext.preg('plugin-name',Ext.ux.PluginName);
Basic Plugin

Register the plugin
Ext.ux.PluginName = Ext.extend(Ext.util.Observable, {
    constructor: function(config){
       Ext.apply(this,config);
       Ext.ux.PluginName.superclass.constructor.call(this, config);
    },
    init: function(cmp){
       // do stuff
    }
});
Ext.preg('plugin-name',Ext.ux.PluginName);
We Have a Plugin

Party (like it's 1999) again


...items: [{
    xtype: 'custompanel',
    border: true,
    plugins: [{
       ptype: 'plugin-name',
       isAwesome: false
    }]
}]
Not awesome yet?




 (lets make it awesome)
Awesome Plugin

The magic happens here
  init: function(cmp){
     this.hostCmp = cmp
     cmp.setTitle('Awesome');
  }


init is called just after initComponent but before render
Sequence/Intercept

Piggyback on existing functions

Useful for small changes/features

Be aware of impact
Basic Sequence/Intercept

Intercept happens before

Sequence happens after
Basic Sequence/Intercept

Class and method to sequence or intercept

Ext.intercept(Ext.form.Field.prototype, 'initComponent', function() {
var fl = this.fieldLabel, ab = this.allowBlank;
if (ab === false && fl) {
this.fieldLabel = '<span style="color:red;">*</span> '+fl;
} else if (ab === true && fl) {
this.fieldLabel = ' '+fl;
}
});
Basic Sequence/Intercept

Scope and arguments remain the same

Ext.intercept(Ext.form.Field.prototype, 'initComponent', function() {
var fl = this.fieldLabel, ab = this.allowBlank;
if (ab === false && fl) {
this.fieldLabel = '<span style="color:red;">*</span> '+fl;
} else if (ab === true && fl) {
this.fieldLabel = ' '+fl;
}
});
Basic Sequence/Intercept

...
{
       fieldLabel: 'Last Name',
       allowBlank: false,
       name: 'last'
},{ß
       fieldLabel: 'Company',
       allowBlank: true,
       name: 'company'
}
...

Four Ways to add Features to Ext JS

  • 1.
    Adding Features toExt JS Get Ext JS to do your bidding
  • 2.
    Options ● Extend ● Override ● Plugin ● Sequence/Intercept
  • 3.
    Extending New component basedon another Inherits functionality Somewhat lightweight (well come back to this) Four step process
  • 4.
    Basic Extending Pick aclass to start from (well come back to this) CustomPanel = Ext.extend(Ext.Panel, { initComponent : function() { Ext.apply(this, { title: 'My Custom Panel' }); CustomPanel.superclass.initComponent.call(this); }, newMethod: function() {}, overriddenMethod: function() {} }); Ext.reg('custompanel', CustomPanel);
  • 5.
    Basic Extending Configure itwith initComponent (well come back to this) CustomPanel = Ext.extend(Ext.Panel, { initComponent : function() { Ext.apply(this, { title: 'My Custom Panel' }); CustomPanel.superclass.initComponent.call(this); }, newMethod: function() {}, overriddenMethod: function() {} }); Ext.reg('custompanel', CustomPanel);
  • 6.
    Basic Extending Add yourown methods (or override existing) CustomPanel = Ext.extend(Ext.Panel, { initComponent : function() { Ext.apply(this, { title: 'My Custom Panel' }); CustomPanel.superclass.initComponent.call(this); }, newMethod: function() {}, overriddenMethod: function() {} }); Ext.reg('custompanel', CustomPanel);
  • 7.
    Basic Extending Register it(for use as an xtype) CustomPanel = Ext.extend(Ext.Panel, { initComponent : function() { Ext.apply(this, { title: 'My Custom Panel' }); CustomPanel.superclass.initComponent.call(this); }, newMethod: function() {}, overriddenMethod: function() { CustomPanel.superclass.overriddenMethod.call(this); } }); Ext.reg('custompanel', CustomPanel);
  • 8.
    Basic Extending Party (likeit's 1999) var myPanel = new CustomPanel({border: true}); ...items: [{ xtype: 'custompanel', border: true }]
  • 9.
    Extend From... Classes thatonly need events should extend Ext.util.Observable Classes that will serve as UI widgets should extend Ext.Component Use Ext.BoxComponent if simple layout management will be necessary Classes that can contain other components should extend Ext.Container Classes that require a title bar, toolbar or other advanced display features should extend Ext.Panel Look at the docs to see the inheritance chain for classes (upper right corner)
  • 11.
    How much overheaddoes extending add?
  • 12.
    Overhead Only as muchcode as you add CustomPanel = Ext.extend(Ext.Panel, { initComponent : function() { Ext.apply(this, { title: 'My Custom Panel' }); CustomPanel.superclass.initComponent.call(this); }, newMethod: function() {}, overriddenMethod: function() {} }); Ext.reg('custompanel', CustomPanel);
  • 13.
    Prototypical Inheritance Ugly word, great for memory usage
  • 14.
    Extending does notcopy, it creates memory pointers. .constructor
  • 15.
    Override Overwrites existing librarycode Used to change base functionality or fix bugs Can be evil (don't let it become your crutch) Keep separate from the your code (ie: overrides.js)
  • 16.
    Basic Override // Classdefinition ExtClass = Ext.extend(Ext.Component, { existingMethod: function() {} overriddenMethod : function() {} }); // Our override Ext.override(ExtClass, { newMethod : function() {}, overriddenMethod : function() {} });
  • 17.
    Basic Override existingMethod remains newMethodis added (does not exist yet) overriddenMethod is completely replaced (exists already) // Class definition ExtClass = Ext.extend(Ext.Component, { existingMethod: function() {} overriddenMethod : function() {} }); Ext.override(MyClass, { newMethod : function() {}, overriddenMethod : function() {} });
  • 18.
    Plugins Adds functionality tovarious classes Can be used on any class that inherits from Ext.Component Independent of base class (more on this later)
  • 19.
    Basic Plugin Extend abase class (usually a simple one) Ext.ux.PluginName = Ext.extend(Ext.util.Observable, { constructor: function(config){ Ext.apply(this,config); Ext.ux.PluginName.superclass.constructor.call(this, config); }, init: function(cmp){ // do stuff } }); Ext.preg('plugin-name',Ext.ux.PluginName);
  • 20.
    Basic Plugin Process anyplugin configuration (can be omitted) Ext.ux.PluginName = Ext.extend(Ext.util.Observable, { constructor: function(config){ Ext.apply(this,config); Ext.ux.PluginName.superclass.constructor.call(this, config); }, init: function(cmp){ // do stuff } }); Ext.preg('plugin-name',Ext.ux.PluginName);
  • 21.
    Basic Plugin Do stuffon host class initialization Ext.ux.PluginName = Ext.extend(Ext.util.Observable, { constructor: function(config){ Ext.apply(this,config); Ext.ux.PluginName.superclass.constructor.call(this, config); }, init: function(cmp){ // do stuff } }); Ext.preg('plugin-name',Ext.ux.PluginName);
  • 22.
    Basic Plugin Register theplugin Ext.ux.PluginName = Ext.extend(Ext.util.Observable, { constructor: function(config){ Ext.apply(this,config); Ext.ux.PluginName.superclass.constructor.call(this, config); }, init: function(cmp){ // do stuff } }); Ext.preg('plugin-name',Ext.ux.PluginName);
  • 23.
    We Have aPlugin Party (like it's 1999) again ...items: [{ xtype: 'custompanel', border: true, plugins: [{ ptype: 'plugin-name', isAwesome: false }] }]
  • 24.
    Not awesome yet? (lets make it awesome)
  • 25.
    Awesome Plugin The magichappens here init: function(cmp){ this.hostCmp = cmp cmp.setTitle('Awesome'); } init is called just after initComponent but before render
  • 26.
    Sequence/Intercept Piggyback on existingfunctions Useful for small changes/features Be aware of impact
  • 27.
    Basic Sequence/Intercept Intercept happensbefore Sequence happens after
  • 28.
    Basic Sequence/Intercept Class andmethod to sequence or intercept Ext.intercept(Ext.form.Field.prototype, 'initComponent', function() { var fl = this.fieldLabel, ab = this.allowBlank; if (ab === false && fl) { this.fieldLabel = '<span style="color:red;">*</span> '+fl; } else if (ab === true && fl) { this.fieldLabel = ' '+fl; } });
  • 29.
    Basic Sequence/Intercept Scope andarguments remain the same Ext.intercept(Ext.form.Field.prototype, 'initComponent', function() { var fl = this.fieldLabel, ab = this.allowBlank; if (ab === false && fl) { this.fieldLabel = '<span style="color:red;">*</span> '+fl; } else if (ab === true && fl) { this.fieldLabel = ' '+fl; } });
  • 30.
    Basic Sequence/Intercept ... { fieldLabel: 'Last Name', allowBlank: false, name: 'last' },{ß fieldLabel: 'Company', allowBlank: true, name: 'company' } ...