3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
15 Ext.Loader.setConfig({enabled: true});
17 Ext.Loader.setPath('Ext.ux', '../ux/');
24 'Ext.ux.ToolbarDroppable',
28 Ext.onReady(function() {
29 //The following functions are used to get the sorting data from the toolbar and apply it to the store
31 * Tells the store to sort itself according to our sort data
34 store.sort(getSorters());
38 * Callback handler used when a sorter button is clicked or reordered
39 * @param {Ext.Button} button The button that was clicked
40 * @param {Boolean} changeDirection True to change direction (default). Set to false for reorder
41 * operations as we wish to preserve ordering there
43 function changeSortDirection(button, changeDirection) {
44 var sortData = button.sortData,
45 iconCls = button.iconCls;
48 if (changeDirection !== false) {
49 button.sortData.direction = Ext.String.toggle(button.sortData.direction, "ASC", "DESC");
50 button.setIconCls(Ext.String.toggle(iconCls, "sort-asc", "sort-desc"));
58 * Returns an array of sortData from the sorter buttons
59 * @return {Array} Ordered sort data from each of the sorter buttons
61 function getSorters() {
64 Ext.each(tbar.query('button'), function(button) {
65 sorters.push(button.sortData);
72 * Convenience function for creating Toolbar Buttons that are tied to sorters
73 * @param {Object} config Optional config object
74 * @return {Object} The new Button configuration
76 function createSorterButtonConfig(config) {
77 config = config || {};
80 click: function(button, e) {
81 changeSortDirection(button, true);
84 iconCls: 'sort-' + config.sortData.direction.toLowerCase(),
92 * Returns an array of fake data
93 * @param {Number} count The number of fake rows to create data for
94 * @return {Array} The fake record data, suitable for usage with an ArrayReader
96 function createFakeData(count) {
97 var firstNames = ['Ed', 'Tommy', 'Aaron', 'Abe', 'Jamie', 'Adam', 'Dave', 'David', 'Jay', 'Nicolas', 'Nige'],
98 lastNames = ['Spencer', 'Maintz', 'Conran', 'Elias', 'Avins', 'Mishcon', 'Kaneda', 'Davis', 'Robinson', 'Ferrero', 'White'],
99 ratings = [1, 2, 3, 4, 5],
100 salaries = [100, 400, 900, 1500, 1000000];
103 for (var i = 0; i < (count || 25); i++) {
104 var ratingId = Math.floor(Math.random() * ratings.length),
105 salaryId = Math.floor(Math.random() * salaries.length),
106 firstNameId = Math.floor(Math.random() * firstNames.length),
107 lastNameId = Math.floor(Math.random() * lastNames.length),
109 rating = ratings[ratingId],
110 salary = salaries[salaryId],
111 name = Ext.String.format("{0} {1}", firstNames[firstNameId], lastNames[lastNameId]);
113 data.push([rating, salary, name]);
118 // create the data store
119 Ext.define('Employee', {
120 extend: 'Ext.data.Model',
122 {name: 'rating', type: 'int'},
123 {name: 'salary', type: 'float'},
128 var store = Ext.create('Ext.data.Store', {
132 data: createFakeData(25),
140 var reorderer = Ext.create('Ext.ux.BoxReorderer', {
143 Drop: function(r, c, button) { //update sort direction when button is dropped
144 changeSortDirection(button, false);
149 var droppable = Ext.create('Ext.ux.ToolbarDroppable', {
151 * Creates the new toolbar item from the drop event
153 createItem: function(data) {
154 var header = data.header,
155 headerCt = header.ownerCt,
156 reorderer = headerCt.reorderer;
158 // Hide the drop indicators of the standard HeaderDropZone
159 // in case user had a pending valid drop in
161 reorderer.dropZone.invalidateDrop();
164 return createSorterButtonConfig({
167 property: header.dataIndex,
174 * Custom canDrop implementation which returns true if a column can be added to the toolbar
175 * @param {Object} data Arbitrary data from the drag source. For a HeaderContainer, it will
176 * contain a header property which is the Header being dragged.
177 * @return {Boolean} True if the drop is allowed
179 canDrop: function(dragSource, event, data) {
180 var sorters = getSorters(),
181 header = data.header,
182 length = sorters.length,
183 entryIndex = this.calculateEntryIndex(event),
184 targetItem = this.toolbar.getComponent(entryIndex),
187 // Group columns have no dataIndex and therefore cannot be sorted
188 // If target isn't reorderable it could not be replaced
189 if (!header.dataIndex || (targetItem && targetItem.reorderable === false)) {
193 for (i = 0; i < length; i++) {
194 if (sorters[i].property == header.dataIndex) {
204 //create the toolbar with the 2 plugins
205 var tbar = Ext.create('Ext.toolbar.Toolbar', {
208 text: 'Sorting order:',
211 plugins: [reorderer, droppable]
214 tbar.add(createSorterButtonConfig({
222 tbar.add(createSorterButtonConfig({
231 var grid = Ext.create('Ext.grid.Panel', {
251 renderer: Ext.util.Format.usMoney
257 title : 'Array Grid',
258 renderTo: 'grid-example',
261 // wait for the first layout to access the headerCt (we only want this once):
263 // tell the toolbar's droppable plugin that it accepts items from the columns' dragdrop group
264 afterlayout: function(grid) {
265 var headerCt = grid.child("headercontainer");
266 droppable.addDDGroup(headerCt.reorderer.dragZone.ddGroup);