Created
November 15, 2012 19:31
-
-
Save atuttle/4080686 to your computer and use it in GitHub Desktop.
Pagination plugin & Query plugin, sitting in a tree...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Confused? Start here: http://brian.io/lawnchair/ | |
This plugin takes two awesome other plugins and mashes their naughty bits together. | |
Queries are awesome. Pagination is awesome. Paginated Queries are awesome^2. | |
I take no credit for any of the heavy lifting done here, all I did was take two genius | |
things and smash them together. | |
*/ | |
// - NOT jsonPath or jsonQuery which are horrendously complex and fugly | |
// - simple query syntax 'its just javascript' | |
// - simple string interpolation | |
// - search then sorting | |
Lawnchair.plugin((function(){ | |
// | |
var interpolate = function(template, args) { | |
var parts = template.split('?').filter(function(i) { return i != ''}) | |
, query = '' | |
for (var i = 0, l = parts.length; i < l; i++) { | |
query += parts[i] + args[i] | |
} | |
return query | |
} | |
var sorter = function(p) { | |
return function(a, b) { | |
if (a[p] < b[p]) return -1 | |
if (a[p] > b[p]) return 1 | |
return 0 | |
} | |
} | |
// | |
return { | |
// query the storage obj | |
where: function() { | |
// ever notice we do this sort thing lots? | |
var args = [].slice.call(arguments) | |
, tmpl = args.shift() | |
, last = args[args.length - 1] | |
, qs = tmpl.match(/\?/g) | |
, q = qs && qs.length > 0 ? interpolate(tmpl, args.slice(0, qs.length)) : tmpl | |
, is = new Function(this.record, 'return !!(' + q + ')') | |
, r = [] | |
, cb | |
// iterate the entire collection | |
// TODO should we allow for chained where() to filter __results? (I'm thinking no b/c creates funny behvaiors w/ callbacks) | |
this.all(function(all){ | |
for (var i = 0, l = all.length; i < l; i++) { | |
if (is(all[i])) r.push(all[i]) | |
} | |
}) | |
// overwrite working results | |
this.__results = r | |
// callback / chain | |
if (args.length === 1) this.fn(this.name, last).call(this, this.__results) | |
return this | |
}, | |
// FIXME should be able to call without this.__results | |
// ascending sort the working storage obj on a property (or nested property) | |
asc: function(property, callback) { | |
this.fn(this.name, callback).call(this, this.__results.sort(sorter(property))) | |
return this | |
}, | |
// descending sort on working storage object on a property | |
desc: function(property, callback) { | |
this.fn(this.name, callback).call(this, this.__results.sort(sorter(property)).reverse()) | |
return this | |
}, | |
//mash in the page method from the pagination plugin | |
page: function (page, callback) { | |
// some defaults | |
var objs = [] | |
, count = 20 // TODO make this configurable | |
, cur = ~~page || 1 | |
, next = cur + 1 | |
, prev = cur - 1 | |
, start = cur == 1 ? 0 : prev*count | |
, end = start >= count ? start+count : count | |
// grab all the records | |
// FIXME if this was core we could use this.__results for faster queries | |
objs = this.__results | |
// grab the metadata | |
var max = Math.ceil(objs.length/count) | |
, page = { max: max | |
, next: next > max ? max : next | |
, prev: prev == 0 ? 1 : prev | |
} | |
// reassign to the working resultset | |
this.__results = page[this.name] = objs.slice(start, end) | |
// callback / chain | |
if (callback) this.fn('page', callback).call(this, page) | |
return this | |
} | |
} | |
///// | |
})()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment