PDA

View Full Version : Need to render a combo inside a grid (not as an editor)



dha
13 Sep 2013, 9:46 AM
I am an Extjs beginner.
I need to render a combobox inside a grid(not as an editor).
Here is a compact version of what I am attempting to do:


Ext.define('BC.view.SelectionGrid',{
extend: 'Ext.grid.Panel',
alias: 'widget.SelectionGrid',
store: Ext.create(Ext.data.Store, {
fields:['component','value','type', 'duration','action']
data:finalData
}),
hideHeaders: true,
width:980,
height:'auto',
autoScroll:true,
layout:'fit',
columns:[
{
text: '',
dataIndex:'component',
flex: 1
},
{
text: '',
dataIndex:'value',
flex: 1,
renderer: function(value, metaData, record, rowIndex, colIndex, store, view){
//value =["on", "off"]
//also tried [["on"], ["off"]]
var el = new Ext.Element(document.createElement('div'));
var comp = Ext.create('Ext.form.ComboBox',{
store: new Ext.data.ArrayStore({
fields: [ "value", "text" ],
data:value
})


});
comp.render(el);
//looks like the renderer needs to return a string:
return el.dom.outerHTML;
}
},
{
text: '',
dataIndex:'type',
flex: 1
},
{
text: '',
dataIndex:'duration',
flex: 1
},
{
text: '',
dataIndex:'action',
renderer:function(sprite, records, attributes, index, store){
return '<a href="javascript:void(0);">'+sprite+'</a>';
}
}]
})


I am not sure if this is the right way to go about this.
The problem I am facing is:
The combo boxes show up without any data.


Any pointers would be highly appreciated!

ettavolt
15 Sep 2013, 10:51 PM
You should not use components in a grid, because this creates a huge load on a browser. Instead use cellediting plugin with custom configurations - like clicksToEdit. If you want to create some visually guidelines, add an icon to your cells setting tdCls on column config.

dha
17 Sep 2013, 12:12 PM
i have made the combo into an editor combo.


Ext.define('BC.view.SelectionGrid',{
extend: 'Ext.grid.Panel',
alias: 'widget.SelectionGrid',
store: Ext.create(Ext.data.Store, {
fields:['component','value','type', 'duration','action']
data:finalData
}),
hideHeaders: true,
width:980,
height:'auto',
autoScroll:true,
layout:'fit',
plugins:[
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
}),
],

selType: 'cellmodel' ,
columns:[
{
text: '',
dataIndex:'component',
flex: 1
},
{
text: '',
dataIndex:'value',
flex: 1,
editor: {
xtype:'combo',
displayField:'name',
valueField: 'value',
editable: false
}
renderer: function(value, metaData, record, rowIndex, colIndex, store, view, self){
this.columns[1].getEditor().store = Ext.create('Ext.data.Store', {
fields:['name', 'value'],
data: value//[{"name":"on", "value":"on"}, {"name":"off", "value":"off"}]
})
return value[0].name;
}
},
{
text: '',
dataIndex:'type',
flex: 1
},
{
text: '',
dataIndex:'duration',
flex: 1
},
{
text: '',
dataIndex:'action',
renderer:function(sprite, records, attributes, index, store){
return '<a href="javascript:void(0);">'+sprite+'</a>';
}
}]
})


When the grid loads, the cell that has the combo displays the first value of the store which is what I want.
Now the problems are:
1) when I click on the cell to display the combo, the combo display is ['object object', 'object object'].(which I think is because it is displaying the whole "value" object converted to string.) I want the text to be the first value ("on") at this point too.


2)Plus, after selecting a combo option, when I click on another row, there is no text in the clicked cell. I would like the cell to display the selected combo value.


If you can point me to how to get this done, that would be very helpful.
thanks in advance!

ettavolt
18 Sep 2013, 12:35 AM
Try declarative config: {ptype:'cellediting',clicksToEdit:1} for plugin; {type:'store',fields:[...],data:finalData} for grid's store;
{xtype:'combo', editable:false,store:['on','off']} for editor field and remove that column renderer.

dha
18 Sep 2013, 2:36 PM
that did not work for me.
Instead I set the dataIndex of the column to be another field and loaded the store of the combo from inside the column renderer.
Now the data is getting displayed but not in the right order.


The data of the combo that was last rendered(in the last row of the grid), is being displayed for every combo. Looks like data is not being bound to the right combo.


columns:[
{
text: '',
dataIndex:'component',
flex: 1
},
{
text: '',
dataIndex:'selectedValue',
flex: 1,
editor: {
xtype:'combo',
store: ['none'],
querymode: 'local',
displayField:'name',
valueField: 'name',
editable: false,
listeners: {
focus: function(obj) {
obj.expand();

},
change: function( self, newValue, oldValue, eOpts){
var comp = self.up('grid').editingPlugin.activeRecord.data.component;
for(var i=0; i<BC.finalValues.length; i++){
if(BC.finalValues[i].component === comp){
BC.finalValues[i].selectedValue = self.rawValue;
break;
}
}
}

}
},
renderer: function(value, metaData, record, rowIndex, colIndex, store, view, self){
//value =["on", "off"]
var storedata =[];
for(var i =0; i<record.data.value.length; i++){
storedata.push([record.data.value[i]]);
}
metaData.column.getEditor().store.loadData(storedata);
return record.data.value[0];
}
}
]

thanks for your patience and help!!

ettavolt
18 Sep 2013, 10:52 PM
Remove displayField and valueField configs and use loadRawData instead of loadData.

dha
19 Sep 2013, 2:56 PM
Thank You!!!
I appreciate your help..
The last tip worked!!

{
text: '',
dataIndex:'selectedValue',
flex: 1,
editor: {
xtype:'combo',
store: ['none'],
queryMode: 'local',
editable: false,
listeners: {
focus: function(obj) {
var raw=[];
var data =Ext.getCmp('tgrid').selModel.selection.record.data.value;
Ext.each(data, function(item, index) {
raw.push([item]);
});
obj.store.loadRawData(raw);
obj.expand();
}

}
}
}

Is there a way to display the editor combo even before the cellclick event ?
I am aware of faking it by imposing background images and so on. But I was wondering if there really was a way to display the combo even as the grid loads?

ettavolt
21 Sep 2013, 3:17 AM
You can trigger edit with grid.editingPlugin.startEdit(...);