PDA

View Full Version : [DEFER] Component.getAutoCreate() -- returns prototype property instead of copy



btmurrell
21 May 2010, 12:48 PM
Ext version tested:

Ext 3.2 rev 1


Adapter used:

ext


css used:

only default ext-all.css


Browser versions tested against:

browser agnostic


Operating System:

OS agnostic


Description:

When you define a class with autoCreate, then create more than one instance of that class, all instance dom elements point to the first one. Componenet.getAutoCreate() is returning the prototype property autoCreate when it should be returning a copy of it.


Test Case:



/*
//uncomment to fix
Ext.override(Ext.Component, {
getAutoCreate : function(){
var cfg = Ext.isObject(this.autoCreate) ?
// was:
// this.autoCreate : Ext.apply({}, this.defaultAutoCreate);

// fix:
Ext.apply({}, this.autoCreate) : Ext.apply({}, this.defaultAutoCreate);
if(this.id && !cfg.id){
cfg.id = this.id;
}
return cfg;
}
});
*/

MyField = Ext.extend(Ext.form.Field, {
autoCreate: {tag: 'input', type: 'hidden'}
});

var fld1, fld2, info;

var initFlds = function() {
fld1 = new MyField({name: 'fld1', id: '1', value: 'foo', fieldLabel: 'can\'t see me 1'});
fld2 = new MyField({name: 'fld2', id: '2', value: 'bar', fieldLabel: 'can\'t see me 2'});
info = new Ext.form.TextArea( {fieldLabel: 'info', width: 350, value: ''});
}();

var p = new Ext.FormPanel({
width: 500,
items: [
fld1,
fld2,
info,
{xtype: 'button',
text: 'Submit',
handler: function() {
var vals = p.getForm().getValues();
info.setValue(
'fld1 el name: ' + fld1.el.dom.name + ' (val: ' + vals.fld1 + ')\n' +
'fld2 el name: ' + fld2.el.dom.name + ' (val: ' + vals.fld2 + ')'
)
}
,scope: this
}
]
});

Ext.onReady(function() {
p.render(document.body);
});


Steps to reproduce the problem:

push the submit button in the test case. info about the two fields shows up in the text area.


The result that was expected:

fld2 el name should be 'fld2', fld2 value should be 'bar'


The result that occurs instead:

fld2 el name shows 'fld1'. fld value shows value from fld1 ('foo').


Screenshot or Video:

n/a


Debugging already done:

workaround provided -- uncomment the top code (override) and re-run the test. the correct results are produced.


Possible fix:

see commented code in test case.

Jamie Avins
21 May 2010, 4:19 PM
You should never put a complex type on the prototype when doing an extend unless you know that it is going to be immutable. This is by design how extend is made to work, if you want to add a complex type, apply it within initComponent.

btmurrell
24 May 2010, 1:39 PM
With all due respect, I think you missed the point of my report. My type on my prototype *is* immutable -- it simply defines that all instances of this class should be created with this definition -- in my case a hidden input field. This is an immutable definition.

The problem occurs when extjs getAutoCreate() returns the prototype property (which extjs previously set the id on -- extjs is changing it), and uses that id to get an element -- in this case, it has a pointer to the first element, not any of the others that might have been created from it.

If I try what you suggest, that is to change my extend like this:

MyField = Ext.extend(Ext.form.Field, {
// autoCreate: {tag: 'input', type: 'hidden'}
initComponent: function() {
autoCreate = {tag: 'input', type: 'hidden'};
MyField.superclass.initComponent.call(this);
}
});

then i get two fields that are visible input fields, which I do not want in this case.

Jamie Avins
24 May 2010, 2:47 PM
I see what you are trying to do now, sorry about that. I'll have to look into any implications with incorporating it.