Reputation: 35
I am trying to hide the column if all the cells in the column are empty. I am trying to do this in the column listener by iterating through the store but I guess the store isnt populated at that time. any suggestions to achieve this functionality?
Ext.define('com.abc.MyGrid' , { extend: 'Ext.grid.Panel', store : 'MyStore', columns : [{ text : 'col1', sortable : true, dataIndex : 'col1' }, { text : 'col2 ', sortable : true, dataIndex : 'col2', listeners:{ "beforerender": function(){ console.log(this.up('grid').store); this.up('grid').store.each(function(record,idx){ // if all are null for record.get('col1') // hide the column console.log(record.get('col1')); }); } } } })
But this is isnt working. Basically the store loop in the column listener "before render" is not executing where as the above console(this.up('grid').store) prints the store with values.
Upvotes: 0
Views: 1643
Reputation: 3959
Here you go, it doesn't handle everything but should be sufficient.
Ext.define('HideColumnIfEmpty', {
extend: 'Ext.AbstractPlugin',
alias: 'plugin.hideColumnIfEmpty',
mixins: {
bindable: 'Ext.util.Bindable'
},
init: function(grid) {
this.grid = grid;
this._initStates();
this.grid.on('reconfigure', this._initStates, this);
},
_initStates: function(store, columns) {
var store = this.grid.getStore(),
columns = this.grid.columns;
this.bindStore(store);
this.columns = columns;
if(store.getCount() > 0) {
this._maybeHideColumns();
}
},
/**
*@implement
*/
getStoreListeners: function() {
return {
load: this._maybeHideColumns
};
},
_maybeHideColumns: function() {
var columns = this.columns,
store = this.store,
columnKeysMc = new Ext.util.MixedCollection();
Ext.Array.forEach(columns, function(column) {
columnKeysMc.add(column.dataIndex, column);
});
Ext.Array.some(store.getRange(),function(record){
//don't saw off the branch you are sitting on
//eachKey does not clone
var keysToRemove = [];
columnKeysMc.eachKey(function(key) {
if(!Ext.isEmpty(record.get(key))) {
keysToRemove.push(key);
}
});
Ext.Array.forEach(keysToRemove, function(k) {
columnKeysMc.removeAtKey(k);
});
return columnKeysMc.getCount() === 0;
});
columnKeysMc.each(function(column) {
column.hide();
});
}
});
Here is an example:
Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
fields:['name', 'email', 'phone'],
data:{'items':[
{ 'name': 'Lisa', "email":"[email protected]", "phone":"555-111-1224" },
{ 'name': 'Bart', "email":"[email protected]", "phone":"555-222-1234" },
{ 'name': 'Homer', "email":"[email protected]", "phone":"555-222-1244" },
{ 'name': 'Marge', "email":"[email protected]", "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' },
{ text: 'Email', dataIndex: 'email', flex: 1 },
{ text: 'Phone', dataIndex: 'phone' },
{ text: 'Says Doh', dataIndex: 'saysDoh'}
],
plugins: {ptype: 'hideColumnIfEmpty'},
height: 200,
width: 400,
renderTo: Ext.getBody()
});
You can see in the example that saysDoh column is hidden.
Upvotes: 2
Reputation: 4431
If you want to iterate over the store, you need to put a listener on the load
event of your store. The beforerender doesn't mean that your store is already loaded.
I would put the creation of you store in the initComponent. Something like this:
Ext.define('com.abc.MyGrid', {
extend: 'Ext.grid.Panel',
columns: [{
text: 'col1',
sortable: true,
dataIndex: 'col1'
}, {
text: 'col2 ',
sortable: true,
dataIndex: 'col2'
},
initComponent: function () {
var me = this;
//Create store
var myStore = Ext.create('MyStore');
myStore.load(); // You can remove this if autoLoad: true on your store.
//Listen to load event (fires when loading has completed)
myStore.on({
load: function (store, records, success) {
store.each(function (record, idx) {
console.log(record.get('col1'));
});
}
});
//Apply the store to your grid
Ext.apply(me, {
store: myStore
});
me.callParent();
}
});
Upvotes: 0