Describe the bug
Clearing the choices will remove all ! Placeholder too.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Have a choice to keep or not the placeholder
Any way you can clear it with .setChoiceByValue('') without losing placeholder
@ch3rn1k You mean, .setChoiceByValue(‘’) before .clearChoices() ?
I'll try what you said, in fact it works, but I understand I have miss something to explain.
I use .setChoices(data,'id', 'fullName', true) and this is this method who clear all, due to the 4th argument.
At leat I my trick is this for the moment:
const placeholder = Choice.setChoiceByValue('').getValue()
// retrieve data from Ajax
Choice.clearChoices().setChoices(ajaxData, 'id', 'fullName', true).setChoices([placeholder]).setChoiceByValue('')
Any way you can clear it with
.setChoiceByValue('')without losing placeholder
although this works what would happen of a choice has a value of ''
@agar23 this will be useless because not really usable on a real form.
@kl3sk fair enough, I was thinking from more of a lib perspective. As a developer I expect the clearChoices() method to work correctly out the box and not clear my placeholder.
I should not have to use .setChoiceByValue('') as a "workaround" to properly clear my choices.
You make a fair point, its probably not very practical to have an option with a value of "" on a real world form.
In a symfony world, placeholder are set with a blank '' value.
@jshjohnson said on the doc, the recommended way of adding a placeholder is as follows. And I totally agree with it.
As a lib perspective, everything could be considered as anything.
So it is still available, but .clearChoices should clear choices an empty value is not a choice.
but a choice can have an empty value ("") as a value.....
Yes this is possible, but unless reading the textValue it reamins useless ^^.
Anyway, without any jokes a choice should be done for the placeholder 😉
Hard fix:
selectElement.addEventListener('removeItem', function () {
if (selectElement.length === 0) {
choicesInstance
.setChoices([{value: '', label: 'None', placeholder: true}], 'value', 'label', true)
.setChoiceByValue('');
}
});
@bupy7 this doesn’t keep the original placeholder.
@kl3sk if you add placeholder programmatically (I recommend that) is no matter.
That’s I did in a previous comment.
@kl3sk, not the same.
Your solution has many side effects:
My solution solve the problem in two step:
I want to keep the original placeholder, generated by (in my case) Symfony formbuilder.
In order to keep it, I have to select it save it and reinject it.
This workaround worked for me (when getting data using ajax). It preserved the placeholder, without needing to do setChoiceByValue('')
if (select.value) choices.clearStore();
choices.setChoices(async () => {
const data = await fetch('/states');
return data.json();
});
I combined some of the previous mentioned workarounds, but rather used Array.prototype.find on the config-Object rather than setChoiceByValue('').getValue() for storing the original placeholder, and came up with this here:
newOptions.push(choicesInstance.config.choices.find(choice => choice.placeholder));
choicesInstance.setChoices(newOptions, 'value', 'label', true)
.setChoiceByValue('');
Very intersting way @FelixWienberg , I use your solution instead of mine.
At least @jshjohnson should implement something for this.
Most helpful comment
Hard fix: