View Full Version : Extending Ext.form.ComboBox

16 Nov 2010, 5:13 AM
Is my code below the correct way of extending the combo xtype with my requirements as follows: (Note my question is whether it is the proper way, as it seems to work (without the listeners part). I just don't want it to bite me in the end in case it isn't the proper way after having built code on top of it.

1) I need to apply a custom XTemplate for the result set, like any property, I assigned tpl my template within the constructor as below. Do I just declare myTpl XTemplate instance within the same file as the extension? Say, just above the extension?

2) I want custom handlers assigned to certain events as well by default. As in declaring an xtype configuration, I also just put them within the listeners property block? (Note that I am not overriding any existing function or creating a new one, I am trying assign custom handlers to event when my xtype is created (keypress event below for example).

This leads me to questions:

3) How does an instance of my xtype extension know which to act on instance values when a handler is invoked? For combo example, the handler should manipulate the store of the object which invoked the handler.
4) If my handler is not inline but a named function var, I just declare the function within the same file, say above the Extension?

Many thanks.

MyDivision.form.SpecCombo = Ext.extend(Ext.form.ComboBox, {
constructor: function(config){
config = config || {};
config = Ext.apply(config || {}, {
fieldLabel:'Search Criteria',
mode: 'local',
typeAhead: false,
hideTrigger: true,
loadingText: 'Searching...',
resizable: true,
tpl: myTpl,
itemSelector: 'div.search-item',
enableKeyEvents: true,
// listeners: {
// 'keypress': function(comboBox, e) {
// if (e.getCharCode() == Ext.EventObject.ENTER) {
// onSearch();
// e.stopEvent();
// }else {
// selectedRecord = null;
// }
// }


MyDivision.form.SpecCombo.superclass.constructor.apply(this, arguments);

// this.lastSelectedIndex = this.selectedIndex || 0;

Ext.reg('speccombo', MyDivision.form.SpecCombo);

16 Nov 2010, 6:38 AM
Declare (pre configured) constants in the extended object's definition instead of in the constructor. Only put things in the constructor that actually need to be configured then (at instantiation time).

xyz = Ext.extend(SomeComponent, {
pre: 'configured',
members: 'lots',
stillTheSame: 'ohYes',
myID: null,
mySpecialClickListener: function() {
this.stillTheSame = 'ohNo';
specialDebug: function() {
constructor: function (cfg) {
//this only refers to our preconfigs, cfg is the users input
xyz.superclass.constructor.call(this, cfg);
//this now has cfg applied to it and acts like a proper Ext Component
this.on('keypress', this.mySpecialClickListener, this); //so I don't need to use the listeners config and
//can install multiple listeners onto the same event

//if you really need to create a function dynamically at instantiation-time, you would do something like this
this.specialDebug = function() {
console.log("I made this dynamically at construct time!");
//some people might have done Ext.apply on an object with a specialDebug function before calling super constructor.
//matter of preference.
this.on('keypress', this.specialDebug, this);//notice 3rd param for scope
Ext.reg(SETS, xyz); //registers SETS as the xtype to use for my component

If you actually need to call a global function with global scope, you can do so. You don't even need those functions to be declared in this file, you just have to be absolutely sure the functions are declared in globabl scope prior to using it.

For a combo box you can do

new Ext.form.Combobox({
tpl: new Ext.XTemplate('<tpl for=".">',...),
hiddenName: ...

Effectively declaring the template in line.

Xtype conversion is "hidden under the covers" somewhat. When Ext begins creating an object (and its children) and runs into a json literal instead of a newly created ext object, it simply references the xtype defs and calls the constructor on the json literal (cfg in constructor). As an offshoot your json configs with xtypes in them ARE NOT THE SAME AS the Ext Component that will eventually get created and used in your project. After it uses your config, your config is still your config. To access the items you created using this xtype system, you will have to use programmatic functions to traverse through the components and their ancestors (like someForm.find or someForm.items.getAt or someComponent.ownerCt etc etc). With a standard constructor, though, like

var myVar = new Ext.XYZ(...);
myVar can be used later on because it IS THE SAME object that your UI is using. Make sense?

16 Nov 2010, 6:56 AM
Other example

MyCombo = Ext.extend(Ext.form.ComboBox, {
// Default/Overridable simple value configs
// You normally don't want objects or arrays here since
// they will be part of the prototype and will be shared
// by all instances.
mode: 'local',
typeAhead: false,

initComponent: function() {

//Declare your template internally
var tpl = ...;

//Not sure if it has to be applied on initialConfig
Ext.apply(this, Ext.apply(this.initialConfig, {
tpl: tpl

// Put your listeners here, they will get processed
// by the parent initComponent.
this.listeners = {



//Add an handler to the store
'load': this.onLoad,
scope: this // Default execution scope would be the store, change it to the combobox

// Additionnal methods would go here
onLoad: function() {


16 Nov 2010, 4:30 PM
Thank you guys, I will try this today.