Instantsearch.js: [refinementList]: sortBy does not correctly sort UTF8 chars

Created on 4 Oct 2016  路  6Comments  路  Source: algolia/instantsearch.js

image

When using the the name sorting (or keeping the default one), facets starting with an accented character are put at the end.

Instead of the default sorting on strings, we could use localeCompare. It needs to know the user locale, but this is already an information we can pass to the main instance (to specify how to format numbers), so we could re-use it here as well.

It will require a change in the Helper as well I guess.

Needs Investigation

Most helpful comment

Seems there is no way to pass a custom sort function to sortBy. What can be done though, is use a normalized string through _.deburr.

Something like

var facets = _.sortBy(facetValues, (facet) => { return _.deburr(facet.name) });

This will convert 脡ric to Eric before applying the sort. Not perfect, but closer to what we want to achieve here.

All 6 comments

The helper uses lodash sortBy I believe. Do you know how to do it with lodash? Searched a bit without luck

Seems there is no way to pass a custom sort function to sortBy. What can be done though, is use a normalized string through _.deburr.

Something like

var facets = _.sortBy(facetValues, (facet) => { return _.deburr(facet.name) });

This will convert 脡ric to Eric before applying the sort. Not perfect, but closer to what we want to achieve here.

Ok so this looks like a helper improvement then. I wonder if we could make it the new default without breaking anything that people are expecting. But clearly your example shows that today at least for french names, doesn't make sense.

@pixelastic, @vvo is right, that's probably something we can look at, but on the Helper side of things. Can you fill in your issue there?

Done.

Thanks :)

You can use the sortBy argument to pass a regular JS sort function to override the sorting behaviour.

search.addWidget(
  instantsearch.widgets.refinementList({
    container: '#brand-list',
    attributeName: 'brand',
    sortBy({ name: a }, { name: b }) {
      return a.localeCompare(b);
    },
  })
);

https://codesandbox.io/s/713rl3zwzq

Sorting can also be done in transformItems if you so prefer.

Was this page helpful?
0 / 5 - 0 ratings