Skip to content

Instantly share code, notes, and snippets.

@dmachi
Created August 13, 2010 18:08
Show Gist options
  • Save dmachi/523288 to your computer and use it in GitHub Desktop.
Save dmachi/523288 to your computer and use it in GitHub Desktop.
//this is a little store wrapper. Pass in an existing store, a filter method, and optionally a query
//adaptor, and it will pass through all requests to the store, except the fetch, which it will perform and
//then pass through the filter before calling the callbacks. Example after the declare. Small console only
//demo currently located at: http://dmachi.dojotoolkit.org/filterstore.html
dojo.declare("FilteringStore", null, {
constructor: function(store, filter, query){
this.store = store;
for (var i in this.store){
if (i != "fetch" && i.charAt(0)!="_"){
this[i] = function(){
return this.store[i].call(arguments);
};
}
}
this.wrapper_filter = filter;
if (query){
this.wrapper_query = query;
}
},
wrapper_query: function(args){
var newArgs = {
query: args.query,
queryOptions: args.queryOptions
}
return newArgs;
},
fetch: function(args){
var newArgs = this.wrapper_query(args);
dojo.mixin(newArgs, {
scope: this,
onComplete: function(items, request){
var filtered= this.wrapper_filter(items, args);
var scope = args.scope || dojo.global;
if (filtered.error&&args.onError) {
args.onError.call(scope, filtered.error, args);
return;
}
if (args.onBegin){
var scope = args.scope || dojo.global;
args.onBegin.call(scope, filtered.count || -1 , args);
}
if (args.onItem){
for (var i=0; i<items.length;i++){
args["onItem"].call(scope, filtered.items[i], args);
}
if (args.onComplete) {
args["onComplete"].call(scope, args);
}
} else if (args.onComplete){
args["onComplete"].call(scope, filtered.items, args);
}
},
onError: function(error){
if (args.onError){
var scope = args.scope || dojo.global;
args.onError.call(scope, error, args);
}
}
});
this.store.fetch(newArgs);
return args;
}
});
//create a normal store of any type
var store = new dojo.data.ItemFileReadStore({url: "dojotoolkit/dijit/tests/_data/countries.json"});
//declare the fileredStore. We pass in the store above as the core. The second argument is a function, that will run in the scope of the filteredStore instance. It gets passed the full set of items from the passed query and the original set of arguments. Based on the original arguments, the items are filtered (or not if the logic so calls for it). The return from this function should be an object in the form:
{
items: [], // array of filtered items
count: 0 // total number of items or -1 if unable to determine that.
}
The third parameter (not shown in the example below) to FilteringStore, is a query adaptor method. It gets passed the original set of args, and should return a new query set (sans callbacks):
{
query: {},
//queryOptions: {},
//start: 0,
//count: 20
}
The latter function may be useful for adapting a query or handling the fetch/filter for more complex patterns where paging is involved.
var filteredStore = new FilteringStore(store, function(items,args){
if(args.queryOptions && args.queryOptions.useFilter){
console.log("Filter Items here and then return {items: filter, count: filter.length} or similar");
var filtered = {};
filtered.items = dojo.filter(items, function(item){
if (item) {
var id = this.store.getIdentity(item);
//filter out items whose ID starts with A as an example
return (id.charAt(0)!="A")
}
});
filtered.count = filtered.items.length || -1;
return filtered;
}
return {
items: items,
count: items.length || -1
}
});
// example fetch everthing and log the count (bypass the filter given the filter logic above);
filteredStore.fetch({
query: {name: "*"},
onBegin: function(count){
console.log("Fetch (sans filter): " + count + " items: ");
},
onComplete: function(items){
console.log("items: ", items);
}
});
// fetch everthing and log the count (using the filter);
filteredStore.fetch({
query: {name: "*"},
queryOptions: {useFilter: true},
onBegin: function(count){
console.log("Fetch (sans filter): " + count + " items: ");
},
onComplete: function(items){
console.log("items: ", items);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment