View Full Version : CheckboxSelectionModel header & sortable

28 Dec 2009, 1:31 AM
Hi Forum, I have been looking for a solution on the forums for some time, and cannot find it. As per the docs you can set the header of the CheckBoxSelectionModel column to be something else than 'check all/none'. I have tried this the way I think it should work (taking imput from this (http://www.extjs.com/forum/showthread.php?t=26285) thread)

Here is my code: in FF 3.5 on linux it shows me a checkbox with 'jopie' written on top of it. Where I would expect the checkbox behind it to be gone and the column should be sortable. What am i doing something wrong here?

* Ext JS Library 3.1.0
* Copyright(c) 2006-2009 Ext JS, LLC
* [email protected]
* http://www.extjs.com/license



var xg = Ext.grid;

// shared reader
var reader = new Ext.data.ArrayReader({}, [
{name: 'company'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'},
{name: 'industry'},
{name: 'desc'}

// Grid 2
var sm = new xg.CheckboxSelectionModel({
header: '<div class="">jopie</div>'
,sortable: true
var grid2 = new xg.GridPanel({
store: new Ext.data.Store({
reader: reader,
data: xg.dummyData
cm: new xg.ColumnModel({
defaults: {
width: 120,
sortable: true
columns: [
{id:'company',header: "Company", width: 200, dataIndex: 'company'},
{header: "Price", renderer: Ext.util.Format.usMoney, dataIndex: 'price'},
{header: "Change", dataIndex: 'change'},
{header: "% Change", dataIndex: 'pctChange'},
{header: "Last Updated", width: 135, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
sm: sm,
columnLines: true,
title:'Framed with Checkbox Selection and Horizontal Scrolling',
renderTo: document.body


// Array data for the grids
Ext.grid.dummyData = [
['3m Co',71.72,0.02,0.03,'9/1 12:00am', 'Manufacturing'],
['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am', 'Manufacturing'],
['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am', 'Manufacturing'],
['American Express Company',52.55,0.01,0.02,'9/1 12:00am', 'Finance'],
['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am', 'Services'],
['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am', 'Services'],
['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am', 'Manufacturing'],
['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am', 'Services'],
['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am', 'Finance'],
['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am', 'Manufacturing'],
['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am', 'Manufacturing'],
['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am', 'Manufacturing'],
['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am', 'Automotive'],
['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am', 'Computer'],
['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am', 'Manufacturing'],
['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am', 'Computer'],
['International Business Machines',81.41,0.44,0.54,'9/1 12:00am', 'Computer'],
['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am', 'Medical'],
['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am', 'Finance'],
['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am', 'Food'],
['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am', 'Medical'],
['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am', 'Computer'],
['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am', 'Services', 'Medical'],
['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am', 'Food'],
['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am', 'Retail'],
['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am', 'Manufacturing'],
['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am', 'Computer'],
['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am', 'Services'],
['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am', 'Retail'],
['Walt Disney Company (The) (Holding Company)',29.89,0.24,0.81,'9/1 12:00am', 'Services']

// add in some dummy descriptions
for(var i = 0; i < Ext.grid.dummyData.length; i++){
Ext.grid.dummyData[i].push('Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed metus nibh, sodales a, porta at, vulputate eget, dui. Pellentesque ut nisl. Maecenas tortor turpis, interdum non, sodales non, iaculis ac, lacus. Vestibulum auctor, tortor quis iaculis malesuada, libero lectus bibendum purus, sit amet tincidunt quam turpis vel lacus. In pellentesque nisl non sem. Suspendisse nunc sem, pretium eget, cursus a, fringilla vel, urna.<br/><br/>Aliquam commodo ullamcorper erat. Nullam vel justo in neque porttitor laoreet. Aenean lacus dui, consequat eu, adipiscing eget, nonummy non, nisi. Morbi nunc est, dignissim non, ornare sed, luctus eu, massa. Vivamus eget quam. Vivamus tincidunt diam nec urna. Curabitur velit.');

28 Dec 2009, 1:45 AM
You should give the grid a cls (e.g. cls:'hide-cb-header') and add a css rule for it, e.g.

.hide-cb-header .x-grid3-hd-checker {background-image: none;}

28 Dec 2009, 2:41 AM
Thanks Condor, i added:

cls: 'hide-cb-header'
to the GridPanel, and the header is now displayed fine.

The 'sortable in:

var sm = new xg.CheckboxSelectionModel({
header: '<div class="">jopie</div>'
,sortable: true

doesn't seem to be doing anything...any thoughts?
This is the behavior I am looking for, sort on checked / unchecked
as per the docs:
sortable (http://www.extjs.com/forum/../deploy/dev/docs/source/CheckboxSelectionModel.html#cfg-Ext.grid.CheckboxSelectionModel-sortable) : Booleantrue if the checkbox column is sortable (defaults to false)

28 Dec 2009, 3:30 AM
sortable:true makes the column sortable by it's dataIndex. CheckboxSelectionModel doesn't have a dataIndex, so it can't be sorted.

Wouldn't it be easier to use a Ext.ux.grid.CheckColumn instead of a CheckboxSelectionModel? It's both sortable and doesn't have a header checkbox.

28 Dec 2009, 3:58 AM
Condor, Thanks
Sortable, I understand.

Your suggestion:

Wouldn't it be easier to use a Ext.ux.grid.CheckColumn instead of a CheckboxSelectionModel? It's both sortable and doesn't have a header checkbox.seems logical, but I don't really want to save my selections if I don't have to.

What I am looking to build is a mail-a-friend window, which allows for selection of recipients in the grid. I have already found the checkboxmemory plugin to remember selections across pages, now all i need is to give the user an opportunity to see which ones are currently selected. Since sorting on 'selected rows' doesn't work out of the box, and would only have been 'good enough' until you select more than one page, I think i am going to have to come up with some additional window or popup to show the current selection.

I'll post here what I came up with.

28 Dec 2009, 4:10 AM
I don't see why using CheckColumn would be a problem in this case (you only need to add one extra field to your record that holds the checkbox value).

31 Dec 2009, 5:15 AM

I am using a remote store and as I understand it, when i add a column to the store so I can sort on it, I have to do this on the server (php/symfony). because the data is not relevant for the server, i don't want that.

The solution I have come up with is this one:
Use the selections of the grid to get a subset of the data from the server with a button 'show selection'.
I am left with getting the paging to work with this subset, but I'm sure i'll find that out.

Even though i am obviously not an expert, here is the code for reference (by all means comment). Sorry all the labels are in dutch.

var mafWindow;
var messagePanel;
var listPanel;

function showMafWindow( listUrl, formAction )

var sm = new Ext.grid.CheckboxSelectionModel();

// idea grid
MailAFriend.userGrid = Ext.extend(Ext.grid.GridPanel, {
initComponent:function() {
var config = {
store:new Ext.data.JsonStore({
url: listUrl,
root: 'result',
totalProperty: 'total',
idIndex: 'id',
fields: [
'id','FullName', 'PrimaryGroupName'
field: 'id',
direction: "DESC"
// turn on remote sorting
,remoteSort: true
,columns: [
header: "ID",
dataIndex: 'id',
width: 10,
sortable: true
header: "Naam",
dataIndex: 'FullName',
width: 120,
sortable: true
header: "Team",
dataIndex: 'PrimaryGroupName',
sortable: true
,sm: sm
,loadMask : {
,viewConfig: { forceFit: true }
,plugins: [ new Ext.ux.grid.Search({
// ,readonlyIndexes:['note']
,position: 'top'
,emptyText: EMPTY_TEXT
}), new Ext.ux.plugins.CheckBoxMemory() ]
}; // eo config object

// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));

this.bbar = new Ext.PagingToolbar({

this.tbar = new Ext.Toolbar();

// call parent
MailAFriend.userGrid.superclass.initComponent.apply(this, arguments);

} // eo function initComponent


Ext.reg('mafGrid', MailAFriend.userGrid);

// if(!mafWindow) {

var messagePanel = new Ext.FormPanel({
region: 'center',
title: 'Bericht',
// deferredRender: false,
plain: true,
//width: 200,
//autoScroll: true,
url: formAction,
bodyStyle: 'padding: 10px;',
//margins:'3 0 3 3',
labelWidth: 100,
defaults: {
msgTarget: 'top'
labelAlign: 'top',
items: [
xtype: 'textfield',
name: 'title',
fieldLabel: 'Titel ',
allowBlank: false
,anchor: '100%'
xtype: 'textarea',
name: 'message',
fieldLabel: 'Bericht',
allowBlank: false
,anchor: '100% 50%'

var mafWindow = new Ext.Window({
id : 'mafWindow',
title : 'Mail a Friend',
layout : 'border',
width : 600,
height : 600,
//autoScroll : true,
closeAction :'close',
plain : true,
split : true,
items : [ messagePanel,
,id: 'mafGrid'
,split: true
,collapsible: true
,region: 'south'
,height: 310
modal : true,
buttons: [
text: 'Toon selectie'
,handler: function(){
var grid = Ext.getCmp('mafGrid');
var friends = grid.plugins[1].items;
var arrFriends = new Array();
for( x in friends)
fields: Ext.encode(new Array('id'))
,query: Ext.encode(arrFriends)
text: 'Toon alles'
,handler: function(){
params: {
text: 'Verstuur',
handler: function(){
var friends = Ext.getCmp('mafGrid').plugins[1].items
var arrFriends = new Array();
for( x in friends)

if(arrFriends.length < 1)
errorMessage('teninste 1 geaddresseerde moet worden aangevinkt')
} else {
var Form = messagePanel.getForm()
url : messagePanel.url,
//scope : mafWindow,
success : mafWindow.onSuccess,
failure : mafWindow.showError,
params : {
friendlist : Ext.encode(arrFriends)
waitMsg : WAIT_TEXT,
waitTitle : WAIT_TITLE
text: 'Sluiten',
handler: function(){
* Success handler
* @param {Ext.form.BasicForm} form
* @param {Ext.form.Action} action
* @private
onSuccess:function(form, action) {
msg:'de mail is succesvol verstuurd',
}, // eo function onSuccess
* Shows Message Box with error
* @param {String} msg Message to show
* @param {String} title Optional. Title for message box (defaults to Error)
* @private
showError:function(form, action) {
} // eo function showError
// } else {
// messagePanel.getForm().reset();
// messagePanel.url = formAction;
// }

function errorMessage(text) {

1 Jan 2010, 11:47 PM
A CheckboxSelectionModel doesn't work very well with paging (it looses all selections when switching to another page). There is however a user extension that allows selections across pages.

Some notes about your code:
1. You are creating a custom component inside the showMafWindow method. The whole point of creating a custom component is to define it once and instantiate it multiple times. This means you should either move your MailAFriend.userGrid class outside the function (if you are planning to use it multiple times) or create a configured GridPanel inside your mafWindow window (if you only use it once)!
2. Why does the showMafWindow method contain an Ext.onReady? How are you calling this method?

ps. Nederlandse labels zijn geen probleem. Labels in het chinees of uit een een of ander oostblokland die ik zo nu en dan op dit forum zie zijn een stuk moeilijker leesbaar.

2 Jan 2010, 11:41 AM
I know about the checkboxmodel and the paging;
I found the extension:
... ,new Ext.ux.plugins.CheckBoxMemory() ]

Thanks for you tips, will refactor.