added advanced subsort support - can now subsort with any arbitrary number of keys

This commit is contained in:
alex-phillips 2016-03-20 11:22:58 -04:00
parent 733f3a4634
commit e758503b0d
2 changed files with 33 additions and 37 deletions

View file

@ -280,54 +280,52 @@
* *
* @source https://github.com/vuejs/vue/blob/dev/src/filters/array-filters.js * @source https://github.com/vuejs/vue/blob/dev/src/filters/array-filters.js
*/ */
Vue.filter('caseInsensitiveOrderBy', (arr, sortKey, reverse, subSortKey) => { Vue.filter('caseInsensitiveOrderBy', (arr, sortKey, reverse) => {
if (!sortKey) { if (!sortKey) {
return arr; return arr;
} }
let order = (reverse && reverse < 0) ? -1 : 1; let order = (reverse && reverse < 0) ? -1 : 1;
function compareRecordsByKey(a, b, key) {
let aKey = Vue.util.isObject(a) ? Vue.parsers.path.getPath(a, key) : a;
let bKey = Vue.util.isObject(b) ? Vue.parsers.path.getPath(b, key) : b;
if (_.isNumber(aKey) && _.isNumber(bKey)) {
return aKey === bKey ? 0 : aKey > bKey;
}
aKey = aKey === undefined ? aKey : aKey.toLowerCase();
bKey = bKey === undefined ? bKey : bKey.toLowerCase();
return aKey === bKey ? 0 : aKey > bKey;
}
// sort on a copy to avoid mutating original array // sort on a copy to avoid mutating original array
return arr.slice().sort((a, b) => { return arr.slice().sort((a, b) => {
let aSub = subSortKey ? Vue.util.isObject(a) ? Vue.parsers.path.getPath(a, subSortKey) : 0 : 0; if (sortKey.constructor === Array) {
let bSub = subSortKey ? Vue.util.isObject(b) ? Vue.parsers.path.getPath(b, subSortKey) : 0 : 0; let diff = 0;
for (let i = 0; i < sortKey.length; i++) {
diff = compareRecordsByKey(a, b, sortKey[i]);
if (diff !== 0) {
break;
}
}
return diff === 0 ? 0 : diff === true ? order : - order;
}
a = Vue.util.isObject(a) ? Vue.parsers.path.getPath(a, sortKey) : a; a = Vue.util.isObject(a) ? Vue.parsers.path.getPath(a, sortKey) : a;
b = Vue.util.isObject(b) ? Vue.parsers.path.getPath(b, sortKey) : b; b = Vue.util.isObject(b) ? Vue.parsers.path.getPath(b, sortKey) : b;
if (_.isNumber(a) && _.isNumber(b)) { if (_.isNumber(a) && _.isNumber(b)) {
if (a === b) { return a === b ? 0 : a > b ? order : -order;
if (_.isNumber(aSub) && _.isNumber(bSub)) {
return aSub === bSub ? 0 : aSub > bSub ? order : -order;
} else if (aSub && bSub) {
aSub = aSub.toLowerCase();
bSub = bSub.toLowerCase();
return aSub === bSub ? 0 : aSub > bSub ? order : -order;
}
return 0;
}
return a > b ? order : -order;
} }
a = a === undefined ? a : a.toLowerCase(); a = a === undefined ? a : a.toLowerCase();
b = b === undefined ? b : b.toLowerCase(); b = b === undefined ? b : b.toLowerCase();
if (a === b) { return a === b ? 0 : a > b ? order : -order;
if (_.isNumber(aSub) && _.isNumber(bSub)) {
return aSub === bSub ? 0 : aSub > bSub ? order : -order;
} else if (aSub && bSub) {
aSub = aSub.toLowerCase();
bSub = bSub.toLowerCase();
return aSub === bSub ? 0 : aSub > bSub ? order : -order;
}
return 0;
}
return a > b ? order : -order;
}); });
}); });

View file

@ -15,11 +15,11 @@
<i class="fa fa-angle-down" v-show="sortKey === 'title' && order > 0"></i> <i class="fa fa-angle-down" v-show="sortKey === 'title' && order > 0"></i>
<i class="fa fa-angle-up" v-show="sortKey === 'title' && order < 0"></i> <i class="fa fa-angle-up" v-show="sortKey === 'title' && order < 0"></i>
</th> </th>
<th @click="sort('album.artist.name')">Artist <th @click="sort(['album.artist.name', 'album.name', 'track'])">Artist
<i class="fa fa-angle-down" v-show="sortKey === 'album.artist.name' && order > 0"></i> <i class="fa fa-angle-down" v-show="sortKey === 'album.artist.name' && order > 0"></i>
<i class="fa fa-angle-up" v-show="sortKey === 'album.artist.name' && order < 0"></i> <i class="fa fa-angle-up" v-show="sortKey === 'album.artist.name' && order < 0"></i>
</th> </th>
<th @click="sort('album.name', 'track')">Album <th @click="sort(['album.name', 'track'])">Album
<i class="fa fa-angle-down" v-show="sortKey === 'album.name' && order > 0"></i> <i class="fa fa-angle-down" v-show="sortKey === 'album.name' && order > 0"></i>
<i class="fa fa-angle-up" v-show="sortKey === 'album.name' && order < 0"></i> <i class="fa fa-angle-up" v-show="sortKey === 'album.name' && order < 0"></i>
</th> </th>
@ -34,7 +34,7 @@
<tbody> <tbody>
<tr <tr
v-for="item in items v-for="item in items
| caseInsensitiveOrderBy sortKey order subSortKey | caseInsensitiveOrderBy sortKey order
| filterSongBy q | filterSongBy q
| limitBy numOfItems" | limitBy numOfItems"
is="song-item" is="song-item"
@ -83,7 +83,6 @@
lastSelectedRow: null, lastSelectedRow: null,
q: '', // The filter query q: '', // The filter query
sortKey: this.type === 'top-songs' ? 'playCount' : '', sortKey: this.type === 'top-songs' ? 'playCount' : '',
subSortKey: 0,
order: this.type === 'top-songs' ? -1 : 1, order: this.type === 'top-songs' ? -1 : 1,
componentCache: {}, componentCache: {},
}; };
@ -112,13 +111,12 @@
* *
* @param {String} key The sort key. Can be 'title', 'album', 'artist', or 'fmtLength' * @param {String} key The sort key. Can be 'title', 'album', 'artist', or 'fmtLength'
*/ */
sort(key, subSortKey) { sort(key) {
if (this.sortable === false) { if (this.sortable === false) {
return; return;
} }
this.sortKey = key; this.sortKey = key;
this.subSortKey = subSortKey ? subSortKey : 0;
this.order = 0 - this.order; this.order = 0 - this.order;
}, },