GWT-EXT: Retain Checkbox selections in page-able GridPanel
When working on a sample project for Mersoft using GWT-EXT I came across a use case that required a data table that was page-able, had a checkbox selection per row, and needed to maintain the checkbox selections when paging.
Here is what I ended up doing. It may not be pretty, but hey, its a sample.
I made a few updates to the CheckboxSelectionModel.js in order to properly update the checkbox in the Header row when a user manually (un)selects all the rows. This required that I comment out the CheckboxSelectionModel definition in the ext-all.js and include the CheckboxSelectionModel.js in my HTML. I updated the onMouseDown function as follows…
if(e.button === 0 && t.className == ‘x-grid3-row-checker’){ // Only fire if left-click
e.stopEvent();
var row = e.getTarget(‘.x-grid3-row’);
if(row){
var index = row.rowIndex;
if(this.isSelected(index)){
this.deselectRow(index);
}else{
this.selectRow(index, true);
}
//Get the CheckboxHeader so it can be updated.
//Loop through the header cells since the user may have re-ordered them…
var cbHeader = null;
var i = 0;
var view = this.grid.getView();
var headerCellEl = view.getHeaderCell(i);
while(cbHeader == null && headerCellEl != null){
if(headerCellEl.className.indexOf(‘x-grid3-td-checker’) > -1){
cbHeader = headerCellEl.firstChild;
cbHeader = Ext.fly(cbHeader);
}
headerCellEl = view.getHeaderCell(++i);
}
if (cbHeader) {
if (this.grid.getStore().getCount() == this.selections.length) {
//all the rows are selected, so check the header…
cbHeader.addClass(‘x-grid3-hd-checker-on’);
} else {
//not all the rows are selected, so uncheck the header…
cbHeader.removeClass(‘x-grid3-hd-checker-on’);
}
}
}
}
},
I also used the code from the URL http://extjs.com/forum/showthread.php?t=45723&highlight=getselectionmodel, however it too needed to be modified to update the Header checkbox.
I created a CheckBoxMemory.js with the following code and included it in my HTML…
Ext.ux.plugins.CheckBoxMemory = Ext.extend(Object, {
constructor : function(config) {
if (!config)
config = {};
this.prefix = ‘id_’;
this.items = {};
this.idProperty = config.idProperty || ‘id’;
},
init : function(grid) {
this.grid = grid;
this.view = grid.getView()
this.store = null;
this.sm = grid.getSelectionModel();
this.sm.on(‘rowselect’, this.onSelect, this);
this.sm.on(‘rowdeselect’, this.onDeselect, this);
this.view.on(‘refresh’, this.reConfigure, this);
},
reConfigure : function() {
this.store = this.grid.getStore();
this.store.on(‘clear’, this.onClear, this);
this.store.on(‘datachanged’, this.restoreState, this);
},
onSelect : function(sm, idx, rec) {
this.items[this.getId(rec)] = true;
},
onDeselect : function(sm, idx, rec) {
delete this.items[this.getId(rec)];
},
restoreState : function() {
if (this.store != null) {
var i = 0;
var sel = [];
this.store.each( function(rec) {
var id = this.getId(rec);
if (this.items[id] === true)
sel.push(i);
++i;
}, this);
if (sel.length > 0){
this.sm.selectRows(sel);
}
var cbHeader = null;
var j = 0;
var view = this.grid.getView();
var headerCellEl = view.getHeaderCell(j);
while (cbHeader == null && headerCellEl != null) {
if (headerCellEl.className.indexOf(‘x-grid3-td-checker’) > -1) {
cbHeader = headerCellEl.firstChild;
cbHeader = Ext.fly(cbHeader);
}
headerCellEl = view.getHeaderCell(++j);
}
if (cbHeader) {
if (this.store.getCount() == this.sm.selections.length) {
cbHeader.addClass(‘x-grid3-hd-checker-on’);
} else {
cbHeader.removeClass(‘x-grid3-hd-checker-on’);
}
}
}
},
onClear : function() {
var sel = [];
this.items = {};
},
getId : function(rec) {
return rec.get(this.idProperty);
}
});
I have not had a chance to really dive in ,but you will need to make sure that your RecordDef has a FieldDef with a name of “id”, example… new StringFieldDef(”id”, 0)
I then created the corresponding Java class as follows.
import com.google.gwt.core.client.JavaScriptObject;
import com.gwtext.client.widgets.Component;
import com.gwtext.client.widgets.ComponentPlugin;
public class CheckBoxMemoryPlugin extends ComponentPlugin {
public CheckBoxMemoryPlugin() {
jsObj = create();
}
protected native JavaScriptObject create() /*-{
return new $wnd.Ext.ux.plugins.CheckBoxMemory();
}-*/;
@Override
public void init(Component component) {
}
}
Then you just need to add the CheckBoxMemoryPlugin to the GridPanel. (This assumes that you already have set up a Local Paging Checkbox Grid Panel)
Anyway, I hope this helps someone else who may be looking to solve this.
I still need to update the code in order to be able to get the selected row IDs, but that is for another day.