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.
@amchang87's answer definitely works, but another that I found worked is simply returning an array of the sortable fields:
this.col = Backbone.Collection.extend({ model: M, comparator: function(item) { return [item.get("level"), item.get("title")] } });
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.
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,
{ "sort" : [ { "field": "strField", "order": "asc" }, { "field": "numField", "order": "desc" }, ... ] }
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.
multiFieldComparator: function(one, another) { // 'this' here is Backbone Collection if (this.sortConfig) { for (var i = 0; i < this.sortConfig.length; i++) { if (one.get(this.sortConfig[i].field) > another.get(this.sortConfig[i].field)) { return ("desc" != this.sortConfig[i].order) ? 1 : -1; } else if (one.get(this.sortConfig[i].field) == another.get(this.sortConfig[i].field)) { // do nothing but let the loop move further for next layer comparison } else { return ("desc" != this.sortConfig[i].order) ? -1 : 1; } } } // if we exited out of loop without prematurely returning, the 2 items being // compared are identical in terms of sortConfig, so return 0 // Or, if it didn't get into the if block due to no 'sortConfig', return 0 // and let the original order not change. return 0; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With