PDA

View Full Version : Grid Plugin dynamically hiding columns matching "emptiness" criteria



info@viamente.com
17 Jul 2011, 4:03 AM
Hi there,

we just implemented this plugin and thought it might be useful to somebody else out there.
It's still rough on the edges but it's a start.

The goal is to hide a column if the mapped field matches a given "emptyness" criteria for all records of the underlying store.

Runtime store operations like add/update/remove/clear will dynamically show/hide columns according to the criteria.

The plugin is designed to handle grids with large amounts of data so that add/remove/update are constant-time operations.

The plugin monitors columns that define all of the following properties:


id (as per ext documentation)
dataIndex (as per ext documentation)
isEmpty: function(value, record) { /* return true if the value or record should be considered empty */ }


Here is the code:



//
// Ext.grid.GridPanel plugin that dynamically hides columns mapped to Record fields matching given hide/show criteria
//

Ext.ux.grid.EmptyColumnHider = Ext.extend(Ext.util.Observable, {
init:function(grid) {
var store = grid.getStore();
var cm = grid.getColumnModel();
var dynHideColArray = [];

// Helper function
var setHidden = function(col, hidden) {
for (var i = 0, len = cm.config.length; i < len; i++) {
if (cm.config[i] === col) {
cm.setHidden(i, hidden);
}
}
}

var reconfigure = function() {
// Performance: find out and cache which columns are configured for dynamic hiding
dynHideColArray = [];
cm.config.each(function(col) {
if (col.isEmpty && col.dataIndex && col.id) {
// Performance: add a counter to each column to keep track of non-empty rows
col.notEmptyCount = 0;
dynHideColArray.push(col);
store.each(function(rec) {
var empty = col.isEmpty(rec.get(col.dataIndex), rec);
// Performance: add a "colEmpty" object to each Record to cache empty/non-empty flags about column data
// Note: use column.id instead of column.dataIndex as key to allow multiple columns to map to the same store field and still define different hide criteria
if (!rec.colEmpty) rec.colEmpty = {};
rec.colEmpty[col.id] = empty;
if (!empty) col.notEmptyCount++;
});
setHidden(col, col.notEmptyCount <= 0);
}
});
}

var storeOnAdd = function(store, recArr) {
for (var i = 0, len = dynHideColArray.length; i < len; i++) {
var col = dynHideColArray[i];

var wasEmpty = col.notEmptyCount <= 0;

recArr.each(function(rec) {
var empty = col.isEmpty(rec.get(col.dataIndex), rec);
// Performance: add a "colEmpty" object to each Record to cache empty/non-empty flags about column data
if (!rec.colEmpty) rec.colEmpty = {};
rec.colEmpty[col.id] = empty;
if (!empty) col.notEmptyCount++;
});

if (wasEmpty && col.notEmptyCount > 0) {
setHidden(col, false);
}
}
}
var storeOnRemove = function(store, rec) {
for (var i = 0, len = dynHideColArray.length; i < len; i++) {
var col = dynHideColArray[i];

var wasEmpty = col.notEmptyCount <= 0;
var empty = rec.colEmpty[col.id];
if (!empty) col.notEmptyCount--;

if (!wasEmpty && col.notEmptyCount <= 0) {
col.notEmptyCount = 0;
setHidden(col, true);
}
}
}

var storeOnUpdate = function(store, rec, op) {
if (op !== Ext.data.Record.EDIT) {
return; // Ignore commit/reject operations
}
for (var i = 0, len = dynHideColArray.length; i < len; i++) {
var col = dynHideColArray[i];

var wasEmpty = col.notEmptyCount <= 0;
// Performance: skip check on not-modified fields
if (!rec.isModified(col.dataIndex)) continue;
var empty = col.isEmpty(rec.get(col.dataIndex), rec);
if (rec.colEmpty[col.id] != empty) {
rec.colEmpty[col.id] = empty;
col.notEmptyCount += (empty) ? -1 : +1;
}

if (wasEmpty && col.notEmptyCount > 0) {
setHidden(col, false);
}
if (!wasEmpty && col.notEmptyCount <= 0) {
setHidden(col, true);
}
}
}

var storeOnClear = function() {
for (var i = 0, len = dynHideColArray.length; i < len; i++) {
var col = dynHideColArray[i];
col.notEmptyCount = 0;
setHidden(col, true);
}
}

var registerStoreEvents = function() {
store.on('add', storeOnAdd);
store.on('remove', storeOnRemove);
store.on('update', storeOnUpdate);
store.on('clear', storeOnClear);
}

var unregisterStoreEvents = function() {
store.un('add', storeOnAdd);
store.un('remove', storeOnRemove);
store.un('update', storeOnUpdate);
store.un('clear', storeOnClear);
}

reconfigure();
registerStoreEvents();

// Listen in on grid events
grid.on('reconfigure', function(grid, newStore, newCm) {
unregisterStoreEvents();
cm = newCm;
store = newStore;
reconfigure();
registerStoreEvents();
});

}
});

PaulyWolly
13 Feb 2012, 12:45 PM
This looks like it might be a very useful plugin, if I knew how to include it and call it in my code, to hide certain fields I have that are empty in my grid. Please provide an example use case of how to use this plugin.