Skip to content

Instantly share code, notes, and snippets.

@gsouf
Created May 22, 2013 06:43
Show Gist options
  • Save gsouf/5625682 to your computer and use it in GitHub Desktop.
Save gsouf/5625682 to your computer and use it in GitHub Desktop.
ExtJs MultiSortToolbar (for architect)
// this is a multisortToolbr which should override a basical toolbar. It can be added as toolbar for a grid. Then you can drop columns from the column model of the grid and it will sort grid as following example : http://docs.sencha.com/extjs/4.2.0/extjs-build/examples/build/KitchenSink/ext-theme-neptune/#multi-sort-grid.
// It is almost an adapted version of the code used in the example.
Ext.define('myApp.view.override.MultiSortToolbar', {
override: 'myApp.view.MultiSortToolbar',
requires: [
'Ext.data.*',
'Ext.grid.*',
'Ext.util.*',
'Ext.toolbar.*',
'Ext.ux.ToolbarDroppable',
'Ext.ux.BoxReorderer'
],
initComponent: function() {
var me = this;
me.on({
// wait for the first layout to access the headerCt (we only want this once):
single: true,
// tell the toolbar's droppable plugin that it accepts items from the columns' dragdrop group
afterlayout: function(tbar) {
var headerCt = tbar.up("grid").child("headercontainer");
droppable.addDDGroup(headerCt.reorderer.dragZone.ddGroup);
me.doSort();
}
});
var reorderer = Ext.create('Ext.ux.BoxReorderer', {
listeners: {
Drop: function(r, c, button) { //update sort direction when button is dropped
me.changeSortDirection(button, false);
}
}
});
var droppable = Ext.create('Ext.ux.ToolbarDroppable', {
/**
* Creates the new toolbar item from the drop event
*/
createItem: function(data) {
var header = data.header,
headerCt = header.ownerCt,
reorderer = headerCt.reorderer;
// Hide the drop indicators of the standard HeaderDropZone
// in case user had a pending valid drop in
if (reorderer) {
reorderer.dropZone.invalidateDrop();
}
return me.createSorterButtonConfig({
text: header.text,
sortData: {
property: header.dataIndex,
direction: "ASC"
}
});
},
/**
* Custom canDrop implementation which returns true if a column can be added to the toolbar
* @param {Object} data Arbitrary data from the drag source. For a HeaderContainer, it will
* contain a header property which is the Header being dragged.
* @return {Boolean} True if the drop is allowed
*/
canDrop: function(dragSource, event, data) {
var sorters = me.getSorters(),
header = data.header,
length = sorters.length,
entryIndex = this.calculateEntryIndex(event),
targetItem = this.toolbar.getComponent(entryIndex),
i;
// Group columns have no dataIndex and therefore cannot be sorted
// If target isn't reorderable it could not be replaced
if (!header.dataIndex || (targetItem && targetItem.reorderable === false)) {
return false;
}
for (i = 0; i < length; i++) {
if (sorters[i].property == header.dataIndex) {
return false;
}
}
return true;
},
afterLayout: function () {
me.doSort();
}
});
Ext.applyIf(me, {
plugins: [ droppable,reorderer],
items:[
// defaultly empty. It allows to be smallest when not used
],
});
me.callParent(arguments);
},
/**
* Returns an array of sortData from the sorter buttons
* @return {Array} Ordered sort data from each of the sorter buttons
*/
getSorters: function () {
var sorters = [];
Ext.each(this.query('button'), function(button) {
sorters.push(button.sortData);
}, this);
return sorters;
},
/**
* Convenience function for creating Toolbar Buttons that are tied to sorters
* @param {Object} config Optional config object
* @return {Object} The new Button configuration
*/
createSorterButtonConfig: function (config) {
var me = this;
config = config || {};
Ext.applyIf(config, {
listeners: {
click: function(button, e) {
me.changeSortDirection(button, true);
}
},
iconCls: 'sort-direction-' + config.sortData.direction.toLowerCase(),
reorderable: true,
xtype: 'button'
});
return config;
},
/**
* Callback handler used when a sorter button is clicked or reordered
* @param {Ext.Button} button The button that was clicked
* @param {Boolean} changeDirection True to change direction (default). Set to false for reorder
* operations as we wish to preserve ordering there
*/
changeSortDirection: function (button, changeDirection) {
var sortData = button.sortData,
iconCls = button.iconCls;
if (sortData) {
if (changeDirection !== false) {
button.sortData.direction = Ext.String.toggle(button.sortData.direction, "ASC", "DESC");
button.setIconCls(Ext.String.toggle(iconCls, "sort-direction-asc", "sort-direction-desc"));
}
this.up("grid").getStore().clearFilter();
this.doSort();
}
},
doSort: function () {
this.up("grid").getStore().sort(this.getSorters());
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment