Non case-sensitive sorting in dojo dgrid

不问归期 提交于 2019-12-11 04:06:41

问题


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 coerce sort 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!