PDA

View Full Version : Ext.getCmp('userForm') is undefined



djfiii
23 Feb 2010, 10:08 AM
I have extended FormPanel as a preconfigured class as follows:


App.userForm = Ext.extend(Ext.form.FormPanel, {
initComponent : function() {
Ext.apply(this, {
layout : 'form',
id : 'userForm',
url : 'users-update.php',
monitorValid : true,
width : 350,
frame : true,
defaults : {
xtype : 'textfield',
width : 200,
allowBlank : false,
msgTarget : 'side'
},
items : [{
fieldLabel : 'First Name',
name : 'firstname',


...
...
...


The form renders fine when I create an instance, however I am unable to reference it via the id. Am I missing something? I've searched the forum many times for this error and haven't found any indication as to why I might be unable to find it with Ext.getCmp. One similar issue was solved because the OP was using the 'name' attribute instead of 'id', however I'm clearly not doing that. When inspected with firebug, it's in the DOM. Any ideas? Might it have something to do with where I'm defining the id in the class extension?

Thanks!

Animal
23 Feb 2010, 10:34 AM
You programatically set the id to 'userForm' in every instance?

Anyway, you just can't do that. The id is set in the constructor.

Just another instance of the extend to configure virus that afflicts the Ext community.

djfiii
23 Feb 2010, 10:41 AM
You programatically set the id to 'userForm' in every instance?

Anyway, you just can't do that. The id is set in the constructor.

Just another instance of the extend to configure virus that afflicts the Ext community.

I will never have more than one instance at a time, so I didn't conceptually see that as an issue.

I'm open to suggestions about the right way to structure it, i.e. in opposition to "extend to configure". My approach comes from saki's tutorials, which are universally pointed to by both the admins on this board (including you, if you take a look at your signature) AND the authors of EXTJS that post here, when questions arise on structuring an application. On the surface, it seems like a good way to logically separate code and avoid having 10k lines of javascript in one file. Care to elaborate on why this approach is bad?

Also, thanks for the solution. I'll try it right now.

bclinton
23 Feb 2010, 10:47 AM
Just another instance of the extend to configure virus that afflicts the Ext community.

I know I've got a flaming case of that myself. When I started learning, it just seemed like Ext.Cmp was a thing to avoid and it was so easy to make everything a member of the component I was extending and using 'this' and '.createDelegate(this)' everywhere.

Is there a recommended path towards recovery?

djfiii
23 Feb 2010, 2:21 PM
As an answer to my own question, for others that might stumble on this, here is a good thread about extending vs. factory patterns. The distinction to be drawn is that if you're extending only to configure (as Animal clearly frowns upon), you might consider a factory pattern instead.

http://www.extjs.com/forum/showthread.php?p=259901#post259901

3rd post - lots of other info in there on app design as well.

bclinton
24 Feb 2010, 12:03 AM
Thanks for the link - bookmarked.

Animal
24 Feb 2010, 12:16 AM
I will never have more than one instance at a time...

So what are you doing creating class?

Animal
24 Feb 2010, 12:20 AM
A guide to creating UI widgets: http://www.extjs.com/learn/Tutorial:Creating_new_UI_controls

djfiii
25 Feb 2010, 10:29 AM
So, I switched all of my "extend to configure" classes to factory methods, and I'm still getting the Ext.getCmp is undefined error.

I start with a grid as follows, which works fine. In the rowselect handler, I'm creating a userWindow and passing the record object, among other stuff. :


cr = Ext.getCmp('centerRegion');
cr.removeAll();
ug = App.userGrid();
ug.getSelectionModel().on('rowselect',function(sm, rowIndex, record){
if(typeof(uw) != 'undefined') {
uw.destroy();
}
record.action = 'edit';
uw = App.userWindow({ title : 'Edit User', iconCls : 'user', record : record});
uw.items.items[0].getForm().loadRecord(record);
uw.show();
});
cr.add( ug );
cr.doLayout();



userWindow defined here, which contains a userForm, and passes along config.record which is the record object for the selected row coming through from the grid:



App.userWindow = function(config) {
return new Ext.Window(Ext.apply({
layout : 'fit',
width : 500,
height : 300,
closeAction : 'destroy',
plain : true,
items : App.userForm(config.record)
}, config));
}



Then userForm, where I set the ID programatically, for the sole purpose of getting reference to the form component in my submit handler (better way to do that??) :


App.userForm = function(config){
return new Ext.form.FormPanel(Ext.apply({
id : 'userForm',
url : 'users-update.php',
monitorValid : true,
width : 350,
frame : true,
defaults : {
xtype : 'textfield',
width : 200,
allowBlank : false,
msgTarget : 'side'
},
items : [{
fieldLabel : 'First Name',
name : 'firstname',
emptyText : 'Enter a First Name'
},{
fieldLabel : 'Last Name',
name : 'lastname'
},{
fieldLabel : 'User Name',
name : 'username'
},{
fieldLabel : 'Email',
name : 'email',
vtype : 'email'
},{
fieldLabel : 'Phone Number',
name : 'phone'
},{
xtype: 'combo',
id : 'role',
fieldLabel : 'Role',
displayField : 'role',
valueField : 'roleid',
hiddenName : 'roleid',
store : new Ext.data.JsonStore({
root : 'records',
fields : [
{ name : 'roleid', mapping : 'roleid' },
{ name : 'role', mapping : 'role'},
],
proxy : new Ext.data.HttpProxy({
url : 'includes/json/roles.php'
})
})
}],
buttons : [{
text : 'Submit',
scope : this,
formBind : true,
handler : function(){
console.log(this.userForm);
Ext.getCmp('userForm').getForm().submit({ action : config.action});
}
}]
}, config));
}


Any idea why I'm getting undefined for Ext.getCmp('userForm')?