PDA

View Full Version : RowEditor - Configure which columns are editable based on record data?



watermark
10 Jul 2012, 1:03 PM
Ext 4.1

I have a grid where the some columns are editable and some aren't based on another field in the record. So row 1 might have columns 1-3 editable, and row 2 might only have columns 2-5 editable. Is there a way I can dynamically set columns as editable or not...possibly somehow in a beforeedit event?

I've already tried to trace the source to figure this out, but I'm a bit lost. Changing the "field" attribute on the column in real-time doesn't seem to do the trick.

jay@moduscreate.com
10 Jul 2012, 1:39 PM
I think you can do this with the before edit event.

jratcliff
10 Jul 2012, 4:31 PM
like you suspect and like Jay said, you just need to add a 'beforeedit' event listener to your grid and in your code you can decide whether or not to let the edit happen. If you return false, the editor will not be created and no editing will be able to happen.

http://docs.sencha.com/ext-js/4-1/#!/api/Ext.grid.plugin.Editing-event-beforeedit

watermark
11 Jul 2012, 4:50 AM
I need to dynamically set which *columns* are editable in the grid based on record data. So row 1 might have different editable columns than row 2.

Returning false would prevent an entire row from being editable, which is not what I need.

jratcliff
11 Jul 2012, 7:08 AM
Did you try any code? :-?

Here's an example for you:



Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
fields:['name', 'email', 'phone'],
data:{'items':[
{ 'name': 'Lisa', "email":"lisa@simpsons.com", "phone":"555-111-1224" },
{ 'name': 'Bart', "email":"bart@simpsons.com", "phone":"555-222-1234" },
{ 'name': 'Homer', "email":"home@simpsons.com", "phone":"555-222-1244" },
{ 'name': 'Marge', "email":"marge@simpsons.com", "phone":"555-222-1254" }
]},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});

Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [
{
text: 'Name',
dataIndex: 'name',
editor: {
allowBlank: false
}
},
{
text: 'Email',
dataIndex: 'email',
flex: 1,
editor: {
allowBlank: false
}
},
{
text: 'Phone',
dataIndex: 'phone',
editor: {
allowBlank: false
}
}
],
height: 200,
width: 400,
renderTo: Ext.getBody(),
plugins: [Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})],
listeners: {
'beforeedit' : function (editor, e) {
// you can't edit the email address of the first row
if (e.rowIdx === 0 && e.colIdx === 1) {
alert('you cannot edit Lisa\'s email address');
return false;
}

// you can't change Bart's phone number
if (e.record.get('name') === 'Bart' && e.colIdx === 2) {
alert('you cannot edit Bart\'s phone number');
return false
}

// you can't edit anythig of Homer's
if (e.record.get('name') === 'Homer') {
alert('you cannot edit anything of Homer');
return false;
}

return true;
}
}
});


This works in Ext 4. However, what I don't like is that it breaks tabbing. In Ext 3.x you could just add a custom isCellEditable method to the column model and from there you could conditionally decide if a cell was editable or not and the good thing with that, is that if it wasn't editable, the tabbing would still work by just trying the next cell. So I'll have to ask the core devs how to do this now in Ext 4.

But, in the meantime, if you can live with tabbing breaking, then this code will work for you.

watermark
11 Jul 2012, 7:30 AM
Ah, I think the miscommunication is coming in for cell vs row editor. Perhaps using a cell editor would be simpler. As the rest of the app is using a row editor, I'd prefer to use a row editor here as well. Any ideas on how I could use a row editor for this, or should I just give it up and use the cell editor?

jratcliff
11 Jul 2012, 8:28 AM
Ah, I think the miscommunication is coming in for cell vs row editor. Perhaps using a cell editor would be simpler. As the rest of the app is using a row editor, I'd prefer to use a row editor here as well. Any ideas on how I could use a row editor for this, or should I just give it up and use the cell editor?

Ahh!! my apologies. Let me dig around some more and see if a solution can be found. :)

jratcliff
11 Jul 2012, 2:08 PM
ok, how about this code. Basically, I modify the loadRecord method of Ext.grid.RowEditor to dynamically change the editor based on a value in the record. When that's done, I call the overridden method so it can continue on and do its thing.



Ext.override(Ext.grid.RowEditor, {
loadRecord: function(record) {
var me = this,
gridCols = me.context.grid.headerCt.getGridColumns(),
i, length;


switch (record.get('name')) {

// you can't change Bart's phone number
case 'Bart' :
for (i = 0, length = gridCols.length; i < length; i++) {
if (gridCols[i].dataIndex === 'phone') {
gridCols[i].setEditor({xtype:'displayfield'});
} else {
gridCols[i].setEditor({xtype:'textfield'});
}
}
break;

// you can't edit anythig of Homer's
case 'Homer' :
for (i = 0, length = gridCols.length; i < length; i++) {
gridCols[i].setEditor({xtype:'displayfield'});
}
break;

// all columns are editable
default:
for (i = 0, length = gridCols.length; i < length; i++) {
gridCols[i].setEditor({xtype:'textfield'});
}

}

me.callParent(arguments);

},

});

Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
fields:['name', 'email', 'phone'],
data:{'items':[
{ 'name': 'Lisa', "email":"lisa@simpsons.com", "phone":"555-111-1224" },
{ 'name': 'Bart', "email":"bart@simpsons.com", "phone":"555-222-1234" },
{ 'name': 'Homer', "email":"home@simpsons.com", "phone":"555-222-1244" },
{ 'name': 'Marge', "email":"marge@simpsons.com", "phone":"555-222-1254" }
]},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});

Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [
{
text: 'Name',
dataIndex: 'name',
editor: {
xtype: 'displayfield'
}
},
{
text: 'Email',
dataIndex: 'email',
flex: 1,
editor: {
allowBlank: false
}
},
{
text: 'Phone',
dataIndex: 'phone',
editor: {
allowBlank: false
}
}
],
height: 200,
width: 400,
renderTo: Ext.getBody(),
plugins: [Ext.create('Ext.grid.plugin.RowEditing', {
clicksToMoveEditor: 1,
autoCancel: false
})]

});