PDA

View Full Version : Adding/removing fields and columns



Condor
18 Nov 2008, 7:19 AM
Because there are so much questions in the Help forum on how to add or remove a grid column I thought I'd post some utility code:


Ext.override(Ext.data.Store,{
addField: function(field){
field = new Ext.data.Field(field);
this.recordType.prototype.fields.replace(field);
if(typeof field.defaultValue != 'undefined'){
this.each(function(r){
if(typeof r.data[field.name] == 'undefined'){
r.data[field.name] = field.defaultValue;
}
});
}
},
removeField: function(name){
this.recordType.prototype.fields.removeKey(name);
this.each(function(r){
delete r.data[name];
if(r.modified){
delete r.modified[name];
}
});
}
});
Ext.override(Ext.grid.ColumnModel,{
addColumn: function(column, colIndex){
if(typeof column == 'string'){
column = {header: column, dataIndex: column};
}
var config = this.config;
this.config = [];
if(typeof colIndex == 'number'){
config.splice(colIndex, 0, column);
}else{
colIndex = config.push(column);
}
this.setConfig(config);
return colIndex;
},
removeColumn: function(colIndex){
var config = this.config;
this.config = [config[colIndex]];
config.splice(colIndex, 1);
this.setConfig(config);
}
});
Ext.override(Ext.grid.GridPanel,{
addColumn: function(field, column, colIndex){
if(!column){
if(field.dataIndex){
column = field;
field = field.dataIndex;
} else{
column = field.name || field;
}
}
this.store.addField(field);
return this.colModel.addColumn(column, colIndex);
},
removeColumn: function(name, colIndex){
this.store.removeField(name);
if(typeof colIndex != 'number'){
colIndex = this.colModel.findColumnIndex(name);
}
if(colIndex >= 0){
this.colModel.removeColumn(colIndex);
}
}
});

Usage example:

var grid = new Ext.grid.GridPanel({
store: new Ext.data.SimpleStore({
fields: ['A', 'B'],
data: [['ABC', 'DEF'], ['GHI', 'JKL']]
}),
columns: [
{header: 'A', dataIndex: 'A'},
{header: 'B', dataIndex: 'B'}
]
});
new Ext.Viewport({
layout: 'fit',
items: grid
});
grid.addColumn('C');
grid.addColumn({name: 'D', defaultValue: 'D'}, {header: 'D', dataIndex: 'D'});
grid.removeColumn('B');

As mentioned in post #37:
Adding and removing fields currently does not update the extractors used to load data. If you want to update these too then you should call:

delete store.reader.ef;
store.reader.buildExtractors();
after modifying fields.

skaue
19 Dec 2008, 2:35 AM
Thanks Condor!! Just what I needed right now \:D/

rtconner
24 Dec 2008, 9:47 PM
!! Oh man, I had my own hack to do this, but I like your's better.

Marshal.Lin
30 Dec 2008, 12:53 AM
very good!

jay@moduscreate.com
30 Dec 2008, 9:01 AM
i think this should be added to the base!

Marshal.Lin
30 Dec 2008, 5:47 PM
i think this should be added to the base!
=D>up!

Marshal.Lin
30 Dec 2008, 10:32 PM
if i want to use it like below,does it work? thanks!

var myReader = new Ext.data.JsonReader({
id:"id",
totalProperty: "total",
root:"rows"
}, new Ext.data.Record.create([
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
])
);
var ds= new Ext.data.Store({
proxy:new Ext.data.HttpProxy({url:'/getdata'}),
reader: myReader
});

var cm = new Ext.grid.ColumnModel([
{header:'ID',dataIndex:'id'},
{header:'NAME',dataIndex:'name'}
]);

var grid = new Ext.grid.EditorGridPanel({
store: ds,
cm: cm
});

grid.addColumn({header:'AGE',dataIndex:'age'});

Condor
31 Dec 2008, 12:38 AM
Yes, that should work.

You could also use:

grid.addColumn({name: 'age', type: 'int', defaultValue: null}, {header: 'AGE', dataIndex: 'age', sortable: true});

Radziu
15 Feb 2009, 11:36 PM
is it possible to add column on the designated place? eg. we have 5 columns and i would like to add second column


hmm...and removeColumn doesnt work in checkboxselectionmodel, addColumn is ok

Condor
16 Feb 2009, 2:26 AM
The addColumn method supports a second parameter: the column index (0-based, so use 1 when inserting the second column).

A CheckboxSelectionModel doesn't have a dataIndex, so you'll have to use the removeColumn method of the columnmodel (and not the grid) and specify the colIndex to remove.

mysticav
20 Feb 2009, 7:07 PM
Get this Json reader error via loadexception when adding a column:


f.convert is not a function

Condor
20 Feb 2009, 11:56 PM
Yes, I just noticed an error in addField. Please try the updated code in the original post.

tchitani
25 Mar 2009, 9:10 PM
Hi Condor

Can grid.addColumn method be used to add a CheckBox column?

Thanks
Nik

Condor
26 Mar 2009, 12:54 AM
Can grid.addColumn method be used to add a CheckBox column?

Yes, but because you didn't specify it as a plugin for the grid you will also need to call:

gridPanel.getView().mainBody.on('mousedown', checkColumn.onMouseDown, checkColumn);

revortado
15 Apr 2009, 5:01 AM
Hi Condor... i having a problem using the code you provide...

When removing a column, the grid doesn't refresh... the column is still there but the fields of the store are destroyed...
Is there anything i have missing from my code?

Try to use the code on a normal grid... below is my code:



// Store de valores
var store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: 'php-grid-group.php',
method: 'POST'
}),
reader: new Ext.data.JsonReader({
id: 'id',
root: 'INDUSTRIA',
totalProperty: 'TOTAL',
fields: [
{name: 'company'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'},
{name: 'excerpt'},
{name: 'industry'}
]
})
});


// Colunas de registros
var cm = [
{id:'company', header: "Company", width: 160, sortable: true, dataIndex: 'company'},
{header: "Price", width: 75, sortable: true, dataIndex: 'price'},
{header: "Change", width: 75, sortable: true, dataIndex: 'change'},
{header: "% Change", width: 75, sortable: true, dataIndex: 'pctChange'},
{header: "Last Updated", width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('d/m/Y'), dataIndex: 'lastChange'},
{header: "Industry", width: 85, sortable: true, hidden: true, dataIndex: 'industry'}
];


var filters = new Ext.grid.GridFilters({
filters:[
{type: 'string', dataIndex: 'company'},
{type: 'numeric', dataIndex: 'price'},
{type: 'numeric', dataIndex: 'change'},
{type: 'date', dataIndex: 'lastChange'}
]});


// Barra superior de menu de botões
var barSup = [
{
text: 'Voltar',
tooltip: 'Voltar',
icon: 'back.png',
cls:'x-btn-text-icon',
handler : function() {
grid.removeColumn('company', 'company');
grid.getView().refresh(true);
}
}, {
text: 'Novo',
tooltip: 'Criar no Item',
icon: 'add.png',
cls:'x-btn-text-icon'
//handler : handleAdicionar
}, {
text: 'Editar',
tooltip: 'Editar Registro Selecionado',
icon: 'edit.png',
cls:'x-btn-text-icon'
//handler : handleAdicionar
}, {
text: 'Remover',
tooltip: 'Remover Selecionado(s)',
icon: 'remove.png',
cls:'x-btn-text-icon'
//handler : handleAdicionar
}
];


// create the Grid
var grid = new Ext.grid.GridPanel({
id: 'grid',
store: store,
columns: cm,
tbar: barSup,
renderTo: document.body,
plugins: [filters],
stripeRows: true,
autoExpandColumn: 'company',
height: 350,
width: 600,
bbar: new Ext.PagingToolbar({
store: store,
pageSize: 10,
plugins: [filters]
})
});

store.load();

galdaka
15 Apr 2009, 5:34 AM
May be gridPanel.getView().refresh ?

ajaxvador
15 Apr 2009, 5:43 AM
very nice =D>=D>=D>

revortado
15 Apr 2009, 5:51 AM
Already try that galdaka... and do nothing...
The problem affects when i'm adding a new column... only the first column insert show the records, the others do show nothing...

Sure i'm missing something...

thanks in advance

Condor
15 Apr 2009, 6:21 AM
Sorry, removeColumn was wrong. Could you try again with the updated code from the first post?

ps. It's removeColumn('company') (no second argument required) and you don't need to call getView().refresh().

revortado
15 Apr 2009, 6:54 AM
Hi condor... will try the new code that you work for on the removeColumn method...
By the way, after try i could solve myself... realize that the function was not removing the column because the remove method was not getting the object...

So i rewrite your code for my personal use only... hope you don't mind... and i'm sharing with you...
Thanks again for the support, i'm only beginning explore Ext...



removeColumn: function(colIndex) {
var config = this.config;
config.remove(config[colIndex]);
}


By the way, still having a problem, when adding columns after the first one... the grid records are only show for the first column...

thanks very much!!!!!!

revortado
15 Apr 2009, 6:57 AM
Condor.... try again the removeColumn with your new code, and it works like a charm...

thanks!

Condor
15 Apr 2009, 7:20 AM
By the way, still having a problem, when adding columns after the first one... the grid records are only show for the first column...

I don't follow what you are trying to do... Could you post an example of this?

revortado
15 Apr 2009, 8:25 AM
Sorry not make myself clear enough...
What i'm doing in this... draging a row from gridA to gridB, when the drop event occur a new column is create in the gridB, the i reload a store on the gridB that brings the result with the new column add...
The problem i'm facing is that the first time (first column drop), the grid loads the records ok, and the data appear... in the second and so on new columns the record is reloaded but the data appear only on the first grid dropped, the others don't show their data...


- understand gridB as secondGrid in the snipe code:

The code to drop, add new column and reload the store:


var destGridDropTarget = new Ext.dd.DropTarget(secondGridDropTargetEl, {
ddGroup : 'secondGridDDGroup',
copy : false,
notifyDrop : function(ddSource, e, data) {

function addColumn(record, index, allItems) {

// Search for duplicates
var foundItem = secondGrid.getColumnModel().findColumnIndex(record.get("CAMPOS"));

// if not found
if (foundItem == -1) {
//Remove Record from the source
ddSource.grid.store.remove(record);

// novo campo da grid
var nome = record.get("CAMPOS");

// Adiciona a coluna
secondGrid.addColumn({ header: nome, dataIndex: nome });

// Carrega a grid com os novos valores
secondGrid.getStore().load({params: { id_query: Ext.get("query").getValue() }});



}


}

// Loop through the selections
Ext.each(ddSource.dragData.selections, addColumn);
return(true);
}
});



The store:


// Busca pelo registro no formato JSON
var secondGridStore = new Ext.data.Store({
remoteSort: true,
proxy: new Ext.data.HttpProxy({
url: '<?php print $this->baseUrl ?>/design/listarregistros',
method: 'POST'
}),
reader: new Ext.data.JsonReader({
root: 'OBJ',
totalProperty: 'TOTAL',
fields: []
})
});


and the data itself:


{"OBJ":[{"ID":"1","DESCRICAO":"NORMAL"},{"ID":"2","DESCRICAO":"ASCENDENTE"},{"ID":"3","DESCRICAO":"DESCENDENTE"
}],"TOTAL":3}



thanks

Condor
15 Apr 2009, 8:48 AM
I would advise to create secondStore with all possible fields an only add the columns to secondGrid (for already existing data), e.g.


secondGrid.getColumnModel().addColumn({header: nome, dataIndex: nome});

revortado
15 Apr 2009, 8:59 AM
Thanks condor... try the code with your correction, and now even the first column inserted doesn't show the record data...
Tell me something about the code addField that you override... te line:


this.recordType.prototype.fields.replace(field);


Come from where... the this.recordType i undestand, is a property of the store, the prototype i know too (you are adding a new field to the function that is inside this.recordType)... but the the rest of the expression is a bit of strange... after all, the fields.replace already exists inside this.recordType?

Unfortunately, my system demands that i do this dynamic operation...

thanks...

revortado
15 Apr 2009, 9:31 AM
Condor... solve my problem... to do what i want, just need to sendo toghter with the data a metaData param of the object as descrived here:

http://extjs.com/deploy/dev/docs/output/Ext.data.JsonReader.html

For people how will face the same problem as i:


It is possible to change a JsonReader's metadata at any time by including a metaData property in the data object. If this is detected in the object, a Store object using this Reader will reconfigure itself to use the newly provided field definition and fire its metachange event. In undergoing this change, the Store sets its sortInfo property from the sortInfo property in the new metadata. Note that reconfiguring a Store potentially invalidates objects which may refer to Fields or Records which no longer exist.




{
metaData: {
totalProperty: 'results',
root: 'rows',
id: 'id',
fields: [
{name: 'name'},
{name: 'occupation'}
]
},
results: 2,
rows: [
{ 'id': 1, 'name': 'Bill', occupation: 'Gardener' },
{ 'id': 2, 'name': 'Ben', occupation: 'Horticulturalist' }
]
}

/:) ... now my work is almost done!

wanwan2277
24 Jun 2009, 12:21 AM
Hello Condor, thanks for your sharing. It's easy to add columns into the grid by your code.
In my requirement, I need requery this grid to get other info.
so there are some different columns into this grid after the second query.
But, there is a problem, some column's value is disappear when I query the second time.
I check a lot of part of the code, but the problem is still lived.

1. data from DB (.Action file) is ok.
2. store is ok.
3. column headers are displayed. (ok)

the following is my code.

thisPage.onSearchPlanTwoWeekClick = function() {

//remove column
for(i=columnName.length-1;i>-1;i=i-1){

thisPage.weeklyPlanGridPane.removeColumn(columnName[i]);
columnName.pop();
}
thisPage.OSPPlanInventoryStore.removeAll();

Ext.Ajax.request({
url : 'GetOSPCommonComposAction.action',
method : 'POST',
timeout : 1800000,
success : function(result, request) {
jsonQuerySeq = Ext.util.JSON.decode(result.responseText);
storeName = '';

for(i=0;i<jsonQuerySeq.rows.length;i=i+1){
if(i!=0){
storeName = storeName+',';
}
storeName = storeName+'{name:'+Ext.util.JSON.encode(jsonQuerySeq.rows[i].compos).substring(1,13)+'}';
columnName[i] = Ext.util.JSON.encode(jsonQuerySeq.rows[i].compos).substring(1,13);
thisPage.weeklyPlanGridPane.addColumn(
{name:Ext.util.JSON.encode(jsonQuerySeq.rows[i].compos).substring(1,13)},
{header : Ext.util.JSON.encode(jsonQuerySeq.rows[i].compos).substring(1,13), align : 'center', width : 100, dataIndex : Ext.util.JSON.encode(jsonQuerySeq.rows[i].compos).substring(1,13)});

}

thisPage.OSPPlanInventoryStore.removeAll();
thisPage.OSPPlanInventoryStore.reload({
callback:function(r, options, success){
if (success){
}else{
thisPage.OSPPlanInventoryStore.removeAll();
}
},timeout:9000000
});


}
});

}

Condor
24 Jun 2009, 12:42 AM
Does the reloaded store contain data for all fields (including the ones you added)?

wanwan2277
24 Jun 2009, 4:35 PM
Yeah! I displayed the store data, and it included the columns I added.
I think action data is ok, but it is not completely loaded into the store.
When the column's position and data is the same as the previous querying one, the store data will show up, otherwise is not.
It's so weird....

revortado
25 Jun 2009, 2:58 AM
hi there wanwan... the solution that i found to my problem with the new columns is describe in my last post in this thread... i send toghter with the data model a column model to the store. This way the columns are add, and is be alive in my grid...
Check my last post please, if this doens't solve your problem, be sure... cordor is the best guy to help you out with this... i just as you still learn ExtJs

thanks

wwwjsx
30 Nov 2009, 12:40 AM
Condor

thank you for your sharing code. I have problem when I using the colIndex it is not possible to touch the added column. I am trying manually switch off the added column.

see:
http://my.jetscreenshot.com/demo/20091130-guuz-1kb.jpg

If i use withour colIndex works very fine

Condor
30 Nov 2009, 12:55 AM
I have problem when I using the colIndex it is not possible to touch the added column.

Are you sure you didn't configure the column with fixed:true or hideable:false?

Otherwise, can you post an example?

asagala
4 Dec 2009, 10:56 AM
Trying to add a column as the first column in the grid by doing this

this.addColumn(0,'C'); -> this. is my grid

but it always adds it to the end. Anyone have a clue?

asagala
4 Dec 2009, 10:59 AM
Nevermind misread the function parameters. Was using the one for the gridcolumn. The one for the grid should be this.addColumn('C','C',0);

jsakalos
28 Dec 2009, 2:02 AM
i think this should be added to the base!
+1

tobiu
31 Dec 2009, 12:34 AM
+1

Izhaki
10 Jan 2010, 9:28 PM
Hi,

Firstly, thank Condor for this.

Then, +1 here as well, but before:

The provided code could break JsonReader/XmlReader calls since buildExtractors is not called. It's a bit odd since sometimes it works, other times it throws load exception or just doesn't load the values. This is due to this (JsonReader):



extractValues : function(data, items, len) {
var f, values = {};
for(var j = 0; j < len; j++){
f = items[j];
var v = this.ef[j](data);
values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
}
return values;
}


So my fix:



Ext.override(Ext.data.Store,{
addField: function(field){
field = new Ext.data.Field(field);
this.recordType.prototype.fields.replace(field);
if(typeof field.defaultValue != 'undefined'){
this.each(function(r){
if(typeof r.data[field.name] == 'undefined'){
r.data[field.name] = field.defaultValue;
}
});
}
delete this.reader.ef;
this.reader.buildExtractors();
},
removeField: function(name){
this.recordType.prototype.fields.removeKey(name);
this.each(function(r){
delete r.data[name];
if(r.modified){
delete r.modified[name];
}
});
delete this.reader.ef;
this.reader.buildExtractors();
}
});



Cheers

Condor
10 Jan 2010, 10:37 PM
The provided code could break JsonReader/XmlReader calls since buildExtractors is not called. It's a bit odd since sometimes it works, other times it throws load exception or just doesn't load the values.

Wouldn't it be better to return metaData from the server? In that case the fields and the data are always in sync.

Izhaki
10 Jan 2010, 10:58 PM
Sure,

metaData will solve this. But if this mod is to be added to the base, I thought I should report this issue/fix.

Also, it took me 4 hours to work out what's wrong, so to save the time for other people...

Cheers

kamalhg
1 Mar 2010, 12:41 PM
this fix makes the extension works with 3.1.x :)


Hi,

Firstly, thank Condor for this.

Then, +1 here as well, but before:

The provided code could break JsonReader/XmlReader calls since buildExtractors is not called. It's a bit odd since sometimes it works, other times it throws load exception or just doesn't load the values. This is due to this (JsonReader):



extractValues : function(data, items, len) {
var f, values = {};
for(var j = 0; j < len; j++){
f = items[j];
var v = this.ef[j](data);
values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
}
return values;
}
So my fix:



Ext.override(Ext.data.Store,{
addField: function(field){
field = new Ext.data.Field(field);
this.recordType.prototype.fields.replace(field);
if(typeof field.defaultValue != 'undefined'){
this.each(function(r){
if(typeof r.data[field.name] == 'undefined'){
r.data[field.name] = field.defaultValue;
}
});
}
delete this.reader.ef;
this.reader.buildExtractors();
},
removeField: function(name){
this.recordType.prototype.fields.removeKey(name);
this.each(function(r){
delete r.data[name];
if(r.modified){
delete r.modified[name];
}
});
delete this.reader.ef;
this.reader.buildExtractors();
}
});

Cheers

steffenk
4 Mar 2010, 5:09 PM
i think this should be added to the base!
+1

btw - Condor, do you have your complete overrides somewhere? You posted so much useful ones, thanks for that!

saadkhan
6 Mar 2010, 9:28 PM
Hi Condor,
I am looking for daysss to how to add fields dynamically into my XMLReader seeing xml. I dont ahve anyyyyyy idea how to do this. I have an xml that I am parsing at runtime to setup fields of my XmlReader of my Grid. Pleassssssseeeee help.....nobody is responding to my threads asking same!!!!!!!!!!!!



var statusStore = new Ext.data.Store({
storeId: 'statusStore',
proxy: new Ext.data.MemoryProxy(''),
reader: new Ext.data.XmlReader(
{
record: 'Status'
},
[
// Here more fields should be add at run time
{name: 'DateAndTime', mapping: '@DateAndTime'}
]
)
});

var statusGrid = new Ext.grid.GridPanel({
id: 'statusGrid',
title: 'Status',
store: statusStore,
hideHeaders: true,
trackMouseOver: false,
autoWidth: false,
columns:
[
// I want to have only only column
{id: '_dateAndTime', header: "DateAndTime", dataIndex: 'DateAndTime', renderer: statusRenderer}
],
viewConfig:
{
forceFit: true
},
autoExpandColumn: '_dateAndTime'
});

function statusRenderer(value, p, r)
{
var arr = [];
var statusStore = Ext.StoreMgr.get('statusStore');
statusStore.each(function(record)
{
arr.push(record.data.title, '<br />', record.data.state, '<br />', record.data.description, '<br /><br />');
});
return arr.join('');
}


I am reading my xml something like that in order to add fields into my reader at runtime:



function RecieveStatusXML(str) {
var statusXml = StringToXml(strrr);

var statusStore = Ext.StoreMgr.get('statusStore');
var childs = statusXml.documentElement.childNodes.item(0).childNodes;
var recData = [];
for(var x=0; x < childs.length; x++)
{
var TopicRecord = Ext.data.Record.create(
[
{name: "'" + childs.item(x).tagName + "Description'", mapping: "'" + childs.item(x).tagName + " > @Description'" },
{name: "'" + childs.item(x).tagName + "State'", mapping: "'" + childs.item(x).tagName + " > @State'" }
]
);
var myNewRecord = new TopicRecord(
{
title: childs.item(x).tagName,
state: childs.item(x).attributes[0].nodeValue,
description: childs.item(x).attributes[1].nodeValue
}
);
recData.push(myNewRecord);
}
// Dont know where to add these fields ???????????
}


Here is my sample XML:



<Statuses>
<Status DateAndTime='date'>
<Door State='1' Description='desc' />
<Acc State='2' Description='sadasd sad r' />
<St State='0' Description='lpc' />
....
</Status>
</Statuses>

lakilevi
31 Mar 2010, 10:51 AM
Hello.
I like realy much this extension and I would use it in my application.
But I have aproblem. :( I add in the fly a column to the grid, but when I reload the store, than the grid is empty.
Here is my code:


var preview_store = new Ext.data.Store({
reader: new Ext.data.JsonReader({fields: ['name'],root: 'rows'}),
proxy: new Ext.data.HttpProxy({
url: 'modules/contacts/jax_import/build_preview.jax.php',
method:'post',
success: function ( result, request ) {store.commitChanges();},
failure: function ( result, request) {Ext.MessageBox.alert('<?=$lang->trans("Failed")?>', result.responseText);}
})
});


var preview_grid = new Ext.grid.GridPanel({
stripeRows:true,
store: preview_store,
loadMask: true,
height:230,
cm: new Ext.grid.ColumnModel([{header:'Company name',dataIndex:'name'}]),
autoScroll:true,
viewConfig:{emptyText:'<?=$lang->trans('No entries')?>.'}
});

preview_grid.addColumn({header: 'first_name', dataIndex: 'first_name'});
preview_store.baseParams={'cols':tmp, filename:uploaded_file, 'target':target_selector.getValue()};
preview_store.load();


and here is my output of the ajax request:


{success: true,rows:[{"first_name":"1","name":"Google"}]}

Thank you very much for your help!

lakilevi
31 Mar 2010, 11:09 AM
there is something with the store.load ...
if I insert the code:


preview_store.load({callback: function(r,o,s){console.dir(r);alert(preview_store.getCount());} });


than alerts 0. But if I take out the line with preview_grid.addColumn(...) than it loads well... What can be the problem?

lakilevi
31 Mar 2010, 9:00 PM
With post #37 I solved the problem. Thanks Izhaki (http://www.extjs.com/forum/member.php?u=70758) :)

alebar
14 Apr 2010, 6:18 AM
Hi,

When I use this solution to add new columns in the grid with big number of columns (from hundreds to thousands) it is very very slow.

Is it expected or apparently I do sth wrong?

Thanks in advance for any suggestions.

Condor
14 Apr 2010, 10:36 PM
Hi,

When I use this solution to add new columns in the grid with big number of columns (from hundreds to thousands) it is very very slow.

Is it expected or apparently I do sth wrong?

Thanks in advance for any suggestions.

That is to be expected. If you want to add a large number of columns then you should use:

grid.getColumnModel().setConfig(newColumns);

alebar
14 Apr 2010, 11:47 PM
That is to be expected. If you want to add a large number of columns then you should use:

grid.getColumnModel().setConfig(newColumns);

Thank you so much. I'm gonna try it!

Sesshomurai
28 Apr 2010, 5:11 AM
Any tips how to make this work with GridFilters, which need the column data too?

vmadman
5 May 2010, 6:33 AM
Has anyone had trouble with the code working on ExtJS 3.2?

I recently upgraded from 3.0.0

Thanks,
Luke

vmadman
5 May 2010, 6:43 AM
Nevermind, it ports just fine. My troubles were elsewhere, in my own code.

gozargozarian
13 Aug 2010, 2:43 PM
If I try to use the code to add a new SelectionModel type of column, such as CheckBoxSelectionModel. Then it loses the field editors that were attached to each field in the Grid. Is there a way to trigger reloading of the field editors on an editable grid?

Thanks!

Jangla
17 Aug 2010, 7:27 AM
I/m trying to use the code to add a rowActions column (as per the Ext.ux.grid.RowActions control) but it doesn't want to play. Any tips appreciated.

Edit - actually got that cracked although it seems that adding an id to the addColumn call doesn't affect where the column is added for me; it's always the last column to the right :(

colinm
6 Dec 2010, 3:43 AM
Hi condor ... very nice post .. but what about duplicating a column ... ?? (or adding a column with specific data ... other than default value?).

i tried to add a duplicateSelectedColumn in between the remove and the add column of your code, but i am facing several problems. before to continue, do you have an easy way to do this?

thanks!

Condor
6 Dec 2010, 4:24 AM
You could add a copy of an existing column config, but that won't work for the editor (you'll have to clone() it).

colinm
6 Dec 2010, 5:42 AM
thanks for the answer ... so i should clone the config of the interested column....
i did something maybe similar. Inside your remove and add columns methods of the gridpanel (btw: i changed it to an editorGridPanel), i did the following


duplicateSelectedColumn: function(){
if (this.selModel.selection)
{
duplicatenum +=1;
var columnindex=this.selModel.selection.cell[1];
var curcolumn=this.colModel.columns[columnindex];
var newheader=curcolumn.header+duplicatenum;
return this.colModel.addColumn({header:newheader, dataindex:newheader, editor: new Ext.form.TextField({ allowBlank: false})}, columnindex);
}
else{ Ext.Msg.alert('select a column first');}
},


this works fine and add a new column with a new header ... strangely, all fields appear with the same values as the column which was at that column index :-? ... the problem is that these values are not really duplicated (eg. i can't change their value .. but if i change the values of the row which was at that location, the values of the duplicated column change in the same time)
do you have any hints about how to duplicate them?

thanx a lot

alok000707
28 Feb 2011, 9:53 PM
Hi COndor,

Thanks for the code.

I had successfully added the column into the grid panel.

But I am not able to add field dyanmically.

I tried the code given by you, but the data is not reflecting in the grid.

Please suggest, what I need to do to proceed.

THe following is the code snippet that I am implementing.




var dataIndex = 'conversionRateKey.'+currencyCode;
grid5.addColumn({name:dataIndex},{header: currencyCode, dataIndex: dataIndex},3);



this code is able to add column successfully but not able to fetch data from json.

Please help.

Regards
Alok

Condor
28 Feb 2011, 11:39 PM
What exactly do you mean by "not able to fetch data from json"?

alok000707
28 Feb 2011, 11:50 PM
let me explain you the situation..

I have data as follows:



var myData = [
['3m Co', 71.72, 0.02, 0.03, 'for new col'],
['Alcoa Inc', 29.01, 0.42, 1.47, 'for new col'],
['Altria Group Inc', 83.81, 0.28, 0.34, 'for new col'],
['American Express Company', 52.55, 0.01, 0.02, 'for new col']
];
Following is my store and fields, where I defined only 4 fields. so that I can add the last field dynamically.



var store = new Ext.data.ArrayStore({
fields: [
{name: 'company'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'}
]
});

// manually load local data
store.loadData(myData);
and this is my grid where I am adding new column,



// create the Grid
var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{
id :'company',
header : 'Company',
width : 160,
sortable : true,
dataIndex: 'company'
},
{
header : 'Price',
width : 75,
sortable : true,
dataIndex: 'price'
},
{
header : 'Change',
width : 75,
sortable : true,
renderer : change,
dataIndex: 'change'
},
{
header : '% Change',
width : 75,
sortable : true,
dataIndex: 'pctChange'
}
],
stripeRows: true,
autoExpandColumn: 'company',
height: 350,
width: 600,
title: 'Array Grid',

});

// render the grid to the specified div in the page
grid.render('grid-example');
//adding new column
grid.addColumn({name: 'D', defaultValue:'D'}, {header: 'D', dataIndex: 'D'});



Now I want that, on adding to column D the extra data coming in store get showed in it. Column is successfully adding into the grid but data is not get populated.

Condor
1 Mar 2011, 12:19 AM
No, it won't automatically populate. For that you would need to reload the store.

alok000707
1 Mar 2011, 1:04 AM
Thanks Condor!!

It worked
:)

lukefowell89
7 Apr 2011, 12:45 AM
Hi Condor,

This extension has worked perfectly for me, however, the way in which my grid has been overwritten means that when I add a column, I also need to adjust the css classes accordingly so that they styles applied to each cell aren't misaligned.

Currently, I am adding a new column to the end of my grid panel (my column headers are generated from code giving me excel like column headers eg. A,B,c...... AB, AC..... FA, FB etc.) Then every cell to the right of the selected index where I would like to insert the column, I have moved to the right by one column including classes which I have moved using Ext.select('.x-spreadsheet-cell-inner-(col index)-(row index)');

Do you have any suggestions for the best way to insert a column at a specific index, and then make sure that the class names follow their associated column? Any and all help appreciated.

ivone_tarigan
17 Jul 2011, 11:29 PM
hiii condor...i have used your code but it doesnt work on my code..

i wanna add field to store but it didnt work..

this is my code :

this is my code to get store

newhid.testkit.gridStore = Ext.extend(Ext.data.JsonStore, {
constructor : function(config) {
config = config || {};
config.pruneModifiedRecords = config.pruneModifiedRecords || true;
config.url = config.url || (baseHref + newhid.testkit.controller + '/getDataTestkit');
config.autoLoad = false;
config.id = config.id || 'test_store';
config.root = config.root || 'rows';
config.totalProperty = config.totalProperty || 'total',
config.fields = [
{name: 'idsoselement',mapping : 'idsoselement'},
{name: 'descriptions',mapping:'descriptions'},
{name: 'idsostestkit',mapping:'idsostestkit'},
{name: 'method',mapping:'method'},
//{name: 'Contaminant',mapping:'Contaminant'},

];
config.autoLoad = config.autoLoad || true,

newhid.testkit.gridStore.superclass.constructor.call(this, config);
}
});

and this is my code to add store from ajax

Ext.Ajax.request({
url: baseHref + newhid.testkit.controller + '/getsosCondition',
success: function(resp, options) {
resp = Ext.decode(resp.responseText);
countTab = resp.rows.length;
var gridStore = Array();
var rows = new Array();
var storex = Array({'name':'ddd'});
var colx = new Array();
var headertab = {};
var store;
var newStore;

if(resp == ''){
Ext.Msg.alert('Status', 'No Data Found');
return false;
}

var newStore = new newhid.testkit.gridStore();
for (i=0;i<countTab;i++) {
colCount = resp.rows.length;
header_desc = resp.rows[i].descriptions;
newStore.addField({'name':resp.rows[i].descriptions,'mapping':resp.rows[i].descriptions});
colx = colx.concat(Array(
coloumnx[i] = new Ext.ux.grid.CheckColumn({
header: header_desc,
align:'center',
width:100,
sortable: true,
dataIndex:resp.rows[i].descriptions,
editable: true,
menuDisabled: true
})

));

storex = storex.concat(Array({'name':resp.rows[i].descriptions,'mapping':resp.rows[i].descriptions}));
}
tabheader = new newhid.testkit.testkit_grid({
store: new newhid.testkit.gridStore({
fields:storex
})
,columns:colx
})
var grid = Ext.getCmp('panelTab').add(tabheader);
Ext.getCmp('panelTab').doLayout();
Ext.getCmp('panelTab').render('dashboard_form_grid');
console.log(tabheader);

}
});

thankyou for your help.. :)

g13013
1 Jan 2012, 8:38 AM
Hi All,

is this Extension work for Ext 4?

sabhandari
12 Jan 2012, 9:53 PM
Hi Condor,

You are a life saver

andreyutz
23 Jan 2012, 5:07 AM
Hi Condor,
Can you please update the code to work with Ext Js 4?

Thanks
Andrei

Golden.Vulture
27 Jan 2012, 4:20 AM
Hi

I am a beginner at EXTJS 4.0 ( yes not migrating from 3.0 to 4.0) and right now i just want to create a editable grid initially with no columns and then add new columns to it and grow it dynamically to you can say 1K rows.
Can anyone please guide me through links how to go about it ? a EXTJS 3.0 version type will also be of soo much help.

i couldnt really get how to fit the code given to make a actual working app.

Thanks in advance ;)

remeis
9 May 2012, 1:20 AM
I tried to implement dynamic grids in Ext 4: Ext.grid.GridPanel: adding/removing columns (http://www.sencha.com/forum/showthread.php?202636-Ext.grid.GridPanel-adding-removing-columns)
At least, it works as it should in my case ;) But I'll continue working on that if problems arise.

smalik
23 May 2012, 11:43 PM
i need to change one of grid column from textfield to combo box.
i am using simple gridpanel for display.

i.e. on select of 1st combobox in grid, depending on value selected in combo, last column can either be textfield or combo box.

any help is appreciated.
thanks in advance.

shobhaaradhya
23 Jul 2012, 6:21 AM
Hi,

The code

grid.addColumn({name: 'age', type: 'int', defaultValue: null}, {header: 'AGE', dataIndex: 'age', sortable: true});

Here the header 'AGE' is static text. Can I add the header from store object. OR can I bind the header text to store object to the existing columns. What I am trying to do is based on certain condition I am trying to change the header text but this header text I am getting from DB.

Can you help me pls. I am struggling since one week.

Thanks,
Aradhya

akshay210
17 Aug 2012, 4:20 AM
This does not work for EXT JS 4.1.1.
Can you help me with a similar workaround for dynamically adding columns in Ext 4.1.1???

Thanks a ton,
Akshay.

jlaskowski
25 Apr 2013, 10:13 AM
This solution worked for me and did it in just a few lines of code:

http://neiliscoding.blogspot.com/2011/09/remove-grid-columns-dynamically-in.html

sandeepsukhani
16 Aug 2013, 3:36 AM
Hi Condor (http://www.sencha.com/forum/member.php?343-Condor),

I am getting "this.recordType is undefined" error for code. I even tried your sample grid code. I am getting same error and I'm using 4.2 version of library.

mgavr
11 Oct 2013, 4:12 PM
Hello,

I tried it on jsfiddle: http://jsfiddle.net/tJhWK/

You can see I commented out all addField/addColumn code and it shows an initial grid. As soon as I uncomment it it stops working. Can you please advise what's wrong?

Mikhail

Toussah
6 Nov 2013, 2:50 AM
I'm working on the Extjs 4 TreeGrid (Ext.tree.TreePanel) and I'd like to use a similar code to update the columns of my grid. I tried to adapt the code but the attributes of the TreePanel are too much different from the GridPanel one. Could someone help me please ?

@naresh
28 Aug 2014, 3:16 AM
Thanks a lot Condor for doing this utility.

But i want to add one extra thing how to map the dynamically record and another things is how to add xtype actioncolumn in this case .


thanks
//Naresh