The code below is a plugin I wrote for Ext.grid.GridPanel
, which basically allows you to have a bit more control over how rows are striped in the grid. By default you can only have every other row in alternate colour. With this plugin you an have for example 5 in basic color, 5 in alternate and so on.
What bothers me about it, is that it basically is 100+ lines copied from Ext.grid.GridView
with no more than 10 lines of my modifications. I would love to know if there's a way to do it in a more elegant way.
My second concern is with that it's a plugin for Ext.grid.GridPanel
, but it actually modifies the underlying Ext.grid.GridView
. As far as I know, there is no way to attach a plugin to a GridView
with current framework architecture, but perhaps you DO know the way.
Legal stuff: The code is largely based on ExtJS source code, and as such it's released under GNU GPL license v3 license
MyNamespace.grid.plugins.RowStriper = Ext.extend(Object, {
constructor : function(config) {
config = config || {};
Ext.apply(this, config);
},
init : function(parent) {
if (parent instanceof Ext.grid.GridPanel) {
this.parent = parent;
this.parent.stripeInterval = this.stripeInterval;
parent.on('destroy', this.onDestroy, this);
Ext.apply(parent.getView(), this.parentViewOverrides);
}
},
onDestroy : Ext.emptyFn,
parentViewOverrides : {
doRender : function(columns, records, store, startRow, colCount, stripe) {
var templates = this.templates,
cellTemplate = templates.cell,
rowTemplate = templates.row,
last = colCount - 1;
var tstyle = 'width:' + this.getTotalWidth() + ';';
// buffers
var rowBuffer = [],
colBuffer = [],
rowParams = {tstyle: tstyle},
meta = {},
column,
record;
//build up each row's HTML
for (var j = 0, len = records.length; j < len; j++) {
record = records[j];
colBuffer = [];
var rowIndex = j + startRow;
//build up each column's HTML
for (var i = 0; i < colCount; i++) {
column = columns[i];
meta.id = column.id;
meta.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
meta.attr = meta.cellAttr = '';
meta.style = column.style;
meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
if (Ext.isEmpty(meta.value)) {
meta.value = ' ';
}
if (this.markDirty && record.dirty && Ext.isDefined(record.modified[column.name])) {
meta.css += ' x-grid3-dirty-cell';
}
colBuffer[colBuffer.length] = cellTemplate.apply(meta);
}
//set up row striping and row dirtiness CSS classes
var alt = [];
if (stripe && (rowIndex % (this.grid.stripeInterval * 2)) > (this.grid.stripeInterval - 1)) {
alt[0] = 'x-grid3-row-alt';
}
if (record.dirty) {
alt[1] = ' x-grid3-dirty-row';
}
rowParams.cols = colCount;
if (this.getRowClass) {
alt[2] = this.getRowClass(record, rowIndex, rowParams, store);
}
rowParams.alt = alt.join(' ');
rowParams.cells = colBuffer.join('');
rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams);
}
return rowBuffer.join('');
},
processRows : function(startRow, skipStripe) {
if (!this.ds || this.ds.getCount() < 1) {
return;
}
var rows = this.getRows(),
len = rows.length,
i, r;
skipStripe = skipStripe || !this.grid.stripeRows;
var stripeInterval = this.grid.stripeInterval || 1;
startRow = startRow || 0;
for (i = 0; i<len; i++) {
r = rows[i];
if (r) {
r.rowIndex = i;
if (!skipStripe) {
r.className = r.className.replace(this.rowClsRe, ' ');
if ((i % (stripeInterval * 2)) > (stripeInterval - 1)){
r.className += ' x-grid3-row-alt';
}
}
}
}
// add first/last-row classes
if (startRow === 0) {
Ext.fly(rows[0]).addClass(this.firstRowCls);
}
Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);
}
}
});