PDA

View Full Version : Error when extending



paulharv
7 May 2010, 5:11 AM
Not getting something here...

I'm learning by reading ExtJS in Action, and trying to digest and apply the stuff about extension/namespacing.
I have a simple app working with all of the code in one file, and am trying now to clean this up by extending.

So I have this in /js/UploadPanel.js


Ext.ns('Gluuee');
Gluuee.UploadPanel = Ext.extend(Ext.form.FormPanel, {
title : 'Add Sugar',
html : 'This works'
});And in my html file I have this...


var uploadPanel = new Gluuee.UploadPanel();
...
var mainPanel = new Ext.Panel({
...
items : [
aGridPanel,
aChartPanel,
uploadPanel
]
...
});And this works

But if I add items to UploadPanel...


Ext.ns('Gluuee');
Gluuee.UploadPanel = Ext.extend(Ext.form.FormPanel, {
title : 'Add Sugar',
html : 'This blows up',
items : [{
fieldLabel : 'File',
id : 'data',
allowBlank : false,
inputType : 'file'
}]
});I get this error...
Error: this.items.add is not a function
Source File: http://localhost:4567/extjs/ext-all-debug.js
Line: 11770

Can anyone point me in the right direction on this?

Thanks

Animal
7 May 2010, 5:14 AM
You are extending to configure. What's the problem with simply configuring a panel?

paulharv
7 May 2010, 5:47 AM
Thanks.
Yeah you're right - my goal was to do var uploadPanel = new Gluuee.UploadPanel() and get a configured FormPanel.

Do you mean just do something like this in /js/UploadPanel.js


var uploadPanel = new Ext.form.FormPanel, {
title : 'Add Sugar',
html : 'This works',
items : [{
fieldLabel : 'File',
id : 'data',
allowBlank : false,
inputType : 'file'
}]
});

Condor
7 May 2010, 6:04 AM
That is the correct solution (apart from the "," typo) when you only need one instance of the formpanel.

If your goal is to be able to create multiple instances then you should use a factory method, e.g.

var createUploadPanel = function(config){
return new Ext.form.FormPanel(Ext.apply({
title: 'Add Sugar',
items: [{
xtype: 'box',
autoEl: {cn: 'This works'}
},{
xtype: 'textfield',
inputType: 'file'
fieldLabel: 'File',
allowBlank: false
}]
}, config));
}

You only extend a class if you are adding specific behaviour, e.g.

var UploadPanel = Ext.extend(Ext.form.FormPanel, {
constructor: function(config){
UploadPanel.superclass.constructor.call(this, Ext.apply({
title: 'Add Sugar',
items: [{
xtype: 'box',
autoEl: {cn: 'This works'}
},{
xtype: 'textfield',
inputType: 'file'
fieldLabel: 'File',
allowBlank: false
}],
buttons: [{
text: 'OK',
handler: this.okClick,
scope: this
}]
}, config));
},
okClick: function(){
Ext.Msg.alert('Message', 'Hello World!');
}
});
(I prefer overriding the constructor, but you could use initComponent instead - like many examples do)

paulharv
7 May 2010, 6:35 AM
Thanks so much.

The following is working - using the initComponent() approach...
I am extending because I do have behavior.
However, it can't be right that I have to do this...

thisPanel = Ext.getCmp('bloodSugarUploadPanel')//!!!!
But I don't know how to get a reference to the current UploadPanel. "this" is not it in this context.

(back to my much-needed reading...)


Ext.ns('Gluuee');
Gluuee.UploadPanel = Ext.extend(Ext.form.FormPanel, {
id : 'bloodSugarUploadPanel',
title : 'Add Sugar',
fileUpload : true,
bodyStyle : 'padding: 6px',
defaultType : 'textfield',
initComponent : function() {
this.items = [{
fieldLabel : 'File',
id : 'data',
allowBlank : false,
inputType : 'file'
}];
this.buttons = [{
text : 'Submit',
handler : function(){
thisPanel = Ext.getCmp('bloodSugarUploadPanel');
thisPanel.el.mask('Your blood sugars are being saved...', 'x-mask-loading');
thisPanel.getForm().submit({
url : '/upload',
success : function(){
thisPanel.el.unmask();
}
});
}
}]
Gluuee.UploadPanel.superclass.initComponent.call(this);
}
});