4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../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> * @class Ext.util.Sortable
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 library 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 * @docauthor Tommy Maintz <tommy@sencha.com>
29 Ext.define("Ext.util.Sortable", {
30 <span id='Ext-util-Sortable-property-isSortable'> /**
31 </span> * @property isSortable
33 * Flag denoting that this object is sortable. Always true.
37 <span id='Ext-util-Sortable-property-defaultSortDirection'> /**
38 </span> * The default sort direction to use if one is not specified (defaults to "ASC")
39 * @property defaultSortDirection
42 defaultSortDirection: "ASC",
48 <span id='Ext-util-Sortable-property-'> /**
49 </span> * The property in each item that contains the data to sort.
53 <span id='Ext-util-Sortable-method-initSortable'> /**
54 </span> * Performs initialization of this mixin. Component classes using this mixin should call this method
55 * during their own initialization.
57 initSortable: function() {
61 <span id='Ext-util-Sortable-property-sorters'> /**
62 </span> * The collection of {@link Ext.util.Sorter Sorters} currently applied to this Store
64 * @type Ext.util.MixedCollection
66 me.sorters = Ext.create('Ext.util.AbstractMixedCollection', false, function(item) {
67 return item.id || item.property;
71 me.sorters.addAll(me.decodeSorters(sorters));
75 <span id='Ext-util-Sortable-method-sort'> /**
76 </span> * <p>Sorts the data in the Store by one or more of its properties. Example usage:</p>
77 <pre><code>
78 //sort by a single field
79 myStore.sort('myField', 'DESC');
81 //sorting by multiple fields
92 </code></pre>
93 * <p>Internally, Store converts the passed arguments into an array of {@link Ext.util.Sorter} instances, and delegates the actual
94 * sorting to its internal {@link Ext.util.MixedCollection}.</p>
95 * <p>When passing a single string argument to sort, Store maintains a ASC/DESC toggler per field, so this code:</p>
96 <pre><code>
97 store.sort('myField');
98 store.sort('myField');
99 </code></pre>
100 * <p>Is equivalent to this code, because Store handles the toggling automatically:</p>
101 <pre><code>
102 store.sort('myField', 'ASC');
103 store.sort('myField', 'DESC');
104 </code></pre>
105 * @param {String|Array} sorters Either a string name of one of the fields in this Store's configured {@link Ext.data.Model Model},
106 * or an Array of sorter configurations.
107 * @param {String} direction The overall direction to sort the data by. Defaults to "ASC".
109 sort: function(sorters, direction, where, doSort) {
114 if (Ext.isArray(sorters)) {
117 newSorters = sorters;
119 else if (Ext.isObject(sorters)) {
122 newSorters = [sorters];
124 else if (Ext.isString(sorters)) {
125 sorter = me.sorters.get(sorters);
132 newSorters = [sorter];
134 else if (direction === undefined) {
138 sorter.setDirection(direction);
142 if (newSorters && newSorters.length) {
143 newSorters = me.decodeSorters(newSorters);
144 if (Ext.isString(where)) {
145 if (where === 'prepend') {
146 sorters = me.sorters.clone().items;
149 me.sorters.addAll(newSorters);
150 me.sorters.addAll(sorters);
153 me.sorters.addAll(newSorters);
158 me.sorters.addAll(newSorters);
161 if (doSort !== false) {
162 me.onBeforeSort(newSorters);
166 if (doSort !== false) {
167 sorters = me.sorters.items;
168 if (sorters.length) {
169 //construct an amalgamated sorter function which combines all of the Sorters passed
170 sorterFn = function(r1, r2) {
171 var result = sorters[0].sort(r1, r2),
172 length = sorters.length,
175 //if we have more than one sorter, OR any additional sorter functions together
176 for (i = 1; i < length; i++) {
177 result = result || sorters[i].sort.call(this, r1, r2);
190 onBeforeSort: Ext.emptyFn,
192 <span id='Ext-util-Sortable-method-decodeSorters'> /**
194 * Normalizes an array of sorter objects, ensuring that they are all Ext.util.Sorter instances
195 * @param {Array} sorters The sorters array
196 * @return {Array} Array of Ext.util.Sorter objects
198 decodeSorters: function(sorters) {
199 if (!Ext.isArray(sorters)) {
200 if (sorters === undefined) {
207 var length = sorters.length,
208 Sorter = Ext.util.Sorter,
209 fields = this.model ? this.model.prototype.fields : null,
213 for (i = 0; i < length; i++) {
216 if (!(config instanceof Sorter)) {
217 if (Ext.isString(config)) {
223 Ext.applyIf(config, {
224 root : this.sortRoot,
225 direction: "ASC"
228 //support for 3.x style sorters where a function can be defined as 'fn'
230 config.sorterFn = config.fn;
233 //support a function to be passed as a sorter definition
234 if (typeof config == 'function') {
240 // ensure sortType gets pushed on if necessary
241 if (fields && !config.transform) {
242 field = fields.get(config.property);
243 config.transform = field ? field.sortType : undefined;
245 sorters[i] = Ext.create('Ext.util.Sorter', config);
252 getSorters: function() {
253 return this.sorters.items;