4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-util-Sortable'>/**
19 </span> * @docauthor Tommy Maintz <tommy@sencha.com>
21 * A mixin which allows a data component to be sorted. This is used by e.g. {@link Ext.data.Store} and {@link Ext.data.TreeStore}.
23 * **NOTE**: This mixin is mainly for internal use and most users should not need to use it directly. It
24 * is more likely you will want to use one of the component classes that import this mixin, such as
25 * {@link Ext.data.Store} or {@link Ext.data.TreeStore}.
27 Ext.define("Ext.util.Sortable", {
28 <span id='Ext-util-Sortable-property-isSortable'> /**
29 </span> * @property {Boolean} isSortable
30 * Flag denoting that this object is sortable. Always true.
34 <span id='Ext-util-Sortable-property-defaultSortDirection'> /**
35 </span> * @property {String} defaultSortDirection
36 * The default sort direction to use if one is not specified.
38 defaultSortDirection: "ASC",
44 <span id='Ext-util-Sortable-property-sortRoot'> /**
45 </span> * @property {String} sortRoot
46 * The property in each item that contains the data to sort.
49 <span id='Ext-util-Sortable-method-initSortable'> /**
50 </span> * Performs initialization of this mixin. Component classes using this mixin should call this method during their
53 initSortable: function() {
57 <span id='Ext-util-Sortable-property-sorters'> /**
58 </span> * @property {Ext.util.MixedCollection} sorters
59 * The collection of {@link Ext.util.Sorter Sorters} currently applied to this Store
61 me.sorters = Ext.create('Ext.util.AbstractMixedCollection', false, function(item) {
62 return item.id || item.property;
66 me.sorters.addAll(me.decodeSorters(sorters));
70 <span id='Ext-util-Sortable-method-sort'> /**
71 </span> * Sorts the data in the Store by one or more of its properties. Example usage:
73 * //sort by a single field
74 * myStore.sort('myField', 'DESC');
76 * //sorting by multiple fields
88 * Internally, Store converts the passed arguments into an array of {@link Ext.util.Sorter} instances, and delegates
89 * the actual sorting to its internal {@link Ext.util.MixedCollection}.
91 * When passing a single string argument to sort, Store maintains a ASC/DESC toggler per field, so this code:
93 * store.sort('myField');
94 * store.sort('myField');
96 * Is equivalent to this code, because Store handles the toggling automatically:
98 * store.sort('myField', 'ASC');
99 * store.sort('myField', 'DESC');
101 * @param {String/Ext.util.Sorter[]} sorters Either a string name of one of the fields in this Store's configured
102 * {@link Ext.data.Model Model}, or an array of sorter configurations.
103 * @param {String} direction The overall direction to sort the data by. Defaults to "ASC".
104 * @return {Ext.util.Sorter[]}
106 sort: function(sorters, direction, where, doSort) {
111 if (Ext.isArray(sorters)) {
114 newSorters = sorters;
116 else if (Ext.isObject(sorters)) {
119 newSorters = [sorters];
121 else if (Ext.isString(sorters)) {
122 sorter = me.sorters.get(sorters);
129 newSorters = [sorter];
131 else if (direction === undefined) {
135 sorter.setDirection(direction);
139 if (newSorters && newSorters.length) {
140 newSorters = me.decodeSorters(newSorters);
141 if (Ext.isString(where)) {
142 if (where === 'prepend') {
143 sorters = me.sorters.clone().items;
146 me.sorters.addAll(newSorters);
147 me.sorters.addAll(sorters);
150 me.sorters.addAll(newSorters);
155 me.sorters.addAll(newSorters);
159 if (doSort !== false) {
160 me.onBeforeSort(newSorters);
162 sorters = me.sorters.items;
163 if (sorters.length) {
164 //construct an amalgamated sorter function which combines all of the Sorters passed
165 sorterFn = function(r1, r2) {
166 var result = sorters[0].sort(r1, r2),
167 length = sorters.length,
170 //if we have more than one sorter, OR any additional sorter functions together
171 for (i = 1; i < length; i++) {
172 result = result || sorters[i].sort.call(this, r1, r2);
185 onBeforeSort: Ext.emptyFn,
187 <span id='Ext-util-Sortable-method-decodeSorters'> /**
189 * Normalizes an array of sorter objects, ensuring that they are all Ext.util.Sorter instances
190 * @param {Object[]} sorters The sorters array
191 * @return {Ext.util.Sorter[]} Array of Ext.util.Sorter objects
193 decodeSorters: function(sorters) {
194 if (!Ext.isArray(sorters)) {
195 if (sorters === undefined) {
202 var length = sorters.length,
203 Sorter = Ext.util.Sorter,
204 fields = this.model ? this.model.prototype.fields : null,
208 for (i = 0; i < length; i++) {
211 if (!(config instanceof Sorter)) {
212 if (Ext.isString(config)) {
218 Ext.applyIf(config, {
219 root : this.sortRoot,
220 direction: "ASC"
223 //support for 3.x style sorters where a function can be defined as 'fn'
225 config.sorterFn = config.fn;
228 //support a function to be passed as a sorter definition
229 if (typeof config == 'function') {
235 // ensure sortType gets pushed on if necessary
236 if (fields && !config.transform) {
237 field = fields.get(config.property);
238 config.transform = field ? field.sortType : undefined;
240 sorters[i] = Ext.create('Ext.util.Sorter', config);
247 getSorters: function() {
248 return this.sorters.items;