ComboBox for Grid (combo having local store)
Many people have been having confusion over how to handle rendering of combo boxes having a separate valueField and displayField. This is how we have been using in our applications:
Ext.ns("Ext.ux.renderer");
Ext.ux.renderer.ComboRenderer = function(options) {
var value = options.value;
var combo = options.combo;
var returnValue = value;
var valueField = combo.valueField;
var idx = combo.store.findBy(function(record) {
if(record.get(valueField) == value) {
returnValue = record.get(combo.displayField);
return true;
}
});
// This is our application specific and might need to be removed for your apps
if(idx < 0 && value == 0) {
returnValue = '';
}
return returnValue;
};
Ext.ux.renderer.Combo = function(combo) {
return function(value, meta, record) {
return ExtHelper.renderer.ComboRenderer({value: value, meta: meta, record: record, combo: combo});
};
}
Then, in grid config you can use the same renderer for combo:
// Your combo definition
var addressTypeCombo = Ext.form.ComboBox();
var cm = new Ext.grid.ColumnModel([
{header: 'Type', dataIndex: 'AddressTypeId', width: 100, renderer: Ext.ux.renderer.Combo(addressTypeCombo), editor: addressTypeCombo},
{header: 'Address', dataIndex: 'Address1', width: 130, editor: new Ext.form.TextField({maxLength:50})},
{header: 'Address 2', dataIndex: 'Address2', width: 110, editor: new Ext.form.TextField({maxLength:50})},
{header: 'Address 3', dataIndex: 'Address3', width: 110, editor: new Ext.form.TextField({maxLength:50})},
{header: 'Zip Code', dataIndex: 'PostalCode', editor: new Ext.form.TextField({maxLength:10}), width: 80},
{header: 'City', dataIndex: 'City', width: 80, editor: new Ext.form.TextField({maxLength:20})}]
])
Please note that the above combo box assumes that the store for combo will be local. This approach won't work with remote combos. For remote combo, we update a "proxy" field in the grid store that is used for rendering.
Let me know your suggestions/ improvements.
=================
REMOTE COMBOBOX ==================
CeeBee, there are examples in Grid FAQ thread that answer your question. However, let me just summarize how we do it:
Let us say you need CountryId and StateId in your grid. So, we'll add CountryName and StateName as two additional proxy fields in the grid. Now your fields will look something like this:
[{name: 'CountryId', type: 'int'}, {name: 'StateId', type: 'int'}, {name: 'CountryName', type: 'string'}, {name: 'StateName', type: 'string'}];
Now in the grid configuration also, you'll do something like this:
[{header: 'Country', dataIndex: 'CountryId', editor: new Ext.form.ComboBox(), renderer: function(v, m, r) { return r.get('CountryName'); }}]
Then, on selection of combo, to update the country name we add an event handler like this:
grid.on('validateedit', function(e) {
var dataIndex = e.field;
switch(dataIndex) {
case "CountryId":
case "StateId":
var combo = grid.getColumnModel().getCellEditor(e.column, e.row).field;
var displayFieldName = e.field.replace('Id', 'Name');
e.record.set(displayFieldname, combo.getRawValue());
break;
}
});
I hope this helps!