PDA

View Full Version : Customizing Grid Cells



sanmatp
18 Dec 2006, 4:53 AM
Grid uses a same .css attribute for all cells in a column.
How can I customize Grid Cell display attributes based on certain conditions, within the same column.
For example:
If I want make some cells editable and others not editable within same column, how can I do that?
If I want to make some cells (not just text) one color and other cells different color, how can I do that?

davida
18 Dec 2006, 6:00 AM
I've had a similar need - for cells displayed differently than others. I do it to show the edit/update status of editable cells.

My solution is a little complex but seems to work fairly well:
I keep a table of "cell states" that's indexed by a key made from rowId and column field name (from the data model). I don't use rowIndex/colIndex as the key because it breaks if you sort the data or reorder the columns.
For various state changes I update the corresponding cell's state: posted an update to the server, got a success response, got a fail response (haven't figured out the "timeout" state change yet).
I use a custom renderer on these cells which looks up the cell's state if it exists and then simply adds a style to the cell's TD element to render it differently.

There are a couple of issues with this approach:
After a cell's state changes, I need to manually "touch" it to force a refresh (via dataModel.setValueAt). This is because the state can change without the value changing.
There isn't a nice way to map to/from the data model field name and the column index. To get the field name I dig into dataModel.schema.fields and to do the reverse mapping I loop through the field list to find the index with the matching value.
I had to look into the source code to realize that a renderer actually gets called with value, rowIndex, colIndex and td - the table element. I never saw that documented anywhere. Yes you can return a span for the cell's rendered value which works fine for foreground styles but doesn't work so well for background styles since I wanted the entire cell to change color.

Maybe someone reading this will point out a simpler way. If not I can post the relevant code snippets.

sanmatp
18 Dec 2006, 6:25 AM
Thanks Dave for your response!

How do you add a style to the cell's TD element to render it differently?

I have a renderer that checks for state and changes color. But I could not change color of the entire cell. This is what I do in my renderer,


this.displayEditCell = function(cell, row, col) {
rtn = "";
if (currGrid.dataModel.getRowCount() > 0) {
var color = currGrid.dataModel.getValueAt(row, 7);
if (color == null)
{
rtn = cell;
}
else if (color == "Yellow")
{
rtn = '<span style="background-color: yellow">' + cell + '</span>';
}
else if (color == "Blue")
{
rtn = '<span style="background-color: blue">' + cell + '</span>';
}
else if (color == "Green")
{
rtn = '<span style="background-color: green">' + cell + '</span>';
}
else
{
rtn = cell;
}
return rtn;
}

I still need a solution for Marking some cells editable and other not-editable as my header definition is like,

{header: "MyHeaderName", width: 126, sortable: false, renderer:this.displayEditCell, editor: new YAHOO.ext.grid.TextEditor({allowBlank:false})},

This makes all cells within a column editable.

Thanks
Sanmat

davida
18 Dec 2006, 9:09 AM
Sanmat,
Here's what I'm doing in my renderer. The trick is that the renderer function is actually passed the td element of the cell so if you add that argument to your function, you can manipulate it directly. Note that I start off by always clearing the color and background and then resetting them based on the cell status.



var select_renderer = function(select_id) {
return function(value, rowIndex, colIndex, td) {
cell = getCellStateByRC(rowIndex, colIndex);
if (cell.current) {
value = cell.current;
}
options = document.getElementById(select_id).options;
for (var i = 0; i < options.length; i++) {
if (options[i].value == value) {
YAHOO.util.Dom.setStyle(td, 'color', '');
YAHOO.util.Dom.setStyle(td, 'background', '');
if (cell.status == 'error') {
YAHOO.util.Dom.setStyle(td, 'background', 'red');
} else if (cell.status == 'pending') {
YAHOO.util.Dom.setStyle(td, 'background', 'yellow');
} else if (cell.status == 'changed') {
YAHOO.util.Dom.setStyle(td, 'color', 'green');
}
return options[i].text;
}
}
return "??";
};
};

sanmatp
18 Dec 2006, 10:01 AM
Thanks Dave

Thanks for attaching the snippet. I will try it.

I still need a solution for Marking some cells editable and other not-editable as my header definition is like,

{header: "MyHeaderName", width: 126, sortable: false, renderer:this.displayEditCell, editor: new YAHOO.ext.grid.TextEditor({allowBlank:false})},

This makes all cells within a column editable.

If you already know the answer, please respond.

Thanks
Sanmat

jack.slocum
18 Dec 2006, 10:56 AM
The default implementation of isCellEditable returns true if the cell has an editor. I do try to think ahead though and isCellEditable gets a col and row index so you can selectively enable edits by row.


yourColModel.isCellEditable = function(colIndex, rowIndex){
// return true if editable, otherwise false
}

davida
18 Dec 2006, 1:41 PM
I do try to think ahead though ....

Understatement of the year.

innovator
22 Sep 2008, 10:28 PM
Understatement of the year.
I too need a solution for Marking some cells editable and other not-editable in the same column.
Plz suggest any approach...........

mystix
22 Sep 2008, 11:01 PM
I too need a solution for Marking some cells editable and other not-editable in the same column.
Plz suggest any approach...........

http://extjs.com/forum/showthread.php?p=206408#post206408

an2ny21
8 Oct 2009, 2:12 AM
you could use an editor grid panel if you just want certain columns to edit and not all in the row.
for example;
tbox = new Ext.form.TextField({});

grid = new Ext.grid.EditorGridPanel({
//i will just go straight to the columns definition
columns: [
{header: 'Test', dataIndex: 'test', editor: tbox}
]
})

that's it. however the changes made to the data is not automatically saved. so you still need to put a code that saves the changes.