yairEO / tagify

🔖 lightweight, efficient Tags input component in Vanilla JS / React / Angular / Vue
https://yaireo.github.io/tagify/
Other
3.52k stars 433 forks source link

Regression with 3.23.0+ with prefill values and whitelist #922

Closed nanawel closed 2 years ago

nanawel commented 3 years ago

Hi there,

💥 Demo Page

https://jsbin.com/zebunog/1/edit

Explanation

With version < 3.23.0 there was no issue with prefilling the <input type="text"> with values and then having them rendered correctly once the dropdown is initialized. More precisely, when the values were IDs only used under the hood but not displayed directly to the user.

Somehow, this behavior broke and I managed to track down the origin to the 3.23.0 release. But the "bug" (if it's one) is still present on versions 4.x.

It seems now necessary to include the value field in the dropdown.searchKeys array, even if in this case it's not desirable because we don't want to filter on hidden IDs, only on visible strings.

Am I missing something?

Please check out the demo page and change the lib version to see the difference. I tried to make it as simple as possible.

yairEO commented 2 years ago

Thanks for telling me, I will investigate

virtualdj commented 2 years ago

It seems now necessary to include the value field in the dropdown.searchKeys array, even if in this case it's not desirable because we don't want to filter on hidden IDs, only on visible strings.

Yeah, in fact if you change:

dropdown: {
  searchKeys: ['name', 'email'],

to:

dropdown: {
  searchKeys: ['value', 'name', 'email'],

it works; the problem seems on this line: https://github.com/yairEO/tagify/blob/23c7e3caf1efb791775e9b073adebc79b1f4f2ab/src/tagify.js#L984 If the value key is not included, the function returns a filteredList with 0-length because it's unable to pick up items from the whitelist.

yairEO commented 2 years ago

The problem is something else entirely. Tagify is dropping the name & email properties of your whitelist objects and therefore the tags do not render as expected, because they lack the expected data.

I will investigate now why this happens


Please don't place your input element (which is Tagified) inside a <label> element, as it messes with the focus of the field

yairEO commented 2 years ago

What you are asking now contradicts with what another user was asking me to do in another issue, which is to remove the automatic matching of values because it really makes sense not show matches for values which are ids, but are not displayed to the user.

For example a list of users, with emails and also ids:

[
    {
        "value": 54,
        "name": "Aric Wolf",
        "email": "aric.wolf89@example.org"
    },
    {
        "value": 89,
        "name": "Carlos Bartell",
        "email": "carlos.54.v@example.org"
    },

So when the user will type 54 or that value will be pre-filled by in the input field, then the matching tags will match unwanted things, since there can be an overlap of the ids and emails containing those ids in their strings... and this is a very simplified example. The situation can be worse.


if you want to match for value only on initialization, but then only allow searching by name or email I suggest doing this:

https://jsbin.com/dofosun/1/edit?html,js,output

💡 The reason for the timeout is because @virtualdj requested me to correct a wrongful chrome behavior regarding history "back"), so there's an internal timeout when tagify first initializes, to allow the browser to fill the input's value so it could be used as tags