Vue-multiselect: Ignore accents/diacritics on search query string

Created on 17 May 2019  路  9Comments  路  Source: shentao/vue-multiselect

This is more a suggestion for enhancement, either as an added argument or possibly in the docs as a custom expansion.

The current search query is exact match but many common searches (including the others on my website) drop accents/diacritics before performing the comparison. Basically I implement this:

const stringIncludes = function (valueStr, search) {
        // https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
        const value = valueStr.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
        return value.toUpperCase().includes(search)
      }

Is this is a fairly easy addition? I had hoped to avoid having to write my own @query-change hook method and update the options etc.

Most helpful comment

Hi @laurens94 & @attack68

If you do not wait until the merge, you can use this code

<multiselect
  :ref="`multiselect-${index}`"
  @search-change="ignoreAccent(`multiselect-${index}`)"
>
</multiselect>
ignoreAccent(elem) {
  this.$refs[elem][0].search = this.$refs[elem][0].search.normalize('NFD').replace(/[\u0300-\u036f]/g, "")
}

That clean key search contains on the Multiselect component 馃憤

All 9 comments

I believe it could be easily implemented by changing the includes function in /src/multiselectMixin.js to:

function includes (str, query) {
  if (str === undefined) str = 'undefined'
  if (str === null) str = 'null'
  if (str === false) str = 'false'
  const text = str.toString().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
  return text.indexOf(query.trim().normalize('NFD').replace(/[\u0300-\u036f]/g, '')) !== -1
}

In this way, both the search query and the string are 'converted' to normal characters when comparing.

But it should definitely be optionally.

Hi @laurens94 & @attack68

If you do not wait until the merge, you can use this code

<multiselect
  :ref="`multiselect-${index}`"
  @search-change="ignoreAccent(`multiselect-${index}`)"
>
</multiselect>
ignoreAccent(elem) {
  this.$refs[elem][0].search = this.$refs[elem][0].search.normalize('NFD').replace(/[\u0300-\u036f]/g, "")
}

That clean key search contains on the Multiselect component 馃憤

As you stated there is open pull request that predates my issue #860 (just linking it)

Any updates regarding this issue?

There are two directions here which are important:

1) Database values contain EUR characters but you wish to search using Non-EUR characters.

E.g. Database has "Gr盲s枚" and you wish this to be found only by typing "Graso".

2) The selected search string is typed with EUR characters but you wish to search for both EUR and Non-EUR character strings.

E.g. You type "Gr盲s枚" and you should return the database values "Graso" "Gr盲so" "Gras枚" or "Gr盲s枚" (as well as many other variants of characters)

I would posit that 1) is much more common - as a search facility (and for non-europeans) you often type the common letters and hope to find the relevant results even if they are distorted by diacritics. Although 2) might also be useful in some cases.

The problem with the above solution provided by @joffreyBerrier is that it does neither 1) nor 2). In fact it actually causes an error as follows:

  • Suppose the Database value is "Gr盲s枚".
  • When you search for "Gr盲s枚" the code removes the diacritics and the search actually becomes "Graso".
  • But we still have the fundamental problem that searches are exact match so this search does not return any results even though what the user originally typed was an exact match for what he wanted.

Hi @laurens94 & @attack68

If you do not wait until the merge, you can use this code

<multiselect
  :ref="`multiselect-${index}`"
  @search-change="ignoreAccent(`multiselect-${index}`)"
>
</multiselect>
ignoreAccent(elem) {
  this.$refs[elem][0].search = this.$refs[elem][0].search.normalize('NFD').replace(/[\u0300-\u036f]/g, "")
}

That clean key search contains on the Multiselect component 馃憤

Hi. i will try . but it's not work.
" [Vue warn]: Property or method "index" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the prope"
https://imgur.com/a/20b1BUd

@thanhrossi are you trying to remove diacritics from your search or from the searched items ?
@attack68 is right, @joffreyBerrier's piece of code "flattens" the search part.
Example: you typed "ch枚u茅tte", it'll search "chouette", but if you have an item containing "ch贸霉ette" it'll not be matched.
I think people usually need the inverse.

However @attack68, as a European user, I almost never type the accents in my searches expecting accented characters to be matched so I guess your 2 cases are important and would deserve an option for each.

My implementation here https://github.com/shentao/vue-multiselect/issues/281#issuecomment-597718858
(Diacritics/case insensitive search)

The solution proposed by @Glideh is the recommended one. Thank you :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stefanheimann picture stefanheimann  路  4Comments

andreasvirkus picture andreasvirkus  路  3Comments

PrimozRome picture PrimozRome  路  3Comments

bushcode picture bushcode  路  3Comments

katranci picture katranci  路  3Comments