Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clearChoice remove placeholder too #803

Closed
kl3sk opened this issue Jan 8, 2020 · 19 comments · Fixed by #1166
Closed

clearChoice remove placeholder too #803

kl3sk opened this issue Jan 8, 2020 · 19 comments · Fixed by #1166
Labels

Comments

@kl3sk
Copy link

kl3sk commented Jan 8, 2020

Describe the bug
Clearing the choices will remove all ! Placeholder too.

To Reproduce
Steps to reproduce the behavior:

  1. Create a Choice from an select with a placeholder (option with value="")
  2. programmatically Choice.clearChoices()
  3. All is removed

Expected behavior
Have a choice to keep or not the placeholder

@kl3sk kl3sk added the bug label Jan 8, 2020
@ch3rn1k
Copy link

ch3rn1k commented Jan 9, 2020

Any way you can clear it with .setChoiceByValue('') without losing placeholder

@kl3sk
Copy link
Author

kl3sk commented Jan 9, 2020

@ch3rn1k You mean, .setChoiceByValue(‘’) before .clearChoices() ?

@kl3sk
Copy link
Author

kl3sk commented Jan 9, 2020

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('')

@alfonsoar
Copy link

Any way you can clear it with .setChoiceByValue('') without losing placeholder

although this works what would happen of a choice has a value of ''

@kl3sk
Copy link
Author

kl3sk commented Jan 12, 2020

@agar23 this will be useless because not really usable on a real form.

@alfonsoar
Copy link

alfonsoar commented Jan 13, 2020

@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.

@kl3sk
Copy link
Author

kl3sk commented Jan 14, 2020

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.

@alfonsoar
Copy link

but a choice can have an empty value ("") as a value.....

@kl3sk
Copy link
Author

kl3sk commented Jan 15, 2020

Yes this is possible, but unless reading the textValue it reamins useless ^^.

Anyway, without any jokes a choice should be done for the placeholder 😉

@bupy7
Copy link

bupy7 commented Jan 25, 2020

Hard fix:

selectElement.addEventListener('removeItem', function () {
    if (selectElement.length === 0) {
        choicesInstance
            .setChoices([{value: '', label: 'None', placeholder: true}], 'value', 'label', true)
            .setChoiceByValue('');
    }
});

@kl3sk
Copy link
Author

kl3sk commented Jan 25, 2020

@bupy7 this doesn’t keep the original placeholder.

@bupy7
Copy link

bupy7 commented Jan 26, 2020

@kl3sk if you add placeholder programmatically (I recommend that) is no matter.

@kl3sk
Copy link
Author

kl3sk commented Jan 26, 2020

That’s I did in a previous comment.

@bupy7
Copy link

bupy7 commented Jan 26, 2020

@kl3sk, not the same.

Your solution has many side effects:

  1. setChoiceByValue('')
  2. clearChoices()
  3. setChoices()
  4. setChoices() again
  5. setChoiceByValue() again

My solution solve the problem in two step:

  1. setChoices()
  2. setChoiceByValue()

@kl3sk
Copy link
Author

kl3sk commented Jan 27, 2020

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.

@yogeshjain999
Copy link

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();
});

@FelixWienberg
Copy link

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('');

@kl3sk
Copy link
Author

kl3sk commented Jun 23, 2020

Very intersting way @FelixWienberg , I use your solution instead of mine.

At least @jshjohnson should implement something for this.

@naiemofficial
Copy link

To avoid repetition of the same code, I modified the solution provided by @FelixWienberg

if(typeof Choices !== 'undefined'){
    Choices.prototype.clearOptions = function(){
        const placeholder = this.config.choices?.find(choice => choice.placeholder);
        if(placeholder){
            this.setChoices([placeholder], 'value', 'label', true).setChoiceByValue('');
        } else {
            this.clearChoices();
        }
    };
}
choicesInstance.clearOptions();

@Xon Xon linked a pull request Aug 6, 2024 that will close this issue
9 tasks
@Xon Xon closed this as completed Aug 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants