X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/2e847cf21b8ab9d15fa167b315ca5b2fa92638fc..refs/heads/old:/src/util/MixedCollection.js diff --git a/src/util/MixedCollection.js b/src/util/MixedCollection.js index a4da8655..558da863 100644 --- a/src/util/MixedCollection.js +++ b/src/util/MixedCollection.js @@ -1,8 +1,8 @@ /*! - * Ext JS Library 3.1.1 - * Copyright(c) 2006-2010 Ext JS, LLC - * licensing@extjs.com - * http://www.extjs.com/license + * Ext JS Library 3.3.1 + * Copyright(c) 2006-2010 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license */ /** * @class Ext.util.MixedCollection @@ -333,7 +333,7 @@ mc.add(otherEl); item : function(key){ var mk = this.map[key], item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined; - return !Ext.isFunction(item) || this.allowFunctions ? item : null; // for prototype! + return typeof item != 'function' || this.allowFunctions ? item : null; // for prototype! }, /** @@ -401,23 +401,38 @@ mc.add(otherEl); /** * @private + * Performs the actual sorting based on a direction and a sorting function. Internally, + * this creates a temporary array of all items in the MixedCollection, sorts it and then writes + * the sorted array data back into this.items and this.keys * @param {String} property Property to sort by ('key', 'value', or 'index') * @param {String} dir (optional) Direction to sort 'ASC' or 'DESC'. Defaults to 'ASC'. * @param {Function} fn (optional) Comparison function that defines the sort order. * Defaults to sorting by numeric value. */ _sort : function(property, dir, fn){ - var i, - len, - dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1, - c = [], k = this.keys, items = this.items; + var i, len, + dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1, - fn = fn || function(a, b){ - return a-b; + //this is a temporary array used to apply the sorting function + c = [], + keys = this.keys, + items = this.items; + + //default to a simple sorter function if one is not provided + fn = fn || function(a, b) { + return a - b; }; + + //copy all the items into a temporary array, which we will sort for(i = 0, len = items.length; i < len; i++){ - c[c.length] = {key: k[i], value: items[i], index: i}; + c[c.length] = { + key : keys[i], + value: items[i], + index: i + }; } + + //sort the temporary array c.sort(function(a, b){ var v = fn(a[property], b[property]) * dsc; if(v === 0){ @@ -425,10 +440,13 @@ mc.add(otherEl); } return v; }); + + //copy the temporary array back into the main this.items and this.keys objects for(i = 0, len = c.length; i < len; i++){ items[i] = c[i].value; - k[i] = c[i].key; + keys[i] = c[i].key; } + this.fireEvent('sort', this); }, @@ -442,6 +460,45 @@ mc.add(otherEl); this._sort('value', dir, fn); }, + /** + * Reorders each of the items based on a mapping from old index to new index. Internally this + * just translates into a sort. The 'sort' event is fired whenever reordering has occured. + * @param {Object} mapping Mapping from old item index to new item index + */ + reorder: function(mapping) { + this.suspendEvents(); + + var items = this.items, + index = 0, + length = items.length, + order = [], + remaining = [], + oldIndex; + + //object of {oldPosition: newPosition} reversed to {newPosition: oldPosition} + for (oldIndex in mapping) { + order[mapping[oldIndex]] = items[oldIndex]; + } + + for (index = 0; index < length; index++) { + if (mapping[index] == undefined) { + remaining.push(items[index]); + } + } + + for (index = 0; index < length; index++) { + if (order[index] == undefined) { + order[index] = remaining.shift(); + } + } + + this.clear(); + this.addAll(order); + + this.resumeEvents(); + this.fireEvent('sort', this); + }, + /** * Sorts this collection by keys. * @param {String} direction (optional) 'ASC' or 'DESC'. Defaults to 'ASC'. @@ -559,11 +616,20 @@ mc.add(otherEl); return -1; }, - // private + /** + * Returns a regular expression based on the given value and matching options. This is used internally for finding and filtering, + * and by Ext.data.Store#filter + * @private + * @param {String} value The value to create the regex for. This is escaped using Ext.escapeRe + * @param {Boolean} anyMatch True to allow any match - no regex start/end line anchors will be added. Defaults to false + * @param {Boolean} caseSensitive True to make the regex case sensitive (adds 'i' switch to regex). Defaults to false. + * @param {Boolean} exactMatch True to force exact match (^ and $ characters added to the regex). Defaults to false. Ignored if anyMatch is true. + */ createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) { if (!value.exec) { // not a regex var er = Ext.escapeRe; value = String(value); + if (anyMatch === true) { value = er(value); } else { @@ -601,4 +667,4 @@ mc.add(otherEl); * not found, returns undefined. If an item was found, but is a Class, * returns null. */ -Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item; \ No newline at end of file +Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;