- }
- }
- },
-
- // @protected onDestroyRecords proxy callback for destroy action
- onDestroyRecords : function(success, rs, data) {
- // splice each rec out of this.removed
- rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs);
- for (var i=0,len=rs.length;i<len;i++) {
- this.removed.splice(this.removed.indexOf(rs[i]), 1);
- }
- if (success === false) {
- // put records back into store if remote destroy fails.
- // @TODO: Might want to let developer decide.
- for (i=rs.length-1;i>=0;i--) {
- this.insert(rs[i].lastIndex, rs[i]); // <-- lastIndex set in Store#destroyRecord
- }
- }
- },
-
- // protected handleException. Possibly temporary until Ext framework has an exception-handler.
- handleException : function(e) {
- // @see core/Error.js
- Ext.handleError(e);
- },
-
- <div id="method-Ext.data.Store-reload"></div>/**
- * <p>Reloads the Record cache from the configured Proxy using the configured
- * {@link Ext.data.Reader Reader} and the options from the last load operation
- * performed.</p>
- * <p><b>Note</b>: see the Important note in {@link #load}.</p>
- * @param {Object} options <p>(optional) An <tt>Object</tt> containing
- * {@link #load loading options} which may override the {@link #lastOptions options}
- * used in the last {@link #load} operation. See {@link #load} for details
- * (defaults to <tt>null</tt>, in which case the {@link #lastOptions} are
- * used).</p>
- * <br><p>To add new params to the existing params:</p><pre><code>
-lastOptions = myStore.lastOptions;
-Ext.apply(lastOptions.params, {
- myNewParam: true
-});
-myStore.reload(lastOptions);
- * </code></pre>
- */
- reload : function(options){
- this.load(Ext.applyIf(options||{}, this.lastOptions));
- },
-
- // private
- // Called as a callback by the Reader during a load operation.
- loadRecords : function(o, options, success){
- if (this.isDestroyed === true) {
- return;
- }
- if(!o || success === false){
- if(success !== false){
- this.fireEvent('load', this, [], options);
- }
- if(options.callback){
- options.callback.call(options.scope || this, [], options, false, o);
- }
- return;
- }
- var r = o.records, t = o.totalRecords || r.length;
- if(!options || options.add !== true){
- if(this.pruneModifiedRecords){
- this.modified = [];
- }
- for(var i = 0, len = r.length; i < len; i++){
- r[i].join(this);
- }
- if(this.snapshot){
- this.data = this.snapshot;
- delete this.snapshot;
- }
- this.clearData();
- this.data.addAll(r);
- this.totalLength = t;
- this.applySort();
- this.fireEvent('datachanged', this);
- }else{
- this.totalLength = Math.max(t, this.data.length+r.length);
- this.add(r);
- }
- this.fireEvent('load', this, r, options);
- if(options.callback){
- options.callback.call(options.scope || this, r, options, true);
- }
- },
-
- <div id="method-Ext.data.Store-loadData"></div>/**
- * Loads data from a passed data block and fires the {@link #load} event. A {@link Ext.data.Reader Reader}
- * which understands the format of the data must have been configured in the constructor.
- * @param {Object} data The data block from which to read the Records. The format of the data expected
- * is dependent on the type of {@link Ext.data.Reader Reader} that is configured and should correspond to
- * that {@link Ext.data.Reader Reader}'s <tt>{@link Ext.data.Reader#readRecords}</tt> parameter.
- * @param {Boolean} append (Optional) <tt>true</tt> to append the new Records rather the default to replace
- * the existing cache.
- * <b>Note</b>: that Records in a Store are keyed by their {@link Ext.data.Record#id id}, so added Records
- * with ids which are already present in the Store will <i>replace</i> existing Records. Only Records with
- * new, unique ids will be added.
- */
- loadData : function(o, append){
- var r = this.reader.readRecords(o);
- this.loadRecords(r, {add: append}, true);
- },
-
- <div id="method-Ext.data.Store-getCount"></div>/**
- * Gets the number of cached records.
- * <p>If using paging, this may not be the total size of the dataset. If the data object
- * used by the Reader contains the dataset size, then the {@link #getTotalCount} function returns
- * the dataset size. <b>Note</b>: see the Important note in {@link #load}.</p>
- * @return {Number} The number of Records in the Store's cache.
- */
- getCount : function(){
- return this.data.length || 0;
- },
-
- <div id="method-Ext.data.Store-getTotalCount"></div>/**
- * Gets the total number of records in the dataset as returned by the server.
- * <p>If using paging, for this to be accurate, the data object used by the {@link #reader Reader}
- * must contain the dataset size. For remote data sources, the value for this property
- * (<tt>totalProperty</tt> for {@link Ext.data.JsonReader JsonReader},
- * <tt>totalRecords</tt> for {@link Ext.data.XmlReader XmlReader}) shall be returned by a query on the server.
- * <b>Note</b>: see the Important note in {@link #load}.</p>
- * @return {Number} The number of Records as specified in the data object passed to the Reader
- * by the Proxy.
- * <p><b>Note</b>: this value is not updated when changing the contents of the Store locally.</p>
- */
- getTotalCount : function(){
- return this.totalLength || 0;
- },
-
- <div id="method-Ext.data.Store-getSortState"></div>/**
- * Returns an object describing the current sort state of this Store.
- * @return {Object} The sort state of the Store. An object with two properties:<ul>
- * <li><b>field : String<p class="sub-desc">The name of the field by which the Records are sorted.</p></li>
- * <li><b>direction : String<p class="sub-desc">The sort order, 'ASC' or 'DESC' (case-sensitive).</p></li>
- * </ul>
- * See <tt>{@link #sortInfo}</tt> for additional details.
- */
- getSortState : function(){
- return this.sortInfo;
- },
-
- // private
- applySort : function(){
- if(this.sortInfo && !this.remoteSort){
- var s = this.sortInfo, f = s.field;
- this.sortData(f, s.direction);
- }
- },
-
- // private
- sortData : function(f, direction){
- direction = direction || 'ASC';
- var st = this.fields.get(f).sortType;
- var fn = function(r1, r2){
- var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
- return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
- };
- this.data.sort(direction, fn);
- if(this.snapshot && this.snapshot != this.data){
- this.snapshot.sort(direction, fn);
- }
- },
-
- <div id="method-Ext.data.Store-setDefaultSort"></div>/**
- * Sets the default sort column and order to be used by the next {@link #load} operation.
- * @param {String} fieldName The name of the field to sort by.
- * @param {String} dir (optional) The sort order, 'ASC' or 'DESC' (case-sensitive, defaults to <tt>'ASC'</tt>)
- */
- setDefaultSort : function(field, dir){
- dir = dir ? dir.toUpperCase() : 'ASC';
- this.sortInfo = {field: field, direction: dir};
- this.sortToggle[field] = dir;
- },
-
- <div id="method-Ext.data.Store-sort"></div>/**
- * Sort the Records.
- * If remote sorting is used, the sort is performed on the server, and the cache is reloaded. If local
- * sorting is used, the cache is sorted internally. See also {@link #remoteSort} and {@link #paramNames}.
- * @param {String} fieldName The name of the field to sort by.
- * @param {String} dir (optional) The sort order, 'ASC' or 'DESC' (case-sensitive, defaults to <tt>'ASC'</tt>)
- */
- sort : function(fieldName, dir){
- var f = this.fields.get(fieldName);
- if(!f){
- return false;
- }
- if(!dir){
- if(this.sortInfo && this.sortInfo.field == f.name){ // toggle sort dir
- dir = (this.sortToggle[f.name] || 'ASC').toggle('ASC', 'DESC');
- }else{
- dir = f.sortDir;
- }
- }
- var st = (this.sortToggle) ? this.sortToggle[f.name] : null;
- var si = (this.sortInfo) ? this.sortInfo : null;
-
- this.sortToggle[f.name] = dir;
- this.sortInfo = {field: f.name, direction: dir};
- if(!this.remoteSort){
- this.applySort();
- this.fireEvent('datachanged', this);
- }else{
- if (!this.load(this.lastOptions)) {
- if (st) {
- this.sortToggle[f.name] = st;
- }
- if (si) {
- this.sortInfo = si;
- }
- }
- }
- },
-
- <div id="method-Ext.data.Store-each"></div>/**
- * Calls the specified function for each of the {@link Ext.data.Record Records} in the cache.
- * @param {Function} fn The function to call. The {@link Ext.data.Record Record} is passed as the first parameter.
- * Returning <tt>false</tt> aborts and exits the iteration.
- * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed.
- * Defaults to the current {@link Ext.data.Record Record} in the iteration.
- */
- each : function(fn, scope){
- this.data.each(fn, scope);
- },
-
- <div id="method-Ext.data.Store-getModifiedRecords"></div>/**
- * Gets all {@link Ext.data.Record records} modified since the last commit. Modified records are
- * persisted across load operations (e.g., during paging). <b>Note</b>: deleted records are not
- * included. See also <tt>{@link #pruneModifiedRecords}</tt> and
- * {@link Ext.data.Record}<tt>{@link Ext.data.Record#markDirty markDirty}.</tt>.
- * @return {Ext.data.Record[]} An array of {@link Ext.data.Record Records} containing outstanding
- * modifications. To obtain modified fields within a modified record see
- *{@link Ext.data.Record}<tt>{@link Ext.data.Record#modified modified}.</tt>.
- */
- getModifiedRecords : function(){
- return this.modified;
- },
-
- // private
- createFilterFn : function(property, value, anyMatch, caseSensitive){
- if(Ext.isEmpty(value, false)){
- return false;
- }
- value = this.data.createValueMatcher(value, anyMatch, caseSensitive);
- return function(r){
- return value.test(r.data[property]);
- };
- },
-
- <div id="method-Ext.data.Store-sum"></div>/**
- * Sums the value of <tt>property</tt> for each {@link Ext.data.Record record} between <tt>start</tt>
- * and <tt>end</tt> and returns the result.
- * @param {String} property A field in each record
- * @param {Number} start (optional) The record index to start at (defaults to <tt>0</tt>)
- * @param {Number} end (optional) The last record index to include (defaults to length - 1)
- * @return {Number} The sum
- */
- sum : function(property, start, end){
- var rs = this.data.items, v = 0;
- start = start || 0;
- end = (end || end === 0) ? end : rs.length-1;
-
- for(var i = start; i <= end; i++){
- v += (rs[i].data[property] || 0);
- }
- return v;
- },
-
- <div id="method-Ext.data.Store-filter"></div>/**
- * Filter the {@link Ext.data.Record records} by a specified property.
- * @param {String} field A field on your records
- * @param {String/RegExp} value Either a string that the field should begin with, or a RegExp to test
- * against the field.
- * @param {Boolean} anyMatch (optional) <tt>true</tt> to match any part not just the beginning
- * @param {Boolean} caseSensitive (optional) <tt>true</tt> for case sensitive comparison
- */
- filter : function(property, value, anyMatch, caseSensitive){
- var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
- return fn ? this.filterBy(fn) : this.clearFilter();
- },
-
- <div id="method-Ext.data.Store-filterBy"></div>/**
- * Filter by a function. The specified function will be called for each
- * Record in this Store. If the function returns <tt>true</tt> the Record is included,
- * otherwise it is filtered out.
- * @param {Function} fn The function to be called. It will be passed the following parameters:<ul>
- * <li><b>record</b> : Ext.data.Record<p class="sub-desc">The {@link Ext.data.Record record}
- * to test for filtering. Access field values using {@link Ext.data.Record#get}.</p></li>
- * <li><b>id</b> : Object<p class="sub-desc">The ID of the Record passed.</p></li>
- * </ul>
- * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to this Store.
- */
- filterBy : function(fn, scope){
- this.snapshot = this.snapshot || this.data;
- this.data = this.queryBy(fn, scope||this);
- this.fireEvent('datachanged', this);
- },
-
- <div id="method-Ext.data.Store-query"></div>/**
- * Query the records by a specified property.
- * @param {String} field A field on your records
- * @param {String/RegExp} value Either a string that the field
- * should begin with, or a RegExp to test against the field.
- * @param {Boolean} anyMatch (optional) True to match any part not just the beginning
- * @param {Boolean} caseSensitive (optional) True for case sensitive comparison
- * @return {MixedCollection} Returns an Ext.util.MixedCollection of the matched records
- */
- query : function(property, value, anyMatch, caseSensitive){
- var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
- return fn ? this.queryBy(fn) : this.data.clone();
- },
-
- <div id="method-Ext.data.Store-queryBy"></div>/**
- * Query the cached records in this Store using a filtering function. The specified function
- * will be called with each record in this Store. If the function returns <tt>true</tt> the record is
- * included in the results.
- * @param {Function} fn The function to be called. It will be passed the following parameters:<ul>
- * <li><b>record</b> : Ext.data.Record<p class="sub-desc">The {@link Ext.data.Record record}
- * to test for filtering. Access field values using {@link Ext.data.Record#get}.</p></li>
- * <li><b>id</b> : Object<p class="sub-desc">The ID of the Record passed.</p></li>
- * </ul>
- * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to this Store.
- * @return {MixedCollection} Returns an Ext.util.MixedCollection of the matched records
- **/
- queryBy : function(fn, scope){
- var data = this.snapshot || this.data;
- return data.filterBy(fn, scope||this);
- },
-
- <div id="method-Ext.data.Store-find"></div>/**
- * Finds the index of the first matching Record in this store by a specific field value.
- * @param {String} fieldName The name of the Record field to test.
- * @param {String/RegExp} value Either a string that the field value
- * should begin with, or a RegExp to test against the field.
- * @param {Number} startIndex (optional) The index to start searching at
- * @param {Boolean} anyMatch (optional) True to match any part of the string, not just the beginning
- * @param {Boolean} caseSensitive (optional) True for case sensitive comparison
- * @return {Number} The matched index or -1
- */
- find : function(property, value, start, anyMatch, caseSensitive){
- var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
- return fn ? this.data.findIndexBy(fn, null, start) : -1;
- },
-
- <div id="method-Ext.data.Store-findExact"></div>/**
- * Finds the index of the first matching Record in this store by a specific field value.
- * @param {String} fieldName The name of the Record field to test.
- * @param {Mixed} value The value to match the field against.
- * @param {Number} startIndex (optional) The index to start searching at
- * @return {Number} The matched index or -1
- */
- findExact: function(property, value, start){
- return this.data.findIndexBy(function(rec){
- return rec.get(property) === value;
- }, this, start);
- },
-
- <div id="method-Ext.data.Store-findBy"></div>/**
- * Find the index of the first matching Record in this Store by a function.
- * If the function returns <tt>true</tt> it is considered a match.
- * @param {Function} fn The function to be called. It will be passed the following parameters:<ul>
- * <li><b>record</b> : Ext.data.Record<p class="sub-desc">The {@link Ext.data.Record record}
- * to test for filtering. Access field values using {@link Ext.data.Record#get}.</p></li>
- * <li><b>id</b> : Object<p class="sub-desc">The ID of the Record passed.</p></li>
- * </ul>
- * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to this Store.
- * @param {Number} startIndex (optional) The index to start searching at
- * @return {Number} The matched index or -1
- */
- findBy : function(fn, scope, start){
- return this.data.findIndexBy(fn, scope, start);
- },
-
- <div id="method-Ext.data.Store-collect"></div>/**
- * Collects unique values for a particular dataIndex from this store.
- * @param {String} dataIndex The property to collect
- * @param {Boolean} allowNull (optional) Pass true to allow null, undefined or empty string values
- * @param {Boolean} bypassFilter (optional) Pass true to collect from all records, even ones which are filtered
- * @return {Array} An array of the unique values
- **/
- collect : function(dataIndex, allowNull, bypassFilter){
- var d = (bypassFilter === true && this.snapshot) ?
- this.snapshot.items : this.data.items;
- var v, sv, r = [], l = {};
- for(var i = 0, len = d.length; i < len; i++){
- v = d[i].data[dataIndex];
- sv = String(v);
- if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
- l[sv] = true;
- r[r.length] = v;
- }
- }
- return r;
- },
-
- <div id="method-Ext.data.Store-clearFilter"></div>/**
- * Revert to a view of the Record cache with no filtering applied.
- * @param {Boolean} suppressEvent If <tt>true</tt> the filter is cleared silently without firing the
- * {@link #datachanged} event.
- */
- clearFilter : function(suppressEvent){
- if(this.isFiltered()){
- this.data = this.snapshot;
- delete this.snapshot;
- if(suppressEvent !== true){
- this.fireEvent('datachanged', this);
- }