Store.js

Ext.data.Store = function(config){
    this.data = new Ext.util.MixedCollection(false);
    this.data.getKey = function(o){
        return o.id;
    };
    this.baseParams = {};
    this.paramNames = {
        'start' : 'start',
        'limit' : 'limit',
        'sort' : 'sort',
        'dir' : 'dir'
    };
    Ext.apply(this, config);
    
    if(this.reader && !this.recordType){ // reader passed
        this.recordType = this.reader.recordType;
    }

    this.fields = this.recordType.prototype.fields;

    this.modified = [];
    
    this.events = {
        datachanged : true,
        add : true,
        remove : true,
        update : true,
        clear : true,
        beforeload : true,
        load : true,
        loadexception : true
    };

    if(this.proxy){
        this.relayEvents(this.proxy,  ['loadexception']);
    }
    this.sortToggle = {};
};
Ext.extend(Ext.data.Store, Ext.util.Observable, {
    remoteSort : false,
    lastOptions : null,
    
    add : function(records){
        records = [].concat(records);
        for(var i = 0, len = records.length; i < len; i++){
            records[i].join(this);
        }
        var index = this.data.length;
        this.data.addAll(records);
        this.fireEvent('add', this, records, index);
    },
    
    remove : function(record){
        var index = this.data.indexOf(record);
        this.data.removeAt(index);
        this.fireEvent('remove', this, record, index);
    },
    
    removeAll : function(){
        this.data.clear();
        this.fireEvent('clear', this);
    },
    
    insert : function(index, records){
        records = [].concat(records);
        for(var i = 0, len = records.length; i < len; i++){
            this.data.insert(index, records[i]);
            records[i].join(this);
        }
        this.fireEvent('add', this, records, index);
    },
    
    indexOf : function(record){
        return this.data.indexOf(record);  
    },
    
    indexOfId : function(id){
        return this.data.indexOfKey(id);  
    },
    
    getById : function(id){
        return this.data.key(id);
    },
    
    getAt : function(index){
        return this.data.itemAt(index);
    },
    
    getRange : function(start, end){
        return this.data.getRange(start, end);
    },
    
    storeOptions : function(o){
        o = Ext.apply({}, o);
        delete o.callback;
        delete o.scope;
        this.lastOptions = o; 
    },
    
    load : function(options){
        options = options || {};
        if(this.fireEvent('beforeload', this, options) !== false){
            this.storeOptions(options);
            var p = Ext.apply(options.params || {}, this.baseParams);
            if(this.sortInfo && this.remoteSort){
                var pn = this.paramNames;
                p[pn['sort']] = this.sortInfo.field;
                p[pn['dir']] = this.sortInfo.direction;
            }
            this.proxy.load(p, this.reader, this.loadRecords, this, options);
        }
    },
    
    loadRecords : function(o, options, success){
        if(!o || !success){
            this.fireEvent('load', this, [], options);
            if(options.callback){
                options.callback.call(options.callback.scope || this, [], options);
            }
            return;
        }
        var r = o.records, t = o.totalRecords || r.length;
        for(var i = 0, len = r.length; i < len; i++){
            r[i].join(this);
        }
        if(options.add !== true){
            this.data.clear();
            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.data.addAll(r);
        }
        this.fireEvent('load', this, r, options);
        if(options.callback){
            options.callback.call(options.callback.scope || this, r, options);
        }
    },
    
    getCount : function(){
        return this.data.length || 0;
    },
    
    getTotalCount : function(){
        return this.totalLength || 0;
    },
    
    getSortState : function(){
        return this.sortInfo;  
    },
    
    applySort : function(){
        if(this.sortInfo && !this.remoteSort){
            var s = this.sortInfo, f = s.field;
            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(s.direction, fn);
            if(this.snapshot && this.snapshot != this.data){
                this.snapshot.sort(s.direction, fn);
            }
        }
    },

    setDefaultSort : function(field, dir){
        this.sortInfo = {field: field, direction: dir ? dir.toUpperCase() : 'ASC'};
    },

    sort : function(fieldName, dir){
        var f = this.fields.get(fieldName); 
        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;
            }
        }  
        this.sortToggle[f.name] = dir;
        this.sortInfo = {field: f.name, direction: dir};
        if(!this.remoteSort){
            this.applySort();
            this.fireEvent('datachanged', this);
        }else{
            this.load(this.lastOptions);
        }
    },
    
    each : function(fn, scope){
        this.data.each(fn, scope);  
    },
    
    getModifiedRecords : function(){
        return this.modified;
    },
    
    /**
     * Filter the records by a specific property. 
     * @param {String} field A field on your records
     * @param {String/RegExp} value Either a string that the field 
     * should start with or a RegExp to test against the field
     */
    filter : function(property, value){
        if(!value.exec){ // not a regex
            value = String(value);
            if(value.length == 0){
                return this.clone();
            }
            value = new RegExp('^' + Ext.escapeRe(value), 'i');
        }
        this.filterBy(function(r){
            return value.test(r.data[property]);
        });
	},
    
    /**
     * Filter by a function. The passed function will be called with each 
     * record in this datesource. If the function returns true, the record is included 
     * otherwise it is filtered.
     * @param {Function} fn The function to be called, it will receive 2 args (record, id)
     * @param {Object} scope (optional) The scope of the function (defaults to this) 
     */
    filterBy : function(fn, scope){
        var data = this.snapshot || this.data;
        this.snapshot = data;
        this.data = data.filterBy(fn, scope);
        this.fireEvent('datachanged', this);
    },
    
    clearFilter : function(){
        if(this.snapshot && this.snapshot != this.data){
            this.data = this.snapshot;
            delete this.snapshot;
            this.fireEvent('datachanged', this);
        }
    },

    afterEdit : function(record){
        this.modified.push(record);
        this.fireEvent('update', this, record);
    }
});

yui-ext - Copyright © 2006 Jack Slocum. | Yahoo! UI - Copyright © 2006 Yahoo! Inc.
All rights reserved.