Skip to content

Instantly share code, notes, and snippets.

@jshirley
Created August 28, 2012 17:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jshirley/3501358 to your computer and use it in GitHub Desktop.
Save jshirley/3501358 to your computer and use it in GitHub Desktop.
An extension to mix-in to your ModelList to support pagination. Still WIP.
YUI.add('paged-model-list', function(Y) {
var NS = Y.namespace('BackOffice.Model'),
Lang = Y.Lang,
isString = Lang.isString,
isArray = Lang.isArray,
isObject = Lang.isObject;
function PagedList() { }
PagedList.prototype = {
timer : null,
initializer : function() {
this.after('startIndexChange', this.initiateLoad, this);
//this.after('sortDirChange', this.initiateLoad, this);
//this.after('sortByChange', this.initiateLoad, this);
this.after('filtersChange', this.initiateLoad, this);
Y.Do.after( '_extractMeta', this, 'parse', this );
},
initiateLoad : function(e) {
if ( this.timer || ( e.options && e.options.silent ) ) {
return;
}
this.timer = Y.later(250, this, function() {
this.timer = null;
this.load()
});
},
_extractMeta : function(response) {
if ( isString(response) ) {
response = Y.JSON.parse(response);
}
this.setAttrs({
'startIndex' : parseInt(response.startIndex, 10),
'pageSize' : parseInt(response.pageSize, 10),
'totalRecords' : parseInt(response.totalRecords, 10),
'totalRecs' : parseInt(response.totalRecords, 10),
'sortDir' : response.dir,
'sortBy' : response.sort
}, {
silent : true
});
return response.records;
},
next : function() {
var current = this.get('startIndex'),
count = this.get('pageSize'),
total = this.get('totalRecords'),
next = current + count;
if ( next >= total ) {
return;
}
this.set('startIndex', next);
},
prev : function() {
var current = this.get('startIndex'),
count = this.get('pageSize'),
next = current - count;
if ( next < 0 ) {
next = 0;
}
this.set('startIndex', next);
},
page : function() {
var current = this.get('startIndex'),
count = this.get('totalRecords') || 1;
if ( typeof current === 'undefined' || current === null ) {
current = 0;
}
return Math.floor( current / count ) + 1;
},
filters_as_string : function() {
var filters = this.get('filters'),
buffer = [];
Y.Object.each( filters, function(value, key) {
buffer.push( encodeURIComponent(key) + '=' + encodeURIComponent(value) );
});
return buffer.join('&') || '';
},
addFilter : function(name, value) {
var filters = this.get('filters');
filters[name] = value;
// Reset this to fire the filtersChange event
this.set('filters', filters);
return filters;
},
removeFilter : function(name) {
var filters = this.get('filters');
delete filters[name];
// Reset this to fire the filtersChange event
this.set('filters', filters);
return filters;
},
// We are overriding this because we don't want filter_string to be encoded
// so we simply append it to the end of the url.
getURL : function(action) {
var url = Y.ModelSync.REST.prototype.getURL.apply(this, arguments);
if ( action === 'read' ) {
url += '&' + this.get('filter_string');
}
return url;
},
_setSortBy : function(val) {
var sortDir = this.get('sortDir'),
sortKey,
maps = this.get('sortKeyMaps');
if ( isArray(val) ) {
val = val[0];
}
if ( isObject(val) ) {
Y.Object.each( val, function(dir, key) {
sortKey = key;
sortDir = dir;
} );
} else {
sortKey = val;
}
if ( maps[sortKey] ) {
sortKey = maps[sortKey];
}
this.set('sortDir', sortDir);
return sortKey;
}
};
PagedList.ATTRS = {
startIndex : { value : 0 },
sortBy : { setter : '_setSortBy' },
sortDir : { },
totalRecords : { },
totalRecs : { },
page : { getter : 'page' },
pageSize : { value : 25 },
filters : { value : { } },
filter_string: { getter : 'filters_as_string' },
/**
This attribute allows a displayable sort key to be remapped before
being stored as a key to filter on. It's useful for nesting keys
like `profile.member_id` when the table key is merely `member_id`.
Look at user-list as an example of usage.
@attribute sortKeyMaps
@type Object
**/
sortKeyMaps : { value : { } }
};
Y.namespace('ModelExt').PagedList = PagedList;
}, '0.1.0', {
requires : [ 'model-list' ]
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment