PDA

View Full Version : Problem sorting paging grid



Jangla
10 Jul 2009, 8:19 AM
I have a grid which reads from a JsonStore (you'll notice I changed the defaultParamNames in an effort to solve my problem but it hasn't helped). The store has a default sort on it so the grid is rendered with the records in a sensible order to begin with:



gridStore = new Ext.data.JsonStore({
root : 'results',
defaultParamNames : {dir: 'sortDir', sort: 'sortCol'},
totalProperty : 'total',
id : 'propertyId',
remoteSort : true,
fields: [
{name : "propertyId", type: 'int', mapping: 'propertyId'},
{name : "propertyImage", mapping: 'propertyImage'},
{name : "propertyName", type: 'string', mapping: 'propertyName'},
{name : "capacity", type: 'string', mapping: 'capacity'},
{name : "region", type: 'string', mapping: 'region'},
{name : "country", type: 'string', mapping: 'country'},
{name : "guidePrice", type: 'string', mapping: 'guidePrice'},
{name : "price"},
{name : "property-details", type: 'string', mapping: 'propertyName'}
],
proxy : new Ext.data.ScriptTagProxy({
url : 'index.php?eID=tx_supersearch_pi1&mode=grid'
})
});
gridStore.setDefaultSort('capacity', 'desc');

This store populates a grid which has a toolbar rather than column headers to allow sorting on it without having to have several columns - I use a template to collate a bunch of data on the grid:



grid = new Ext.grid.GridPanel
({
id : 'results-grid',
region : 'center',
border : false,
collapsed : false,
collapsible : false,
titleCollapse : false,
animCollapse : false,
floatable : false,
bodyStyle : 'padding:0;',
margins : '1 0 1 1',
cmargins : '1 1 1 1',
border : false,
height : 492,
width : 426,
title : '',
enableColumnHide : false,
enableColumnMove : false,
enableColumnResize : false,
enableHdMenu : false,
header : false,
hideHeaders : true,
store : gridStore,
loadMask : {msg:"Loading properties..."},
viewConfig : {
headersDisabled : true
},
columns :
[{
header : 'Property Image',
dataIndex : 'propertyImage',
loadingMask : true,
width : 115,
readOnly : true,
renderer : renderPropertyImage,
sortable : true
},{
header : 'Property Details',
readOnly : true,
dataIndex : 'property-details',
renderer : renderPropertyDetails,
width : 309,
hidden : false,
readOnly : true,
sortable : true
}],
sm : new Ext.grid.RowSelectionModel({singleSelect:true}),
tbar:[{
text : 'Sort by capacity',
id : 'toolbar-sort-capacity',
tooltip : 'Click to sort by capacity',
cls : 'x-btn-text-icon',
icon : 'fileadmin/templates/images/sortasc.gif',
handler : function(e) {
var sortState = gridStore.getSortState();
var newDirection = (sortState.direction != 'desc') ? 'desc' : 'asc';
refreshGridStore(true, 'capacity');
}
}, '-', {
text : 'Sort by max price',
id : 'toolbar-sort-price',
tooltip : 'Click to sort by weekly price',
cls : 'x-btn-text-icon',
icon : 'fileadmin/templates/images/sortasc.gif',
handler : function(e) {
var sortState = gridStore.getSortState();
var newDirection = (sortState.direction != 'desc') ? 'desc' : 'asc';
refreshGridStore(true, 'price');
}
},'-',{
text : 'Sort by country/region',
tooltip : 'Click to sort by country/region',
cls : 'x-btn-text-icon',
icon : 'fileadmin/templates/images/sortasc.gif',
handler : function(e) {
var sortState = gridStore.getSortState();
var newDirection = (sortState.direction != 'desc') ? 'desc' : 'asc';
refreshGridStore(true, 'country');
}
}],
bbar : pagingBar,
});
The refreshGrid function is designed to examine the current sort direction and reverse it:



function refreshGridStore(changeDirection, column) {

if ( gridStore.getSortState() ) {
var sortState = gridStore.getSortState();
var newDirection = (sortState.direction != 'desc') ? 'desc' : 'asc';
} else {
var newDirection = 'asc';
}


var minCapacity;
if ( Ext.getCmp('minCap').value ) {
minCapacity = Ext.getCmp('minCap').value;
} else {
minCapacity = 0;
}

var maxPrice;
if ( Ext.getCmp('maxPrice').value ) {
maxPrice = Ext.getCmp('maxPrice').value;
} else {
maxPrice = 999999999999;
}

if ( changeDirection ) {
gridStore.load({params:{start:0, limit:5, sortDir: newDirection, sortCol: column, maxPr: maxPrice, minCap: minCapacity}});
} else {
gridStore.load({params:{start:0, limit:5, sortDir: sortState.direction, sortCol: column, maxPr: maxPrice, minCap: minCapacity}});
}

}


The issue is that without a setDefaultSort defined on the store, it seems to be impossible to pick up the sort state of the grid - it always returns undefined. If I do define a setDefaultSort value then no matter what sort column or direction I tell it to use, it always uses the default! I've no idea why this is!!!

If it helps, the initial load of the store is called like this:



propertyGrid.on({
render : {
fn : function() {
gridStore.load({params:{start:0, limit:5, sortDir: 'desc', sortCol: 'capacity', maxPr: 9999999999, minCap: 0}});
}
}
});

Jangla
13 Jul 2009, 4:48 AM
Anyone able to help on this?

It appears that unless you set a default sort, you can't get the sort state of the store and when you do set a default sort state, you can't change those for subsequent sorts.

Condor
13 Jul 2009, 7:30 AM
Normally, you don't load a store with a different sort order; you call store.sort().

But, since you also want to send different parameters you'll have to set the new sort order manually using store.setDefaultSort().

store.setDefaultSort(column, changeDirection ? newDirection : sortState.direction);
gridStore.load({params:{start:0, limit:5, maxPr: maxPrice, minCap: minCapacity}});

Note that you don't have to supply the sortCol and sortDir as parameters.

Jangla
14 Jul 2009, 6:41 AM
Seems there's a problem with this approach - the paging toolbar reverts to the full data set when you click the next button, wiping out any active filters such as min price. Is there any way of hooking into the next, prev, first and last actions of the toolbar so I can run the same function as I do for the filters? Or do I need a different approach completely?

Condor
14 Jul 2009, 6:46 AM
Yes, if you want to keep filters during paging you'll have to use:


store.setDefaultSort(column, changeDirection ? newDirection : sortState.direction);
store.setBaseParam('maxPr', maxPrice);
store.setBaseParam('minCap', minCapacity);
gridStore.load({params:{start:0, limit:5}});