PDA

View Full Version : Editor grid with different editors and renderers in the same column



willigogs
7 Jun 2011, 4:29 AM
Hi there,

This is probably going to take some explaining, but I'll try and be as concise as possible :)

I have an editor grid with lets say 10 rows. For each row there is effectively a description of the setting, a "Current Setting" column (uneditable), and a "New Setting" column, which will feature a combo with the various options for that individual setting.

Now each row is a different type of setting, therefore will require a different combo. The cell should also be rendered differently depending on what setting has been chosen from the combo to populate the "New Setting" column.

Here's a basic example of how it could display:
http://img857.imageshack.us/img857/6197/examplem.png
(The New Setting column is actually pre-populated with the Current Setting, but I'm using a column renderer to hide the value if it's the same as the current column).

I started by looking at an example of Condor's (http://www.sencha.com/forum/showthread.php?29853-set-field-type-in-editor-grid-based-on-a-combo-box-selection&p=141782#post141782) where he setup different editors based on the value of the previous cell.

I twisted this and managed to get it working, but then of course ran into the issue of the combo submitting the valuefield into the table rather than the displayfield. I again twisted the renderer logic to handle this, but have now come to a conclusion where it works, but there will have to be a LOT of code held in the column renderers to handle all this logic.

I'll attach a stripped down sample of the code in question below, and I guess I'm simply asking is there a better way to achieve this functionality? The table in question actually has over 100 settings, so I can see the switch statements growing very long if I proceed this way...

// STORES
var store_settings = new Ext.data.JsonStore({
storeId:'store_settings',
url: 'url',
fields:['id',' description','currentsetting','newsetting'],
reader: settingsreader,
writer: settingswriter,
totalProperty: 'totalCount',
successProperty: 'success',
messageProperty: 'message',
idProperty: 'id',
root: 'records'
});
var store_combo_onoff = new Ext.data.JsonStore({
fields:['id','config'],
data: [
{id:'0', config:'Off'},
{id:'1', config:'On'}
]
});
var store_combo_level = new Ext.data.JsonStore({
fields:['id','type'],
data: [
{id:'0', type:'None'},
{id:'1', type:'Low'},
{id:'2', type:'Medium'},
{id:'3', type:'High'},
{id:'4', type:'Maximum'}
]
});

// COMBOS
var combo_onoff = new Ext.form.ComboBox({
id: 'combo_onoff',
name : 'combo_onoff',
hideLabel:false,
xtype: 'combo',
valueField : 'id',
displayField : 'config',
hiddenName : 'id',
store : store_combo_onoff,
triggerAction : 'all',
selectOnFocus:true,
forceSelection : true,
mode : 'local'
});
var combo_level = new Ext.form.ComboBox({
id: 'combo_level ',
name : 'combo_level ',
hideLabel:false,
xtype: 'combo',
valueField : 'id',
displayField : 'type',
hiddenName : 'id',
store : store_combo_level,
triggerAction : 'all',
selectOnFocus:true,
forceSelection : true,
mode : 'local'
});

// COLUMN RENDERERS

// "CURRENT SETTING" COLUMN
function render_current (val, meta, record, rowIndex, colIndex, store) {
var id = record.get('id');
switch(id){
case '1':
switch(val){
case '0':
meta.css += ' setting_0';
return 'None';
case '1':
meta.css += ' setting_1';
return 'Low';
case '2':
meta.css += ' setting_2';
return 'Medium';
case '3':
meta.css += ' setting_3';
return 'High';
case '4':
meta.css += ' setting_4';
return 'Maximum';
}
break;
default:
if (val == '1') {
meta.css += ' settingon';
return 'On';
} else {
meta.css += ' settingoff';
return 'Off';
}
break;
}
};


// "NEW SETTING" COLUMN
Ext.ux.renderer.ComboRenderer = function(options) {

var rec = options.record;
var currentval = rec.get('currentsetting');
var newval = rec.get('newsetting');
var id = rec.get('id');

// TELL THE SWITCH STATEMENT BELOW WHICH COMBO TO LOOK AT
switch(id){
case '1':
var combo = options.combo.combo_level;
default:
var combo = options.combo.combo_onoff;
}

var value = options.value;
var returnValue = value; // THIS IS WHAT WILL GET SENT BACK AT THE END OF THE FUNCTION
var valueField = combo.valueField;
var meta = options.meta;

var idx = combo.store.findBy(function(record) {
switch(id){
case '1':
if(newval == currentval) {
returnValue = '';
return;
} else {
switch(value){
case '0':
meta.css += ' setting_0';
returnValue = 'None';
return;
case '1':
meta.css += ' setting_1';
returnValue = 'Low';
return;
case '2':
meta.css += ' setting_2';
returnValue = 'Medium';
return;
case '3':
meta.css += ' setting_3';
returnValue = 'High';
return;
case '4':
meta.css += ' setting_4';
returnValue = 'Maximum';
return;
}
returnValue = record.get(combo.displayField);
return;
}
default:
if(record.get(valueField) == value) {
if(pendingval == liveval) {
returnValue = '';
return;
} else {
if (value == '1') {
meta.css += ' settingon';
} else {
meta.css += ' settingoff';
}
returnValue = record.get(combo.displayField);
return;
}
}
break;
}
});
return returnValue;
};

Ext.ux.renderer.Combo = function(combo) {
return function(value, meta, record) {
return Ext.ux.renderer.ComboRenderer({value: value, meta: meta, record: record, combo: combo});
};
}

// GRID
var cm = new Ext.grid.ColumnModel({
editors: {
'combo_onoff': new Ext.grid.GridEditor(combo_onoff),
'combo_level': new Ext.grid.GridEditor(combo_level)
},
getCellEditor: function(colIndex, rowIndex) {
var rec = store_policyedit.getAt(rowIndex);
var id = rec.get('id');
switch(id){
case '1':
return this.editors['combo_level'];
break;
default:
return this.editors['combo_onoff'];
break;
}
},
columns: [
{header:'Description', id:'description', dataIndex:'description
{header:'Current Setting', id:'currentsetting', dataIndex:'currentsetting', renderer: render_current},
{header:'New Setting', id:'newsetting', dataIndex:'newsetting', editable: true, renderer: Ext.ux.renderer.Combo(this)}
]
});
var grid_editsettings = {
id: 'grid_editsettings',
xtype: 'editorgrid',
autoSave:false,
margins:'0',
region:'center',
autoScroll:true,
viewConfig: {markDirty: false},
clicksToEdit: 1,
store: store_settings,
stripeRows:true,
cm: cm
};

e.taranov
7 Jun 2011, 6:12 AM
Are you using ExtJS 4.0.x?
I am trying to do similair thing in 4.0.1 and can't find ColumnModel class at all.

I have some kind of properties grid with editable cells:
http://xmages.net/storage/10/1/0/c/5/upload/a213e003.png
And i need to have different editors in different rows (cells).
Is it possible in Ext 4.0.x?

Thanks

e.taranov
7 Jun 2011, 11:31 PM
Are you using ExtJS 4.0.x?
I am trying to do similair thing in 4.0.1 and can't find ColumnModel class at all.


Sorry, didn't noticed that this is Ext 3.x branch.

dbrin
4 Sep 2012, 5:03 PM
ever found your answer?

willigogs
5 Sep 2012, 2:07 AM
ever found your answer?
Well since no-one commented or suggested a better way, I just proceeded as described in my first post ;)

It seemed like a lot of code to achieve something so seemingly simple, but it worked. I can always provide a small example on JSFiddle if needed.

dbrin
5 Sep 2012, 10:05 AM
I am using a getEditor (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.grid.column.Column-method-getEditor)method to try to do what you are doing. It seems to work, but not 100% as I expect. I am still debbuging it.