PDA

View Full Version : own components and id conflict



TheMonolith
8 Mar 2010, 6:26 AM
I have a fundamental problem with creating custom components. For example, I have created a class TextFieldSet which extends FieldSet and contains a combobox and a text area as items:

TextFieldSet
--- combobox
--- text area

If I select a value from the combobox, the value of the text area should change.

Therefore, I wrote a listener for the combobox:


listeners:
{
select:
function(combo, record, index)
{
switch (index)
{
case 0:
Ext.getCmp('textAreaID').setValue('nonsense');
break;
case 1:
Ext.getCmp('textAreaID').setValue('more nonsense');
break;
case 2:
Ext.getCmp('textAreaID').setValue('even more nonsense');
break;
}
}
}The text area (with id: 'textAreaID') is defined by lazy instantiation. The problem is that I have three TextFieldSet objects and each has a text area with the same id (textAreaID). That's why setting the value of the text area of myTextFieldSet1 leads to an undefined result because there are two other text areas with the same id (they belong to myTextFieldSet2 and myTextFieldSet3).

How can I solve this problem?

I guess different text area IDs have to be generated for each TextFieldSet. But how can I do that? Or is there an easier way?

tobiu
8 Mar 2010, 7:47 AM
id has to be unique for each dom-node.

but you can take a look at the two configs:



itemId
ref


that's what they are made for ;)


kind regards,
tobiu

TheMonolith
8 Mar 2010, 8:16 AM
Man, that's extremely cool. Thanx!

Stormseeker
8 Mar 2010, 10:13 AM
There is also a method on the Ext object that will generate a unique id for the given element if it doesn't have an ID already.

http://www.extjs.com/deploy/dev/docs/?class=Ext

TheMonolith
9 Mar 2010, 12:44 AM
Can anybody please tell me why setting the text area value through itemId and getComponent doesn't work?
Firebug tells me "this.getComponent is not a function" for the blue lines listed below:


TextFieldSet = Ext.extend(Ext.form.FieldSet,
{
constructor: function(config)
{
Ext.apply(this,
{
autoHeight: true,
title: "Text",
disabled: true,
items:
[{
xtype: "combo",
hiddenName: "combovalue",
width: 200,
fieldLabel: "Vorlage",
editable: false,
allowBlank: false,
blankText: 'test',
triggerAction: 'all',
editable: false,
store: new Ext.data.SimpleStore
({
fields: ['field1'],
data: [['#1'], ['#2'], ['#3']]
}),
displayField: 'field1',
mode: 'local',
listeners:
{
select:
function(combo, record, index)
{
switch (index)
{
case 0:
this.getComponent('textArea').setValue('test');
break;
case 1:
this.getComponent('textArea').setValue('test');
break;
case 2:
this.getComponent('textArea').setValue('test');
break;
}
}
}
},
{
xtype: 'textarea',
itemId: 'textArea',
width: 200,
fieldLabel: 'test',
disabled: true
},
{
xtype: 'textfield',
itemId: 'textField',
width: 200,
fieldLabel: 'test',
autoCreate:
{
tag: 'input',
type: 'text',
maxlength: 25
}
}
]
});

TextFieldSet.superclass.constructor.apply(this, arguments);
}
});

tobiu
9 Mar 2010, 12:52 AM
probably the wrong scope.

you use "this" in a select-listener of a combo, so i guess it will point to that element.
try console.log(this) for details ;)

TheMonolith
9 Mar 2010, 1:09 AM
You're right tobiu, thanks.
But how can I achieve what I want?

Just removing the "this." doesn't work. I get a "getComponent is not defined" error message.

TheMonolith
9 Mar 2010, 1:24 AM
P.S.

TextFieldSet.getComponent('textArea').setValue('test') doesn't work either:
TextFieldSet.getComponent is not a function

evant
9 Mar 2010, 1:30 AM
Because TextFieldSet is a class name, not an instance of a class.

As tobiu said, you want to set the scope on the listener:



listeners: {
scope: this,
select: function(){
console.log(this);
}
}

TheMonolith
9 Mar 2010, 1:42 AM
What does "setting the scope on the listener" mean? I couldn't find an explantion in the Learning Ext JS" book or in the API documentation.

tobiu
9 Mar 2010, 2:00 AM
evan changed the scope from the combo to your TextFieldSet - class. That means where the this-pointer shows to. with that scope,



this.getComponent('textArea').setValue('test');


will do.



TextFieldSet.getComponent('textArea').setValue('test')


could not work.

var myFieldset = new TextFieldSet(...);
myFieldset .getComponent('textArea').setValue('test')

should.

back to the scope: i think jay garcia made a tutorial-video about it, search for it.
at the creation of your instance, the scope points to it. so the listener gets the reference to your class (to be more precise to the new created instance).

after creation, on the event select, the scope points to the combo. but since even pointed it somewhere else (the this is replaced through your new instance), it points there .

i hope it gets a bit clearer now.


kind regards,
tobiu

Mike Robinson
9 Mar 2010, 7:08 AM
If you look at the definition of things like listener, you'll notice that you can specify either a function or a hash. If you use a hash, you'll see that the function is identified by the fn attribute of that hash ... and that there are other attributes too, including scope.

scope allows you to specify what the value of this will be when the handler (fn) is called.