Sorting on all series views is now working

New: Sorting is now persisted on a per page and browser basis
New: Series lists now support sorting on all views
This commit is contained in:
Mark McDowall
2013-12-27 00:31:34 -08:00
parent 4d6d477947
commit 6ba17782aa
13 changed files with 414 additions and 123 deletions
+18 -2
View File
@@ -1,13 +1,29 @@
'use strict';
define(
[
'underscore',
'backbone'
], function (Backbone) {
], function (_, Backbone) {
return Backbone.Model.extend({
defaults: {
'target' : '/nzbdrone/route',
'title' : '',
'active' : false,
'tooltip': undefined }
'tooltip': undefined
},
sortValue: function () {
var sortValue = this.get('sortValue');
if (_.isString(sortValue)) {
return this[sortValue];
}
else if (_.isFunction(sortValue)) {
return sortValue;
}
return function (model, colName) {
return model.get(colName);
};
}
});
});
@@ -13,7 +13,6 @@ define(
'click': 'onClick'
},
initialize: function () {
this.storageKey = this.model.get('menuKey') + ':' + this.model.get('key');
@@ -53,7 +52,6 @@ define(
callback.call(this.model.ownerContext);
}
}
});
});
@@ -0,0 +1,87 @@
'use strict';
define(
[
'backbone.pageable',
'marionette',
'Shared/Toolbar/Sorting/SortingButtonView'
], function (PageableCollection, Marionette, ButtonView) {
return Marionette.CompositeView.extend({
itemView : ButtonView,
template : 'Shared/Toolbar/Sorting/SortingButtonCollectionViewTemplate',
itemViewContainer: '.dropdown-menu',
initialize: function (options) {
this.viewCollection = options.viewCollection;
this.listenTo(this.viewCollection, 'drone:sort', this.sort);
},
itemViewOptions: function () {
return {
viewCollection: this.viewCollection
};
},
sort: function (sortModel, sortDirection) {
var collection = this.viewCollection;
var order;
if (sortDirection === 'ascending') {
order = -1;
}
else if (sortDirection === 'descending') {
order = 1;
}
else {
order = null;
}
var comparator = this.makeComparator(sortModel.get('name'), order,
order ?
sortModel.sortValue() :
function (model) {
return model.cid;
});
if (PageableCollection &&
collection instanceof PageableCollection) {
collection.setSorting(order && sortModel.get('name'), order,
{sortValue: sortModel.sortValue()});
if (collection.mode === 'client') {
if (collection.fullCollection.comparator === null) {
collection.fullCollection.comparator = comparator;
}
collection.fullCollection.sort();
}
else {
collection.fetch({reset: true});
}
}
else {
collection.comparator = comparator;
collection.sort();
}
return this;
},
makeComparator: function (attr, order, func) {
return function (left, right) {
// extract the values from the models
var l = func(left, attr), r = func(right, attr), t;
// if descending order, swap left and right
if (order === 1) t = l, l = r, r = t;
// compare as usual
if (l === r) return 0;
else if (l < r) return -1;
return 1;
};
}
});
});
@@ -0,0 +1,8 @@
<div class="btn-group sorting-buttons">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
Sort <span class="caret"></span>
</a>
<ul class="dropdown-menu">
</ul>
</div>
@@ -0,0 +1,84 @@
'use strict';
define(
[
'backbone',
'marionette',
'underscore'
], function (Backbone, Marionette, _) {
return Marionette.ItemView.extend({
template : 'Shared/Toolbar/Sorting/SortingButtonViewTemplate',
tagName : 'li',
ui: {
icon: 'i'
},
events: {
'click': 'onClick'
},
initialize: function (options) {
this.viewCollection = options.viewCollection;
this.listenTo(this.viewCollection, 'drone:sort', this.render);
this.listenTo(this.viewCollection, 'backgrid:sort', this.render);
},
onRender: function () {
if (this.viewCollection.state) {
var key = this.viewCollection.state.sortKey;
var order = this.viewCollection.state.order;
if (key === this.model.get('name')) {
this._setSortIcon(order);
}
else {
this._removeSortIcon();
}
}
},
onClick: function (e) {
e.preventDefault();
var collection = this.viewCollection;
var event = 'drone:sort';
collection.state.sortKey = this.model.get('name');
var direction = collection.state.order;
if (direction === 'ascending' || direction === -1)
{
collection.state.order = 'descending';
collection.trigger(event, this.model, 'descending');
}
else
{
collection.state.order = 'ascending';
collection.trigger(event, this.model, 'ascending');
}
},
_convertDirectionToIcon: function (dir) {
if (dir === 'ascending' || dir === -1) {
return 'icon-sort-up';
}
return 'icon-sort-down';
},
_setSortIcon: function (dir) {
this._removeSortIcon();
this.ui.icon.addClass(this._convertDirectionToIcon(dir));
},
_removeSortIcon: function () {
this.ui.icon.removeClass('icon-sort-up icon-sort-down');
}
});
});
@@ -0,0 +1,4 @@
<a href="#">
<span>{{title}}</span>
<i class=""></i>
</a>
+11 -1
View File
@@ -6,8 +6,9 @@ define(
'Shared/Toolbar/ButtonModel',
'Shared/Toolbar/Radio/RadioButtonCollectionView',
'Shared/Toolbar/Button/ButtonCollectionView',
'Shared/Toolbar/Sorting/SortingButtonCollectionView',
'underscore'
], function (Marionette, ButtonCollection, ButtonModel, RadioButtonCollectionView, ButtonCollectionView,_) {
], function (Marionette, ButtonCollection, ButtonModel, RadioButtonCollectionView, ButtonCollectionView, SortingButtonCollectionView, _) {
return Marionette.Layout.extend({
template: 'Shared/Toolbar/ToolbarLayoutTemplate',
@@ -78,6 +79,15 @@ define(
});
break;
}
case 'sorting':
{
buttonGroupView = new SortingButtonCollectionView({
collection : groupCollection,
menu : buttonGroup,
viewCollection: buttonGroup.viewCollection
});
break;
}
default :
{
buttonGroupView = new ButtonCollectionView({
@@ -1,8 +1,8 @@
<div class="pull-left page-toolbar">
<div class="x-toolbar-left-1"/>
<div class="x-toolbar-left-2"/>
<div class="toolbar-group x-toolbar-left-1"/>
<div class="toolbar-group x-toolbar-left-2"/>
</div>
<div class="pull-right page-toolbar">
<div class="x-toolbar-right-1"/>
<div class="x-toolbar-right-2"/>
<div class="toolbar-group x-toolbar-right-1"/>
<div class="toolbar-group x-toolbar-right-2"/>
</div>