Upgrade to ExtJS 3.2.0 - Released 03/30/2010
[extjs.git] / examples / grid / multiple-sorting.js
diff --git a/examples/grid/multiple-sorting.js b/examples/grid/multiple-sorting.js
new file mode 100644 (file)
index 0000000..20b5bb5
--- /dev/null
@@ -0,0 +1,228 @@
+/*!
+ * Ext JS Library 3.2.0
+ * Copyright(c) 2006-2010 Ext JS, Inc.
+ * licensing@extjs.com
+ * http://www.extjs.com/license
+ */
+/*!
+ * Ext JS Library 3.2.0
+ * Copyright(c) 2006-2010 Ext JS, LLC
+ * licensing@extjs.com
+ * http://www.extjs.com/license
+ */
+Ext.onReady(function() {
+    // create the data store
+    var store = new Ext.data.ArrayStore({
+        fields: [
+           {name: 'rating', type: 'int'},
+           {name: 'salary', type: 'float'},
+           {name: 'name'}
+        ]
+    });
+
+    // manually load local fake data
+    store.loadData(createFakeData(25));
+    
+    var reorderer = new Ext.ux.ToolbarReorderer();
+    var droppable = new Ext.ux.ToolbarDroppable({
+        /**
+         * Creates the new toolbar item from the drop event
+         */
+        createItem: function(data) {
+            var column = this.getColumnFromDragDrop(data);
+            
+            return createSorterButton({
+                text    : column.header,
+                sortData: {
+                    field: column.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
+         * @return {Boolean} True if the drop is allowed
+         */
+        canDrop: function(dragSource, event, data) {
+            var sorters = getSorters(),
+                column  = this.getColumnFromDragDrop(data);
+
+            for (var i=0; i < sorters.length; i++) {
+                if (sorters[i].field == column.dataIndex) return false;
+            }
+
+            return true;
+        },
+        
+        afterLayout: doSort,
+
+        /**
+         * Helper function used to find the column that was dragged
+         * @param {Object} data Arbitrary data from
+         */
+        getColumnFromDragDrop: function(data) {
+            var index    = data.header.cellIndex,
+                colModel = grid.colModel,
+                column   = colModel.getColumnById(colModel.getColumnId(index));
+
+            return column;
+        }
+    });
+    
+    //create the toolbar with the 2 plugins
+    var tbar = new Ext.Toolbar({
+        items  : ['Sorting order:', '-'],
+        plugins: [reorderer, droppable],
+        listeners: {
+            scope    : this,
+            reordered: function(button) {
+                changeSortDirection(button, false);
+            }
+        }
+    });
+    
+    // create the Grid
+    var grid = new Ext.grid.GridPanel({
+        tbar : tbar,
+        store: store,
+        
+        columns: [
+            {header: 'Name',   width: 160, sortable: false, dataIndex: 'name',   id:'company'},
+            {header: 'Rating', width: 125, sortable: false, dataIndex: 'rating'},
+            {header: 'Salary', width: 125, sortable: false, dataIndex: 'salary', renderer: 'usMoney'}
+        ],
+        autoExpandColumn: 'company',
+        stripeRows: true,
+        
+        height: 350,
+        width : 600,
+        title : 'Array Grid',
+        
+        listeners: {
+            scope: this,
+            
+            //here we tell the toolbar's droppable plugin that it can accept items from the columns' dragdrop group
+            render: function() {
+                var dragProxy = grid.getView().columnDrag,
+                    ddGroup   = dragProxy.ddGroup;
+                
+                droppable.addDDGroup(ddGroup);
+            }
+        }
+    });
+    
+    tbar.add(createSorterButton({
+        text: 'Rating',
+        sortData: {
+            field: 'rating',
+            direction: 'DESC'
+        }
+    }));
+    
+    tbar.add(createSorterButton({
+        text: 'Salary',
+        sortData: {
+            field: 'salary',
+            direction: 'ASC'
+        }
+    }));
+    
+    // render the grid to the specified div in the page
+    grid.render('grid-example');
+    doSort();
+    
+    //The following functions are used to get the sorting data from the toolbar and apply it to the store
+    
+    /**
+     * Tells the store to sort itself according to our sort data
+     */
+    function doSort() {
+        store.sort(getSorters(), "ASC");
+    };
+    
+    /**
+     * 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
+     */
+    function changeSortDirection(button, changeDirection) {
+        var sortData = button.sortData,
+            iconCls  = button.iconCls;
+        
+        if (sortData != undefined) {
+            if (changeDirection !== false) {
+                button.sortData.direction = button.sortData.direction.toggle("ASC", "DESC");
+                button.setIconClass(iconCls.toggle("sort-asc", "sort-desc"));
+            }
+            
+            store.clearFilter();
+            doSort();
+        }
+    };
+    
+    /**
+     * Returns an array of sortData from the sorter buttons
+     * @return {Array} Ordered sort data from each of the sorter buttons
+     */
+    function getSorters() {
+        var sorters = [];
+        
+        Ext.each(tbar.findByType('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 {Ext.Button} The new Button object
+     */
+    function createSorterButton(config) {
+        config = config || {};
+              
+        Ext.applyIf(config, {
+            listeners: {
+                click: function(button, e) {
+                    changeSortDirection(button, true);                    
+                }
+            },
+            iconCls: 'sort-' + config.sortData.direction.toLowerCase(),
+            reorderable: true
+        });
+        
+        return new Ext.Button(config);
+    };
+    
+    /**
+     * Returns an array of fake data
+     * @param {Number} count The number of fake rows to create data for
+     * @return {Array} The fake record data, suitable for usage with an ArrayReader
+     */
+    function createFakeData(count) {
+        var firstNames   = ['Ed', 'Tommy', 'Aaron', 'Abe', 'Jamie', 'Adam', 'Dave', 'David', 'Jay'],
+            lastNames    = ['Spencer', 'Maintz', 'Conran', 'Elias', 'Avins', 'Mishcon', 'Kaneda', 'Davis', 'Robinson'],
+            ratings      = [1, 2, 3, 4, 5],
+            salaries     = [100, 400, 900, 1500, 1000000];
+
+        var data = [];
+        for (var i=0; i < (count || 25); i++) {
+            var ratingId    = Math.floor(Math.random() * ratings.length),
+                salaryId    = Math.floor(Math.random() * salaries.length),
+                firstNameId = Math.floor(Math.random() * firstNames.length),
+                lastNameId  = Math.floor(Math.random() * lastNames.length),
+
+                rating      = ratings[ratingId],
+                salary      = salaries[salaryId],
+                name        = String.format("{0} {1}", firstNames[firstNameId], lastNames[lastNameId]);
+
+            data.push([rating, salary, name]);
+        }
+        
+        return data;
+    }
+});
\ No newline at end of file