问题
Is it possible to sort without case-sensitivity?
For instance, sorts by default show up like this:
Awesomeman
adam
beyonce
but, I'd like to sort like:
adam
Awesomeman
beyonce
Is it possible to override the sensitivity easily? From what I can tell the grid inherits from OnDemandGrid
and OnDemandList
, which both inherit from Grid
and List
. For my store, I am using Memory
wrapped in Observable
.
As of now, I'm trying to overwrite _setSort
in List.js
, however that's not working. Anyone out there familiar with these frameworks?
回答1:
There are potentially 2 ways of solving this:
- On the grid end, by handling and canceling the
dgrid-sort
event - On the store end, by extending
query
to coercesort
into doing what you want (preferred)
First, the dgrid-sort
version:
grid.on('dgrid-sort', function (event) {
// Cancel the event to prevent dgrid's default behavior which simply
// passes the sort criterion through to the store and updates the UI
event.preventDefault();
// sort is an array as expected by the store API, but dgrid's UI only sorts one field at a time
var sort = event.sort[0];
grid.set('sort', function (a, b) {
var aValue = a[sort.attribute].toLowerCase();
var bValue = b[sort.attribute].toLowerCase();
if (aValue === bValue) {
return 0;
}
var result = aValue > bValue ? 1 : -1;
return result * (sort.descending ? -1 : 1);
});
// Since we're canceling the event, we need to update the UI ourselves;
// the `true` tells it to also update dgrid's internal representation
// of the sort setting, so that toggling between asc/desc will still work
grid.updateSortArrow(event.sort, true);
});
While this works for handling when the user clicks in header cells, it will not take effect for programmatic set('sort')
calls, or the initial setting of sort
in the object passed to the Grid constructor, which could be problematic.
Since sorting is ultimately a store concern, addressing it on the store end is really the preferable solution. Admittedly dojo/store/Memory
and namely dojo/store/util/SimpleQueryEngine
doesn't make this...well...simple... but one thing to note about SimpleQueryEngine
is that if you pass a function via queryOptions.sort
rather than an array, it will be applied verbatim as the sort function to use.
This means we can take the incoming sort
array that dgrid will set, write our own version of SimpleQueryEngine
's default sort function while also accounting for case-insensitivity, and store that in queryOptions.sort
for the inherited call:
var CIMemory = declare(Memory, {
query: function (query, queryOptions) {
var sort = queryOptions && queryOptions.sort;
if (sort) {
// Replace sort array with a function equivalent that performs
// case-insensitive sorting
queryOptions.sort = function (a, b) {
for (var i = 0; i < sort.length; i++) {
var aValue = a[sort[i].attribute].toLowerCase();
var bValue = b[sort[i].attribute].toLowerCase();
if (aValue !== bValue) {
var result = aValue > bValue ? 1 : -1;
return result * (sort[i].descending ? -1 : 1);
}
}
return 0;
}
}
return this.inherited(arguments);
}
});
Using this in place of dojo/store/Memory
will cause all sorts to be case-insensitive.
Note that I took a couple of shortcuts over SimpleQueryEngine
's sort
function (checking for null/undefined and coercing values to primitives). Alter the sort function as necessary if you need to worry about either of those things.
回答2:
Okay, for lack of a better solution, I found that I had to create a custom version of dojo's SimpleQueryEngine
, adding .toLowerCase()
on both of the values here. The reason it couldn't be simply changed was because it happens inside of an internal function (inside of another function) so it was easier to make another version entirely.
Then, when creating Memory
, passing in the query engine like so:
new Memory({ queryEngine : customEngine });
and it seems to work. If there's a cleaner solution please share bc I hate this one :)
来源:https://stackoverflow.com/questions/26783489/non-case-sensitive-sorting-in-dojo-dgrid