Created
January 3, 2013 17:24
-
-
Save loicfrering/4445123 to your computer and use it in GitHub Desktop.
backbone.datagrid v0.3.2-alpha
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
// backbone.datagrid v0.3.2-alpha | |
// | |
// Copyright (c) 2012 Loïc Frering <[email protected]> | |
// Distributed under the MIT license | |
(function() { | |
var Datagrid = Backbone.View.extend({ | |
initialize: function() { | |
this.columns = this.options.columns; | |
this.options = _.defaults(this.options, { | |
paginated: false, | |
page: 1, | |
perPage: 10, | |
tableClassName: 'table' | |
}); | |
this.collection.on('reset', this.render, this); | |
this._prepare(); | |
}, | |
render: function() { | |
this.$el.empty(); | |
this.renderTable(); | |
if (this.options.paginated) { | |
this.renderPagination(); | |
} | |
return this; | |
}, | |
renderTable: function() { | |
var $table = $('<table></table>', {'class': this.options.tableClassName}); | |
this.$el.append($table); | |
var header = new Header({columns: this.columns, sorter: this.sorter}); | |
$table.append(header.render().el); | |
$table.append('<tbody></tbody>'); | |
this.collection.forEach(this.renderRow, this); | |
}, | |
renderPagination: function() { | |
var pagination = new Pagination({pager: this.pager}); | |
this.$el.append(pagination.render().el); | |
}, | |
renderRow: function(model) { | |
var options = { | |
model: model, | |
columns: this.columns | |
}; | |
var rowClassName = this.options.rowClassName; | |
if (_.isFunction(rowClassName)) { | |
rowClassName = rowClassName(model); | |
} | |
options.className = rowClassName; | |
var row = new Row(options); | |
this.$('tbody').append(row.render(this.columns).el); | |
}, | |
refresh: function(options) { | |
if (this.options.paginated) { | |
this._page(options); | |
} else { | |
if (this.options.inMemory) { | |
this.collection.trigger('reset', this.collection); | |
if (options && options.success) { | |
options.success(); | |
} | |
} else { | |
this._request(options); | |
} | |
} | |
}, | |
sort: function(column, order) { | |
this.sorter.sort(column, order); | |
}, | |
page: function(page) { | |
this.pager.page(page); | |
}, | |
perPage: function(perPage) { | |
this.pager.set('perPage', perPage); | |
}, | |
_sort: function() { | |
if (this.options.inMemory) { | |
this._sortInMemory(); | |
} else { | |
this._sortRequest(); | |
} | |
}, | |
_sortInMemory: function() { | |
if (this.options.paginated) { | |
this._originalCollection.comparator = _.bind(this._comparator, this); | |
this._originalCollection.sort(); | |
this.page(1); | |
} else { | |
this.collection.comparator = _.bind(this._comparator, this); | |
this.collection.sort(); | |
} | |
}, | |
_comparator: function(model1, model2) { | |
var columnComparator = this._comparatorForColumn(this.sorter.get('column')); | |
var order = columnComparator(model1, model2); | |
return this.sorter.sortedASC() ? order : -order; | |
}, | |
_comparatorForColumn: function(column) { | |
var c = _.find(this.columns, function(c) { | |
return c.property === column || c.index === column; | |
}); | |
return c ? c.comparator : undefined; | |
}, | |
_sortRequest: function() { | |
this._request(); | |
}, | |
_page: function(options) { | |
if (this.options.inMemory) { | |
this._pageInMemory(options); | |
} else { | |
this._pageRequest(options); | |
} | |
}, | |
_pageRequest: function(options) { | |
this._request(options); | |
}, | |
_request: function(options) { | |
options = options || {}; | |
var success = options.success; | |
var silent = options.silent; | |
options.data = this._getRequestData(); | |
options.success = _.bind(function(collection) { | |
if (!this.columns || _.isEmpty(this.columns)) { | |
this._prepareColumns(); | |
} | |
if (success) { | |
success(); | |
} | |
if (this.options.paginated) { | |
this.pager.update(collection); | |
} | |
if (!silent) { | |
collection.trigger('reset', collection); | |
} | |
}, this); | |
options.silent = true; | |
this.collection.fetch(options); | |
}, | |
_getRequestData: function() { | |
if (this.collection.data && _.isFunction(this.collection.data)) { | |
return this.collection.data(this.pager, this.sorter); | |
} else if (this.collection.data && typeof this.collection.data === 'object') { | |
var data = {}; | |
_.each(this.collection.data, function(value, param) { | |
if (_.isFunction(value)) { | |
value = value(this.pager, this.sorter); | |
} | |
data[param] = value; | |
}, this); | |
return data; | |
} else if (this.options.paginated) { | |
return { | |
page: this.pager.get('currentPage'), | |
per_page: this.pager.get('perPage') | |
}; | |
} | |
return {}; | |
}, | |
_pageInMemory: function(options) { | |
if (!this._originalCollection) { | |
this._originalCollection = this.collection.clone(); | |
} | |
var page = this.pager.get('currentPage'); | |
var perPage = this.pager.get('perPage'); | |
var begin = (page - 1) * perPage; | |
var end = begin + perPage; | |
if (options && options.success) { | |
options.success(); | |
} | |
this.pager.set('total', this._originalCollection.size()); | |
this.collection.reset(this._originalCollection.slice(begin, end), options); | |
}, | |
_prepare: function() { | |
this._prepareSorter(); | |
this._preparePager(); | |
this._prepareColumns(); | |
this.refresh(); | |
}, | |
_prepareSorter: function() { | |
this.sorter = new Sorter(); | |
this.sorter.on('change', function() { | |
this._sort(this.sorter.get('column'), this.sorter.get('order')); | |
}, this); | |
}, | |
_preparePager: function() { | |
this.pager = new Pager({ | |
currentPage: this.options.page, | |
perPage: this.options.perPage | |
}); | |
this.pager.on('change:currentPage', function () { | |
this._page(); | |
}, this); | |
this.pager.on('change:perPage', function() { | |
this.page(1); | |
}, this); | |
}, | |
_prepareColumns: function() { | |
if (!this.columns || _.isEmpty(this.columns)) { | |
this._defaultColumns(); | |
} else { | |
_.each(this.columns, function(column, i) { | |
this.columns[i] = this._prepareColumn(column, i); | |
}, this); | |
} | |
}, | |
_prepareColumn: function(column, index) { | |
if (_.isString(column)) { | |
column = { property: column }; | |
} | |
if (_.isObject(column)) { | |
column.index = index; | |
if (column.property) { | |
column.title = column.title || this._formatTitle(column.property); | |
} else if (!column.property && !column.view) { | |
throw new Error('Column \'' + column.title + '\' has no property and must accordingly define a custom cell view.'); | |
} | |
if (this.options.inMemory && column.sortable) { | |
if (!column.comparator && !column.property && !column.sortedProperty) { | |
throw new Error('Invalid column definition: a sortable column must have a comparator, property or sortedProperty defined.'); | |
} | |
column.comparator = column.comparator || this._defaultComparator(column.sortedProperty || column.property); | |
} | |
} | |
return column; | |
}, | |
_formatTitle: function(title) { | |
return _.map(title.split(/\s|_/), function(word) { | |
return word.charAt(0).toUpperCase() + word.substr(1); | |
}).join(' '); | |
}, | |
_defaultColumns: function() { | |
this.columns = []; | |
var model = this.collection.first(), i = 0; | |
if (model) { | |
for (var p in model.toJSON()) { | |
this.columns.push(this._prepareColumn(p, i++)); | |
} | |
} | |
}, | |
_defaultComparator: function(column) { | |
return function(model1, model2) { | |
var val1 = model1.has(column) ? model1.get(column) : ''; | |
var val2 = model2.has(column) ? model2.get(column) : ''; | |
return val1.localeCompare(val2); | |
}; | |
} | |
}); | |
var Header = Datagrid.Header = Backbone.View.extend({ | |
tagName: 'thead', | |
initialize: function() { | |
this.columns = this.options.columns; | |
this.sorter = this.options.sorter; | |
}, | |
render: function() { | |
var model = new Backbone.Model(); | |
var headerColumn, columns = []; | |
_.each(this.columns, function(column, i) { | |
headerColumn = _.clone(column); | |
headerColumn.property = column.property || column.index; | |
headerColumn.view = column.headerView || { | |
type: HeaderCell, | |
sorter: this.sorter | |
}; | |
model.set(headerColumn.property, column.title); | |
columns.push(headerColumn); | |
}, this); | |
var row = new Row({model: model, columns: columns, header: true}); | |
this.$el.html(row.render().el); | |
return this; | |
} | |
}); | |
var Row = Datagrid.Row = Backbone.View.extend({ | |
tagName: 'tr', | |
initialize: function() { | |
this.columns = this.options.columns; | |
this.model.on('change', this.render, this); | |
}, | |
render: function() { | |
this.$el.empty(); | |
_.each(this.columns, this.renderCell, this); | |
return this; | |
}, | |
renderCell: function(column) { | |
var cellView = this._resolveCellView(column); | |
this.$el.append(cellView.render().el); | |
}, | |
_resolveCellView: function(column) { | |
var options = { | |
model: this.model, | |
column: column | |
}; | |
if (this.options.header || column.header) { | |
options.tagName = 'th'; | |
} | |
var cellClassName = column.cellClassName; | |
if (_.isFunction(cellClassName)) { | |
cellClassName = cellClassName(this.model); | |
} | |
options.className = cellClassName; | |
var view = column.view || Cell; | |
// Resolve view from string or function | |
if (typeof view !== 'object' && !(view.prototype && view.prototype.render)) { | |
if (_.isString(view)) { | |
options.callback = _.template(view); | |
view = CallbackCell; | |
} else if (_.isFunction(view) && !view.prototype.render) { | |
options.callback = view; | |
view = CallbackCell; | |
} else { | |
throw new TypeError('Invalid view passed to column "' + column.title + '".'); | |
} | |
} | |
// Resolve view from options | |
else if (typeof view === 'object') { | |
_.extend(options, view); | |
view = view.type; | |
if (!view || !view.prototype || !view.prototype.render) { | |
throw new TypeError('Invalid view passed to column "' + column.title + '".'); | |
} | |
} | |
return new view(options); | |
} | |
}); | |
var Pagination = Datagrid.Pagination = Backbone.View.extend({ | |
className: 'pagination pagination-centered', | |
events: { | |
'click li:not(.disabled) a': 'page', | |
'click li.disabled a': function(e) { e.preventDefault(); } | |
}, | |
initialize: function() { | |
this.pager = this.options.pager; | |
}, | |
render: function() { | |
var $ul = $('<ul></ul>'), $li; | |
$li = $('<li class="prev"><a href="#">«</a></li>'); | |
if (!this.pager.hasPrev()) { | |
$li.addClass('disabled'); | |
} | |
$ul.append($li); | |
if (this.pager.hasTotal()) { | |
for (var i = 1; i <= this.pager.get('totalPages'); i++) { | |
$li = $('<li></li>'); | |
if (i === this.pager.get('currentPage')) { | |
$li.addClass('active'); | |
} | |
$li.append('<a href="#">' + i + '</a>'); | |
$ul.append($li); | |
} | |
} | |
$li = $('<li class="next"><a href="#">»</a></li>'); | |
if (!this.pager.hasNext()) { | |
$li.addClass('disabled'); | |
} | |
$ul.append($li); | |
this.$el.append($ul); | |
return this; | |
}, | |
page: function(event) { | |
var $target = $(event.target), page; | |
if ($target.parent().hasClass('prev')) { | |
this.pager.prev(); | |
} else if ($target.parent().hasClass('next')) { | |
this.pager.next(); | |
} | |
else { | |
this.pager.page(parseInt($(event.target).html(), 10)); | |
} | |
return false; | |
} | |
}); | |
var Cell = Datagrid.Cell = Backbone.View.extend({ | |
tagName: 'td', | |
initialize: function() { | |
this.column = this.options.column; | |
}, | |
render: function() { | |
this._prepareValue(); | |
this.$el.html(this.value); | |
return this; | |
}, | |
_prepareValue: function() { | |
this.value = this.model.get(this.column.property); | |
} | |
}); | |
var CallbackCell = Datagrid.CallbackCell = Cell.extend({ | |
initialize: function() { | |
CallbackCell.__super__.initialize.call(this); | |
this.callback = this.options.callback; | |
}, | |
_prepareValue: function() { | |
this.value = this.callback(this.model.toJSON()); | |
} | |
}); | |
var ActionCell = Datagrid.ActionCell = Cell.extend({ | |
initialize: function() { | |
ActionCell.__super__.initialize.call(this); | |
}, | |
action: function() { | |
return this.options.action(this.model); | |
}, | |
_prepareValue: function() { | |
var a = $('<a></a>'); | |
a.html(this.options.label); | |
a.attr('href', this.options.href || '#'); | |
if (this.options.actionClassName) { | |
a.addClass(this.options.actionClassName); | |
} | |
if (this.options.action) { | |
this.delegateEvents({ | |
'click a': this.action | |
}); | |
} | |
this.value = a; | |
} | |
}); | |
var HeaderCell = Datagrid.HeaderCell = Cell.extend({ | |
initialize: function() { | |
HeaderCell.__super__.initialize.call(this); | |
this.sorter = this.options.sorter; | |
if (this.column.sortable) { | |
this.delegateEvents({click: 'sort'}); | |
} | |
}, | |
render: function() { | |
this._prepareValue(); | |
var html = this.value, icon; | |
if (this.column.sortable) { | |
this.$el.addClass('sortable'); | |
if (this.sorter.sortedBy(this.column.sortedProperty || this.column.property) || this.sorter.sortedBy(this.column.index)) { | |
if (this.sorter.sortedASC()) { | |
icon = 'icon-chevron-up'; | |
} else { | |
icon = 'icon-chevron-down'; | |
} | |
} else { | |
icon = 'icon-minus'; | |
} | |
html += ' <i class="' + icon + ' pull-right"></i>'; | |
} | |
this.$el.html(html); | |
return this; | |
}, | |
sort: function() { | |
this.sorter.sort(this.column.sortedProperty || this.column.property); | |
} | |
}); | |
var Pager = Datagrid.Pager = Backbone.Model.extend({ | |
initialize: function() { | |
this.on('change:perPage change:total', function() { | |
this.totalPages(this.get('total')); | |
}, this); | |
if (this.has('total')) { | |
this.totalPages(this.get('total')); | |
} | |
}, | |
update: function(options) { | |
_.each(['hasNext', 'hasPrev', 'total', 'totalPages', 'lastPage'], function(p) { | |
if (!_.isUndefined(options[p])) { | |
this.set(p, options[p]); | |
} | |
}, this); | |
}, | |
totalPages: function(total) { | |
if (_.isNumber(total)) { | |
this.set('totalPages', Math.ceil(total/this.get('perPage'))); | |
} else { | |
this.set('totalPages', undefined); | |
} | |
}, | |
page: function(page) { | |
if (this.inBounds(page)) { | |
if (page === this.get('currentPage')) { | |
this.trigger('change:currentPage'); | |
} else { | |
this.set('currentPage', page); | |
} | |
} | |
}, | |
next: function() { | |
this.page(this.get('currentPage') + 1); | |
}, | |
prev: function() { | |
this.page(this.get('currentPage') - 1); | |
}, | |
hasTotal: function() { | |
return this.has('totalPages'); | |
}, | |
hasNext: function() { | |
if (this.hasTotal()) { | |
return this.get('currentPage') < this.get('totalPages'); | |
} else { | |
return this.get('hasNext'); | |
} | |
}, | |
hasPrev: function() { | |
if (this.has('hasPrev')) { | |
return this.get('hasPrev'); | |
} else { | |
return this.get('currentPage') > 1; | |
} | |
}, | |
inBounds: function(page) { | |
return !this.hasTotal() || page > 0 && page <= this.get('totalPages'); | |
}, | |
validate: function(attrs) { | |
if (attrs.perPage < 1) { | |
throw new Error('perPage must be greater than zero.'); | |
} | |
} | |
}); | |
var Sorter = Datagrid.Sorter = Backbone.Model.extend({ | |
sort: function(column, order) { | |
if (!order && this.get('column') === column) { | |
this.toggleOrder(); | |
} else { | |
this.set({ | |
column: column, | |
order: order || Sorter.ASC | |
}); | |
} | |
}, | |
sortedBy: function(column) { | |
return this.get('column') === column; | |
}, | |
sortedASC: function() { | |
return this.get('order') === Sorter.ASC; | |
}, | |
sortedDESC: function() { | |
return this.get('order') === Sorter.DESC; | |
}, | |
toggleOrder: function() { | |
if (this.get('order') === Sorter.ASC) { | |
this.set('order', Sorter.DESC); | |
} else { | |
this.set('order', Sorter.ASC); | |
} | |
} | |
}); | |
Sorter.ASC = 'asc'; | |
Sorter.DESC = 'desc'; | |
Backbone.Datagrid = Datagrid; | |
})(); |
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
// backbone.datagrid v0.3.2-alpha | |
// | |
// Copyright (c) 2012 Loïc Frering <[email protected]> | |
// Distributed under the MIT license | |
(function(){var e=Backbone.View.extend({initialize:function(){this.columns=this.options.columns,this.options=_.defaults(this.options,{paginated:!1,page:1,perPage:10,tableClassName:"table"}),this.collection.on("reset",this.render,this),this._prepare()},render:function(){return this.$el.empty(),this.renderTable(),this.options.paginated&&this.renderPagination(),this},renderTable:function(){var e=$("<table></table>",{"class":this.options.tableClassName});this.$el.append(e);var n=new t({columns:this.columns,sorter:this.sorter});e.append(n.render().el),e.append("<tbody></tbody>"),this.collection.forEach(this.renderRow,this)},renderPagination:function(){var e=new r({pager:this.pager});this.$el.append(e.render().el)},renderRow:function(e){var t={model:e,columns:this.columns},r=this.options.rowClassName;_.isFunction(r)&&(r=r(e)),t.className=r;var i=new n(t);this.$("tbody").append(i.render(this.columns).el)},refresh:function(e){this.options.paginated?this._page(e):this.options.inMemory?(this.collection.trigger("reset",this.collection),e&&e.success&&e.success()):this._request(e)},sort:function(e,t){this.sorter.sort(e,t)},page:function(e){this.pager.page(e)},perPage:function(e){this.pager.set("perPage",e)},_sort:function(){this.options.inMemory?this._sortInMemory():this._sortRequest()},_sortInMemory:function(){this.options.paginated?(this._originalCollection.comparator=_.bind(this._comparator,this),this._originalCollection.sort(),this.page(1)):(this.collection.comparator=_.bind(this._comparator,this),this.collection.sort())},_comparator:function(e,t){var n=this._comparatorForColumn(this.sorter.get("column")),r=n(e,t);return this.sorter.sortedASC()?r:-r},_comparatorForColumn:function(e){var t=_.find(this.columns,function(t){return t.property===e||t.index===e});return t?t.comparator:undefined},_sortRequest:function(){this._request()},_page:function(e){this.options.inMemory?this._pageInMemory(e):this._pageRequest(e)},_pageRequest:function(e){this._request(e)},_request:function(e){e=e||{};var t=e.success,n=e.silent;e.data=this._getRequestData(),e.success=_.bind(function(e){(!this.columns||_.isEmpty(this.columns))&&this._prepareColumns(),t&&t(),this.options.paginated&&this.pager.update(e),n||e.trigger("reset",e)},this),e.silent=!0,this.collection.fetch(e)},_getRequestData:function(){if(this.collection.data&&_.isFunction(this.collection.data))return this.collection.data(this.pager,this.sorter);if(this.collection.data&&typeof this.collection.data=="object"){var e={};return _.each(this.collection.data,function(t,n){_.isFunction(t)&&(t=t(this.pager,this.sorter)),e[n]=t},this),e}return this.options.paginated?{page:this.pager.get("currentPage"),per_page:this.pager.get("perPage")}:{}},_pageInMemory:function(e){this._originalCollection||(this._originalCollection=this.collection.clone());var t=this.pager.get("currentPage"),n=this.pager.get("perPage"),r=(t-1)*n,i=r+n;e&&e.success&&e.success(),this.pager.set("total",this._originalCollection.size()),this.collection.reset(this._originalCollection.slice(r,i),e)},_prepare:function(){this._prepareSorter(),this._preparePager(),this._prepareColumns(),this.refresh()},_prepareSorter:function(){this.sorter=new f,this.sorter.on("change",function(){this._sort(this.sorter.get("column"),this.sorter.get("order"))},this)},_preparePager:function(){this.pager=new a({currentPage:this.options.page,perPage:this.options.perPage}),this.pager.on("change:currentPage",function(){this._page()},this),this.pager.on("change:perPage",function(){this.page(1)},this)},_prepareColumns:function(){!this.columns||_.isEmpty(this.columns)?this._defaultColumns():_.each(this.columns,function(e,t){this.columns[t]=this._prepareColumn(e,t)},this)},_prepareColumn:function(e,t){_.isString(e)&&(e={property:e});if(_.isObject(e)){e.index=t;if(e.property)e.title=e.title||this._formatTitle(e.property);else if(!e.property&&!e.view)throw new Error("Column '"+e.title+"' has no property and must accordingly define a custom cell view.");if(this.options.inMemory&&e.sortable){if(!e.comparator&&!e.property&&!e.sortedProperty)throw new Error("Invalid column definition: a sortable column must have a comparator, property or sortedProperty defined.");e.comparator=e.comparator||this._defaultComparator(e.sortedProperty||e.property)}}return e},_formatTitle:function(e){return _.map(e.split(/\s|_/),function(e){return e.charAt(0).toUpperCase()+e.substr(1)}).join(" ")},_defaultColumns:function(){this.columns=[];var e=this.collection.first(),t=0;if(e)for(var n in e.toJSON())this.columns.push(this._prepareColumn(n,t++))},_defaultComparator:function(e){return function(t,n){var r=t.has(e)?t.get(e):"",i=n.has(e)?n.get(e):"";return r.localeCompare(i)}}}),t=e.Header=Backbone.View.extend({tagName:"thead",initialize:function(){this.columns=this.options.columns,this.sorter=this.options.sorter},render:function(){var e=new Backbone.Model,t,r=[];_.each(this.columns,function(n,i){t=_.clone(n),t.property=n.property||n.index,t.view=n.headerView||{type:u,sorter:this.sorter},e.set(t.property,n.title),r.push(t)},this);var i=new n({model:e,columns:r,header:!0});return this.$el.html(i.render().el),this}}),n=e.Row=Backbone.View.extend({tagName:"tr",initialize:function(){this.columns=this.options.columns,this.model.on("change",this.render,this)},render:function(){return this.$el.empty(),_.each(this.columns,this.renderCell,this),this},renderCell:function(e){var t=this._resolveCellView(e);this.$el.append(t.render().el)},_resolveCellView:function(e){var t={model:this.model,column:e};if(this.options.header||e.header)t.tagName="th";var n=e.cellClassName;_.isFunction(n)&&(n=n(this.model)),t.className=n;var r=e.view||i;if(typeof r!="object"&&(!r.prototype||!r.prototype.render))if(_.isString(r))t.callback=_.template(r),r=s;else{if(!_.isFunction(r)||!!r.prototype.render)throw new TypeError('Invalid view passed to column "'+e.title+'".');t.callback=r,r=s}else if(typeof r=="object"){_.extend(t,r),r=r.type;if(!r||!r.prototype||!r.prototype.render)throw new TypeError('Invalid view passed to column "'+e.title+'".')}return new r(t)}}),r=e.Pagination=Backbone.View.extend({className:"pagination pagination-centered",events:{"click li:not(.disabled) a":"page","click li.disabled a":function(e){e.preventDefault()}},initialize:function(){this.pager=this.options.pager},render:function(){var e=$("<ul></ul>"),t;t=$('<li class="prev"><a href="#">«</a></li>'),this.pager.hasPrev()||t.addClass("disabled"),e.append(t);if(this.pager.hasTotal())for(var n=1;n<=this.pager.get("totalPages");n++)t=$("<li></li>"),n===this.pager.get("currentPage")&&t.addClass("active"),t.append('<a href="#">'+n+"</a>"),e.append(t);return t=$('<li class="next"><a href="#">»</a></li>'),this.pager.hasNext()||t.addClass("disabled"),e.append(t),this.$el.append(e),this},page:function(e){var t=$(e.target),n;return t.parent().hasClass("prev")?this.pager.prev():t.parent().hasClass("next")?this.pager.next():this.pager.page(parseInt($(e.target).html(),10)),!1}}),i=e.Cell=Backbone.View.extend({tagName:"td",initialize:function(){this.column=this.options.column},render:function(){return this._prepareValue(),this.$el.html(this.value),this},_prepareValue:function(){this.value=this.model.get(this.column.property)}}),s=e.CallbackCell=i.extend({initialize:function(){s.__super__.initialize.call(this),this.callback=this.options.callback},_prepareValue:function(){this.value=this.callback(this.model.toJSON())}}),o=e.ActionCell=i.extend({initialize:function(){o.__super__.initialize.call(this)},action:function(){return this.options.action(this.model)},_prepareValue:function(){var e=$("<a></a>");e.html(this.options.label),e.attr("href",this.options.href||"#"),this.options.actionClassName&&e.addClass(this.options.actionClassName),this.options.action&&this.delegateEvents({"click a":this.action}),this.value=e}}),u=e.HeaderCell=i.extend({initialize:function(){u.__super__.initialize.call(this),this.sorter=this.options.sorter,this.column.sortable&&this.delegateEvents({click:"sort"})},render:function(){this._prepareValue();var e=this.value,t;return this.column.sortable&&(this.$el.addClass("sortable"),this.sorter.sortedBy(this.column.sortedProperty||this.column.property)||this.sorter.sortedBy(this.column.index)?this.sorter.sortedASC()?t="icon-chevron-up":t="icon-chevron-down":t="icon-minus",e+=' <i class="'+t+' pull-right"></i>'),this.$el.html(e),this},sort:function(){this.sorter.sort(this.column.sortedProperty||this.column.property)}}),a=e.Pager=Backbone.Model.extend({initialize:function(){this.on("change:perPage change:total",function(){this.totalPages(this.get("total"))},this),this.has("total")&&this.totalPages(this.get("total"))},update:function(e){_.each(["hasNext","hasPrev","total","totalPages","lastPage"],function(t){_.isUndefined(e[t])||this.set(t,e[t])},this)},totalPages:function(e){_.isNumber(e)?this.set("totalPages",Math.ceil(e/this.get("perPage"))):this.set("totalPages",undefined)},page:function(e){this.inBounds(e)&&(e===this.get("currentPage")?this.trigger("change:currentPage"):this.set("currentPage",e))},next:function(){this.page(this.get("currentPage")+1)},prev:function(){this.page(this.get("currentPage")-1)},hasTotal:function(){return this.has("totalPages")},hasNext:function(){return this.hasTotal()?this.get("currentPage")<this.get("totalPages"):this.get("hasNext")},hasPrev:function(){return this.has("hasPrev")?this.get("hasPrev"):this.get("currentPage")>1},inBounds:function(e){return!this.hasTotal()||e>0&&e<=this.get("totalPages")},validate:function(e){if(e.perPage<1)throw new Error("perPage must be greater than zero.")}}),f=e.Sorter=Backbone.Model.extend({sort:function(e,t){!t&&this.get("column")===e?this.toggleOrder():this.set({column:e,order:t||f.ASC})},sortedBy:function(e){return this.get("column")===e},sortedASC:function(){return this.get("order")===f.ASC},sortedDESC:function(){return this.get("order")===f.DESC},toggleOrder:function(){this.get("order")===f.ASC?this.set("order",f.DESC):this.set("order",f.ASC)}});f.ASC="asc",f.DESC="desc",Backbone.Datagrid=e})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment