PDA

View Full Version : Add a field to a form in tablelayout



wuschba
18 May 2009, 8:06 AM
Hello!

I have a simple formpanel with tablelayout, like:


title: 'Block',
layout: 'table',
items: [{ fieldLabel: 'Name',
name: 'sName'
}]


Now I want to add a field at runtime. I do it like:


var field = new Ext.form.TextField({
fieldLabel: 'Test',
name: 'Added',
value: 'It works'
});
this.form.insert(0, field);
this.form.doLayout();


I don't get an error, but I don't get the field either. What could be wrong?

18 May 2009, 8:57 AM
what does this.form = ?

wuschba
18 May 2009, 10:10 AM
It's just a new FormPanel, like:



this.form = new Ext.form.FormPanel({
title: 'Block',
layout: 'table',
layoutConfig: {
columns: 1
},
items: [{ fieldLabel: 'Name',
name: 'sName'
}]
});


I tried to find the part in the source-code, but I couldn't figure how tablelayout is inserting an item when the first layout had already been done. I guess the whole table of the tablelayout has to be rebuild to make sure that an inserted item moves all items forward in the table-structure. But how/where is it done?

Added: I looked in the html-soruce with firebug after inserting the new field, but it doesn't appear there.

Animal
19 May 2009, 12:07 AM
Why use a table tayout if you only have 1 column?

wuschba
19 May 2009, 4:40 AM
Why use a table tayout if you only have 1 column?
Thats just a test-situation - I wanted to make the code as easy as possible to show the problem in the forum. It doesn't work with 2 or x columns either.

In http://extjs.com/deploy/dev/docs/output/Ext.form.FormPanel.html -> render it's said that TableLayout should allow dynamic addition of child components. But it just doesn't work for me. Does it work for somebody else?

In fact I'm trying to implement my own layout-manager and want to know how tablelayout is managing items which are inserted after the layout had been done already once. But my guess is that tablelayout has to rearrange all the items after the added item to do so, but I couldn't find in the source-code where this could be done.

Animal
19 May 2009, 5:02 AM
Should work in 3.0 (depending upon when the fix ws committed to the 3.0 trunk)

TableLayout in SVN has



onLayout : function(ct, target){
var cs = ct.items.items, len = cs.length, c, i;

if(!this.table){
target.addClass('x-table-layout-ct');

this.table = target.createChild(
Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
}
this.renderAll(ct, target);
},


See if tat's what yhou have.

wuschba
19 May 2009, 6:17 AM
Thanks again for your reply. This code is what I have as well - it's actually no difference from 2.2.1.

But the code you posted creates the table on the first layout. This works fine for me as well.


What I want to know is what is happening when a control is inserted dynamically AFTER the whole container has already been rendered.


Imagine you have a tablelayout like:



+--------+-----------------+
| A | B | C |
| |--------+--------|
| | D | E |
+--------+--------+--------+


And you do a:


this.form.insert(2, NEW);
this.form.doLayout();


This should result in something like:


+--------+-----------------+
| A | B | NEW |
| |--------+--------|
| | C | D |
+--------+--------+--------+
| E |
+--------+--------+--------+


So, what has to be done is:
- Move C from the 1st to the 2nd <tr> of the table.
- Move D from the 1st to the 2nd <td> of the 2nd row of the table.
- Create a new row and move E there.

Whats actually happening is just nothing - and thats my problem.

Animal
19 May 2009, 6:53 AM
I don't think that's ever going to work the way it is now.

You'll have to create a new layout class which recreates the table on every layout.

wuschba
19 May 2009, 11:54 AM
Sounds like a plan ;-) How could I do that?

I spend some hours trying to remove/destroy innerCt of tablelayout or the table itself, but the table keeps empty after that although I'm re-initiating the creating-process.

Animal
19 May 2009, 12:33 PM
Try removing the table element, and nulling out this.table in onLayout so that it basically rerenders the table with its contents on each layout.

Animal
19 May 2009, 12:36 PM
You'll have to have an "else" side to the if (!rendered) test which basically does



}else if(c && !this.isValidParent(c, target)){
if(typeof position == 'number'){
position = target.dom.childNodes[position];
}
target.dom.insertBefore(c.getDomPositionEl().dom, position || null);
c.container = target;
this.configureItem(c, position);
}


to move an already rendered Component's Element into the current TD

Maharshi
2 Jun 2009, 12:37 PM
Hi,

I have a formpanel with tablelayout fields as shown in the attached jpg.My requirement is based on the 'Fields' combobox items , the 'Value' textfield should be replaced by a combobox and vice versa.I am able to dynamically remove the textfield from the form,however the new combobox doesnt get inserted in the form.please help me ,as to how can i dynamically do this?
heres my code , to simplyfy i have shown only snippet of code.Please let me know if more info or complete code is needed.

var field = grpcombo.ownerCt.find('name','valueTf'+gpn);
var nform =grpcombo.ownerCt.ownerCt;
var indx = nform.items.findIndex('name','valueTf'+gpn);
nform.remove(field[0]);
var enumCombo = new Ext.Component({
xtype:'combo',
name:'enumCombo',
typeAhead: true,
triggerAction: 'all',
store: new Ext.data.SimpleStore({
fields: ['itemIndex','itemValue'],
data:Ext.decode(Avata.dbUtils.getEnums4AvataProjectKind())
}),
displayField: 'itemValue',
valueField:'itemIndex',
mode: 'local',
emptyText:'Select a Item',
emptyClass:'emptyTextfield',
width:250
});
nform.insert(indx,enumCombo);
nform.doLayout();