123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>The source code</title>
- <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
- <style type="text/css">
- .highlight { display: block; background-color: #ddd; }
- </style>
- <script type="text/javascript">
- function highlight() {
- document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
- }
- </script>
- </head>
- <body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-util-Sortable'>/**
- </span> * @docauthor Tommy Maintz <tommy@sencha.com>
- *
- * 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}.
- *
- * **NOTE**: This mixin is mainly for internal use and most users should not need to use it directly. It
- * is more likely you will want to use one of the component classes that import this mixin, such as
- * {@link Ext.data.Store} or {@link Ext.data.TreeStore}.
- */
- Ext.define("Ext.util.Sortable", {
- <span id='Ext-util-Sortable-property-isSortable'> /**
- </span> * @property {Boolean} isSortable
- * `true` in this class to identify an object as an instantiated Sortable, or subclass thereof.
- */
- isSortable: true,
- <span id='Ext-util-Sortable-property-defaultSortDirection'> /**
- </span> * @property {String} defaultSortDirection
- * The default sort direction to use if one is not specified.
- */
- defaultSortDirection: "ASC",
- requires: [
- 'Ext.util.Sorter'
- ],
- <span id='Ext-util-Sortable-property-sortRoot'> /**
- </span> * @property {String} sortRoot
- * The property in each item that contains the data to sort.
- */
- <span id='Ext-util-Sortable-method-initSortable'> /**
- </span> * Performs initialization of this mixin. Component classes using this mixin should call this method during their
- * own initialization.
- */
- initSortable: function() {
- var me = this,
- sorters = me.sorters;
- <span id='Ext-util-Sortable-property-sorters'> /**
- </span> * @property {Ext.util.MixedCollection} sorters
- * The collection of {@link Ext.util.Sorter Sorters} currently applied to this Store
- */
- me.sorters = new Ext.util.AbstractMixedCollection(false, function(item) {
- return item.id || item.property;
- });
- if (sorters) {
- me.sorters.addAll(me.decodeSorters(sorters));
- }
- },
- <span id='Ext-util-Sortable-method-sort'> /**
- </span> * Sorts the data in the Store by one or more of its properties. Example usage:
- *
- * //sort by a single field
- * myStore.sort('myField', 'DESC');
- *
- * //sorting by multiple fields
- * myStore.sort([
- * {
- * property : 'age',
- * direction: 'ASC'
- * },
- * {
- * property : 'name',
- * direction: 'DESC'
- * }
- * ]);
- *
- * Internally, Store converts the passed arguments into an array of {@link Ext.util.Sorter} instances, and delegates
- * the actual sorting to its internal {@link Ext.util.MixedCollection}.
- *
- * When passing a single string argument to sort, Store maintains a ASC/DESC toggler per field, so this code:
- *
- * store.sort('myField');
- * store.sort('myField');
- *
- * Is equivalent to this code, because Store handles the toggling automatically:
- *
- * store.sort('myField', 'ASC');
- * store.sort('myField', 'DESC');
- *
- * @param {String/Ext.util.Sorter[]} [sorters] Either a string name of one of the fields in this Store's configured
- * {@link Ext.data.Model Model}, or an array of sorter configurations.
- * @param {String} [direction="ASC"] The overall direction to sort the data by.
- * @return {Ext.util.Sorter[]}
- */
- sort: function(sorters, direction, where, doSort) {
- var me = this,
- sorter, sorterFn,
- newSorters;
- if (Ext.isArray(sorters)) {
- doSort = where;
- where = direction;
- newSorters = sorters;
- }
- else if (Ext.isObject(sorters)) {
- doSort = where;
- where = direction;
- newSorters = [sorters];
- }
- else if (Ext.isString(sorters)) {
- sorter = me.sorters.get(sorters);
- if (!sorter) {
- sorter = {
- property : sorters,
- direction: direction
- };
- newSorters = [sorter];
- }
- else if (direction === undefined) {
- sorter.toggle();
- }
- else {
- sorter.setDirection(direction);
- }
- }
- if (newSorters && newSorters.length) {
- newSorters = me.decodeSorters(newSorters);
- if (Ext.isString(where)) {
- if (where === 'prepend') {
- sorters = me.sorters.clone().items;
- me.sorters.clear();
- me.sorters.addAll(newSorters);
- me.sorters.addAll(sorters);
- }
- else {
- me.sorters.addAll(newSorters);
- }
- }
- else {
- me.sorters.clear();
- me.sorters.addAll(newSorters);
- }
- }
- if (doSort !== false) {
- me.onBeforeSort(newSorters);
-
- sorters = me.sorters.items;
- if (sorters.length) {
- // Sort using a generated sorter function which combines all of the Sorters passed
- me.doSort(me.generateComparator());
- }
- }
- return sorters;
- },
- <span id='Ext-util-Sortable-method-generateComparator'> /**
- </span> * <p>Returns a comparator function which compares two items and returns -1, 0, or 1 depending
- * on the currently defined set of {@link #sorters}.</p>
- * <p>If there are no {@link #sorters} defined, it returns a function which returns <code>0</code> meaning that no sorting will occur.</p>
- */
- generateComparator: function() {
- var sorters = this.sorters.getRange();
- return sorters.length ? this.createComparator(sorters) : this.emptyComparator;
- },
-
- createComparator: function(sorters) {
- return function(r1, r2) {
- var result = sorters[0].sort(r1, r2),
- length = sorters.length,
- i = 1;
- // if we have more than one sorter, OR any additional sorter functions together
- for (; i < length; i++) {
- result = result || sorters[i].sort.call(this, r1, r2);
- }
- return result;
- };
- },
-
- emptyComparator: function(){
- return 0;
- },
- onBeforeSort: Ext.emptyFn,
- <span id='Ext-util-Sortable-method-decodeSorters'> /**
- </span> * @private
- * Normalizes an array of sorter objects, ensuring that they are all Ext.util.Sorter instances
- * @param {Object[]} sorters The sorters array
- * @return {Ext.util.Sorter[]} Array of Ext.util.Sorter objects
- */
- decodeSorters: function(sorters) {
- if (!Ext.isArray(sorters)) {
- if (sorters === undefined) {
- sorters = [];
- } else {
- sorters = [sorters];
- }
- }
- var length = sorters.length,
- Sorter = Ext.util.Sorter,
- fields = this.model ? this.model.prototype.fields : null,
- field,
- config, i;
- for (i = 0; i < length; i++) {
- config = sorters[i];
- if (!(config instanceof Sorter)) {
- if (Ext.isString(config)) {
- config = {
- property: config
- };
- }
- Ext.applyIf(config, {
- root : this.sortRoot,
- direction: "ASC"
- });
- //support for 3.x style sorters where a function can be defined as 'fn'
- if (config.fn) {
- config.sorterFn = config.fn;
- }
- //support a function to be passed as a sorter definition
- if (typeof config == 'function') {
- config = {
- sorterFn: config
- };
- }
- // ensure sortType gets pushed on if necessary
- if (fields && !config.transform) {
- field = fields.get(config.property);
- config.transform = field ? field.sortType : undefined;
- }
- sorters[i] = new Ext.util.Sorter(config);
- }
- }
- return sorters;
- },
- getSorters: function() {
- return this.sorters.items;
- },
-
- <span id='Ext-util-Sortable-method-getFirstSorter'> /**
- </span> * Gets the first sorter from the sorters collection, excluding
- * any groupers that may be in place
- * @protected
- * @return {Ext.util.Sorter} The sorter, null if none exist
- */
- getFirstSorter: function(){
- var sorters = this.sorters.items,
- len = sorters.length,
- i = 0,
- sorter;
-
- for (; i < len; ++i) {
- sorter = sorters[i];
- if (!sorter.isGrouper) {
- return sorter;
- }
- }
- return null;
- }
- });</pre>
- </body>
- </html>
|