this.col = Backbone.Collection.extend({
model: M,
comparator: function(item) {
return item.get("level");
}
});
This above code sorts items by level. I want to sort by level, then by title. Can I do that? Thanks.
this.col = Backbone.Collection.extend({
model: M,
comparator: function(item) {
return item.get("level");
}
});
This above code sorts items by level. I want to sort by level, then by title. Can I do that? Thanks.
String concatenation works fine when sorting multiple fields in ascending order, but it didn't work for me because 1) I had to support asc/desc per field and 2) certain fields were number field (i.e., I want 10 to come after 2 if it is ascending). So, below was a comparator function I used and worked OK for my needs. It assumes the backbone collection has a variable assigned with 'sortConfig', which is an array of JSON objects with field name and sort order direction. For example,
With the JSON object above assigned as 'sortConfig' to the collection, the function below will make Backbone sort by strField in ascending order first, then sort by numField in descending order, etc. If no sort order is specified, it sorts ascending by default.
"inspired" in hyong answer.
This also allows you to change the data before compare it, valueTransforms is an object, if there is an attribute in that object that has a function, it will be used.
Returning an array is not consistent if you need to sort descending and some ascending...
I created a small set of functions which can be used to return the relevant comparison integer back to Backbone Comparator function:
backbone-collection-multisort
The main thing is that Backbone sorts by a single relative value of one item to another. So it's not directly possible to sort twice in a single collection but I'd try this.
What this will do is return a string of like "1Cool", "1title", "2newTitle" ... Javascript should sort the strings by the numerical character first then each character afterwards. But this will only work as long as your levels have the same amount of digits. IE "001title" vs "200title". The main idea though is that you need to produce two comparable objects, line a number or string, that can be compared to each other based on one criteria.
Other solution would be to use underscore to "groupby" your level then use "sortby" to manually sort each level group then manually replace the underlying collection with this newly created array. You can probably setup a function to do this whenever the collection "changes".
@amchang87's answer definitely works, but another that I found worked is simply returning an array of the sortable fields:
I haven't tested this in multiple browsers yet as I think it relies on JS' behavior in sort order for arrays (based on their contents). It definitely works in WebKit.