+
+ // create the data store
+ Ext.define('Employee', {
+ extend: 'Ext.data.Model',
+ fields: [
+ {name: 'rating', type: 'int'},
+ {name: 'salary', type: 'float'},
+ {name: 'name'}
+ ]
+ });
+
+ var store = Ext.create('Ext.data.Store', {
+ model: 'Employee',
+ proxy: {
+ type: 'memory',
+ data: createFakeData(25),
+ reader: {
+ type: 'array'
+ }
+ },
+ autoLoad: true
+ });
+
+ var reorderer = Ext.create('Ext.ux.BoxReorderer', {
+ listeners: {
+ scope: this,
+ Drop: function(r, c, button) { //update sort direction when button is dropped
+ 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 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 = 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: doSort
+ });
+
+ //create the toolbar with the 2 plugins
+ var tbar = Ext.create('Ext.toolbar.Toolbar', {
+ items : [{
+ xtype: 'tbtext',
+ text: 'Sorting order:',
+ reorderable: false
+ }, '-'],
+ plugins: [reorderer, droppable]
+ });
+
+ tbar.add(createSorterButtonConfig({
+ text: 'Rating',
+ sortData: {
+ property: 'rating',
+ direction: 'DESC'
+ }
+ }));
+
+ tbar.add(createSorterButtonConfig({
+ text: 'Salary',
+ sortData: {
+ property: 'salary',
+ direction: 'ASC'
+ }
+ }));
+
+ // create the Grid
+ var grid = Ext.create('Ext.grid.Panel', {
+ tbar : tbar,
+ store: store,
+ columns: [
+ {
+ text: 'Name',
+ flex:1 ,
+ sortable: false,
+ dataIndex: 'name'
+ },{
+ text: 'Rating',
+ width: 125,
+ sortable: false,
+ dataIndex: 'rating'
+ },{
+ text: 'Salary',
+ width: 125,
+ sortable: false,
+ dataIndex: 'salary',
+ align: 'right',
+ renderer: Ext.util.Format.usMoney
+ }
+ ],
+ stripeRows: true,
+ height: 350,
+ width : 600,
+ title : 'Array Grid',
+ renderTo: 'grid-example',
+ listeners: {
+ scope: this,
+ // 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(grid) {
+ var headerCt = grid.child("headercontainer");
+ droppable.addDDGroup(headerCt.reorderer.dragZone.ddGroup);
+ doSort();
+ }
+ }
+ });
+});