orchidjs / tom-select

Tom Select is a lightweight (~16kb gzipped) hybrid of a textbox and select box. Forked from selectize.js to provide a framework agnostic autocomplete widget with native-feeling keyboard navigation. Useful for tagging, contact lists, etc.
https://tom-select.js.org
Apache License 2.0
1.63k stars 121 forks source link

[Bug]: Removing items removes all duplicates in a specific scenario. #762

Open StephenLongville opened 1 month ago

StephenLongville commented 1 month ago

Bug description

removeItem() does a check to remove the option too - if (!self.settings.persist && self.userOptions.hasOwnProperty(value))

However it doesn't take into account a very specific programmatic setup - adding items to options and selections as user created, but not persisting when removed, also allowing duplicates (see Additional context).

In this scenario, I add additional items that are not part of the "normal allowed selection" programmatically, but when removing these additional values, it removes all duplicates, not just the clicked item because of a recursive loop of removeItem() -> removeOption() -> removeItem()...

Expected behavior

Regardless of if an item is user created or not, removing it should remove just that single item and no other items. If the item removed was a duplicate, it's option should stay present as it's still present as a selected item.

Steps to reproduce

JS Fiddle: https://jsfiddle.net/stigmund/wg8po1yt/19/

  1. Remove either of the great tags.
  2. Both tags and the option are removed.

Additional context

I realize I'm adding the option as "created" manually, and then turning off the create option, and this is the root cause of my issue, however there is a valid reason for this.

I am loading content into multiple fields, generated by user maintained formula (producing delimited strings). It is important for us to show all values the user configured in the formulas - valid or not - and alert the user on form submission of the "bad values".

I also need to prevent them manually entering any additional values that are not part of the options list - all while allowing duplicates. This is why create is disabled at the end.

My workaround is to adjust the condition in the description to: if ((!self.settings.persist && self.userOptions.hasOwnProperty(value)) && (!self.settings.duplicates || self.items.indexOf(value) == -1))