Choices icon indicating copy to clipboard operation
Choices copied to clipboard

setChoiceByValue not working for choices loaded with AJAX

Open vitobotta opened this issue 4 years ago • 4 comments

Hi! I am using Choices as autocomplete, and when the user types some text in the search input the choices are loaded with an AJAX request (using the "search" event).

I use setChoices with the json data. The choices appear as expected in the DropDown, but setChoiceByValue with one of the values added doesn't actually work. It just returns the instance of Choices without selecting the choice. The same thing with a select that already had options before initialising with Choices, works fine when using setChoiceByValue.

So it seems that there might be a problem with setChoiceByValue and items added with setChoices. Is there any workaround?

Thanks!

To Reproduce Steps to reproduce the behavior:

  • load choices with AJAX
  • try setChoiceByValue with one of the values loaded

Expected behavior I would expect the choice to be selected

Desktop (please complete the following information):

  • MacOS, Chrome/Brave

vitobotta avatar Feb 26 '20 14:02 vitobotta

I may have found the problem: the _findAndSelectChoiceByValue function

    const foundChoice = choices.find(choice =>
      this.config.valueComparer(choice.value, value),
    );

config.choices is empty if I use setChoices while it has the choices if the select already has options when initialised with Choices.js. As a workaround I am adding the choices as per below instead of using setChoices:

                      data.forEach((item) => {
                        const choice = {
                          value: String(item.value),
                          label: item.label,
                          isSelected: false,
                          isDisabled: false,
                          groupId: 1,
                          customProperties: {},
                          placeholder: item.label
                        }

                        choices._addChoice(choice)
                        choices.config.choices.push(choice)
                      })

vitobotta avatar Feb 26 '20 15:02 vitobotta

If anyone else lands here because you're not able to use setChoiceByValue successfully, do also note that when valueComparer searches for IDs (see @vitobotta comment above) it uses a === comparison, not a ==. If, like me, you are using numeric IDs as your value, the choices library interprets them as strings, and setChoiceByValue(someInteger) will politely ignore you. Instead, you need setChoiceByValue('someInteger').

(This is not a bad thing, once you know it - using === means that 0 won't match [empty string] and so on. It's just something that caught me out.)

almcnicoll avatar Jul 27 '20 22:07 almcnicoll

If you're simply trying to preselect from AJAX source, but do not need to programatically select afterwards, you can simply set the json response to selected => true in your AJAX loaded Json file. I have create a php file which encodes the responses as json for choices.js, and with the AJAX call I simply decide if the particular choice should be selected. Hope this helps anybody.

mectorfector avatar Feb 13 '21 18:02 mectorfector

If anyone else lands here because you're not able to use setChoiceByValue successfully, do also note that when valueComparer searches for IDs (see @vitobotta comment above) it uses a === comparison, not a ==. If, like me, you are using numeric IDs as your value, the choices library interprets them as strings, and setChoiceByValue(someInteger) will politely ignore you. Instead, you need setChoiceByValue('someInteger').

(This is not a bad thing, once you know it - using === means that 0 won't match [empty string] and so on. It's just something that caught me out.)

I just want to say thank you was having issues with this as well in a laravel project with numeric ID's

wesleyfraser avatar Jun 07 '23 01:06 wesleyfraser