Custom sort functions for ICollectionView/FlexGrid

Posted by: qualton on 14 September 2017, 11:15 am EST

    • Post Options:
    • Link

    Posted 14 September 2017, 11:15 am EST

    Is there a standard way to implement custom/manual sorting based on a sort function rather than using SortDescriptions? It seems that SortDescriptions are quite limited to what would be considered the ‘natural’ sort order of single fields.

    There are a few approaches I see but I’d rather not use a non-optimal solution:

    1. CollectionView has a prototype method _compareItems (meant to be private) which could be forcibly overridden.
    2. Alter the source data structures to be more complex so that they contain both the value and the ‘sortValue’ and then interrupt the FlexGrid request to sort to calculate and use this metadata when sorting
    3. There is an IComparer interface, but it does not seem to be used. Would require forking to make sort uniformly use IComparer for SortDescriptions and then create a new implementer of IComparer for user-defined sort functions. This seems like the ‘proper’ solution and may be the path you all initially set to follow - did you plan on implementing it like this soon?
  • Posted 14 September 2017, 11:15 am EST

    Hello there

    In version 35 we added a CollectionView.sortConverter property. It specifies a function that can be used to customize the sorting behavior of the CollectionView.

    The function takes as parameters the SortDescription, the item being sorted, and the proposed value to be used in the comparison, and returns a new value to be used instead of the original.

    This fiddle demonstrates:

    http://jsfiddle.net/Wijmo5/L3k8fct4/

    If you click the header of the “Action” column, you will notice that the values get sorted by weight rather than by id or display value. This is done by specifying the following sortConverter:

    [js]// use sortConverter to sort actions by weight

    var sortMap = new wijmo.grid.DataMap(map, ‘key’, ‘weight’);

    view.sortConverter = function (sd, item, value) {

    if (sd.property == ‘action’) {

    value = sortMap.getDisplayValue(value);

    }

    return value;

    }[/js]

    I hope this solution works for you, and I’m interested in any feedback you may have.

    Thanks.

  • Posted 14 September 2017, 11:15 am EST

    You can download build 39 from the site, it’s already posted.

  • Posted 14 September 2017, 11:15 am EST

    • 4 -

    In using DataMap in context of sortConverter, the naming of ‘getDisplayValue’ is odd since the DataMap is not always a value->display relationship anymore. Instead it would make more sense for DataMap to have a more generic API like ‘getMappedValue’

  • Posted 14 September 2017, 11:15 am EST

    Hello

    Whoa, that was a long post :wink: Let’s see, item by item:

    1. We already have something like a groupConverter. The PropertyGroupDescription class has a constructor that takes a ‘classifier’ function. That functions takes an item and returns the name of the group the item belongs to. For example:

    [js]var groupDesc = new wijmo.collections.PropertyGroupDescription(groupName, function (item, prop) {

    return

    item.amount >= 5000 ? ‘More than 5,000’ :

    item.amount >= 500 ? ‘500 to 5,000’ :

    ‘less than 500’;

    });[/js]

    This example is from our FlexGridIntro sample.

    1. I understand your comments about the sortConverter. This was added specifically to support scenarios like DataMap, where you store a key and display something else. And you want the sort to reflect the displayed value rather than the internal value. But I understand there might be situations where you would like to override the comparison function rather than simply convert the values. Both scenarios seem useful, we may add this second option in the future.

    2. The sortConverter is missing from the documentation because someone (probably me) used “/*” instead of “/**” in the source code. Wonders of automated documentation ;-). This has been fixed and the next version of the docs will include it. Note however that this was added to the “CollectionView” class, and not to the “ICollectionView” interface. We want to keep ICollectionView as close as possible to the original MS spec. Of course changing interfaces is never a good idea.

    3. I agree with you about DataMap in the context of converting sort values. The “DisplayValue” looks strange, in this case it should be a “SortValue” or something like that. But that’s just a sample, not really what DataMap was designed to do. In fact, I almost used a switch statement in the sample for that precise reason. But I ended up leaving it there mostly to show you can do it if you want to.

    Thanks a lot for your insightful comments and for pointing out the issue with the documentation.

  • Posted 14 September 2017, 11:15 am EST

    1. PropertyGroupDescription - perfect

    2. “Both scenarios seem useful, we may add this second option in the future” - glad to hear it.

    3. Ahh… the alignment to .NET was not something in the forefront of my mind… that definitely helps to understand why some things are the way they are. I’ll definitely look among .NET resources for how different implementations of certain things might be achieved.

    Thanks again for your help.

  • Posted 14 September 2017, 11:15 am EST

    It took a while, but we finally added this new feature to the CollectionView class in build 167+. It is documented as follows:

    CollectionView.sortComparer

    Gets or sets a function used to compare values when sorting.

    If provided, the sort comparer function should take as parameters two values of any type, and should return -1, 0, or +1 to indicate whether the first value is smaller than, equal to, or greater than the second. If the sort comparer returns null, the standard built-in comparer is used.

    This sortComparer property allows you to use custom comparison algorithms that in some cases result in sorting sequences that are more consistent with user’s expectations than plain string comparisons.

    For example, see Dave Koele’s Alphanum algorithm. It breaks up strings into chunks composed of strings or numbers, then sorts number chunks in value order and string chunks in ASCII order. Dave calls the result a “natural sorting order”.

    The example below shows a typical use for the sortComparer property:

    // create a CollectionView with a custom sort comparer
    var dataCustomSort = new wijmo.collections.CollectionView(data, {
      sortComparer: function (a, b) {
        return wijmo.isString(a) && wijmo.isString(b)
          ? alphanum(a, b) // custom comparer used for strings
          : null; // use default comparer used for everything else
      }
    });
    

    I have included a screenshot that shows the difference between the standard and “natural” sort orders.

    Thank you for the suggestion and patience.

  • Posted 14 September 2017, 11:15 am EST

    Hi,

    I’m working on flexgrid paging with backend sorting.

    however, my issue is after doing back end sorting, I’m not able to prevent the client side sorting from kicking in which messes up my custom sorting logic from the back end.

    Any ideas?

    I’ve already added a handler to flexgrid.sortedColumn… to set e.cancel=true. but still client side sorting keeps on happening for that page.

  • Posted 14 September 2017, 11:15 am EST

    Hello,

    You can set allowSorting to false for disable sorting in FlexGrid. This property prevents to sort FlexGrid on column header click. Use following code to disable sorting in FlexGrid:

    
    <wj-flex-grid items-source="data" allow-sorting="false" >
    </wj-flex-grid>
    

    Hope it helps.

    Thanks,

    Manish Kumar Gupta

  • Posted 15 October 2019, 11:14 am EST - Updated 3 October 2022, 7:00 pm EST

    We just tracked down an issue where our multi-column sorting was no longer working after upgrading to a more recent version of Wijmo. In our grids, we allow the user to sort by more than one column by holding down the Shift key, and we also provide custom sorting that is very similar to what @Bernard suggested above. It turns out that custom sorting breaks multi-sorting. I’ve demonstrated this issue using your ‘Multi-column sorting’ demo, as shown in the attached screenshot. This was working for us in an older version of Wijmo. Can you provide a workaround, or let us know when a fix might be available?

    Thanks,

    Terry

  • Posted 18 October 2019, 3:39 am EST

    Hi Terry,

    We are extremely sorry for the delayed response on this issue.

    We have also created this issue in the SupportOne portal which can be logged in using the same credential used in Grapecity WebSite.

    http://supportone.componentone.com/home/casedetail/402253

    In case it does not allow login using the credential, used current email to get the forgot password link.

    We are able to replicate the issue at our end and we have forwarded this issue to the concerned team for further investigation. Also, we have tried with older builds e.g 2018v1 onwards but the sortComparer method does not trigger for the current clicked column.

    Please let us know the build version in which it was working fine.

    Here is the sample for your reference:

    https://stackblitz.com/edit/angular-5vg9r9?file=src/app/app.component.ts

    Regards,

    Manish Gupta

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels