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

[Autocomplete] allowDuplicate option #18755

Closed
1 task done
thealjey opened this issue Dec 9, 2019 · 12 comments
Closed
1 task done

[Autocomplete] allowDuplicate option #18755

thealjey opened this issue Dec 9, 2019 · 12 comments
Labels
component: autocomplete This is the name of the generic UI component, not the React module! discussion

Comments

@thealjey
Copy link

thealjey commented Dec 9, 2019

I want to be able to add the same chip more than once.

  • I have searched the issues of this repository and believe that this is not a duplicate.

Summary 💡

By setting the allowDuplicate prop to true the items in the dropdown list will not be highlighted and will always add a new item to the value array.

Examples 🌈

<Autocomplete
  multiple
  allowDuplicate
  value={["one", "one", "two"]}
  {...rest}
/>

Motivation 🔦

I am making a GUI builder application for react components.
Items in the Autocomplete describe react children.
I need to be able to add the same child more than once.

@oliviertassinari
Copy link
Member

@thealjey Could you provide more detail on your use case? What prevents you from using two different objects with the same representation?

@oliviertassinari oliviertassinari added component: autocomplete This is the name of the generic UI component, not the React module! waiting for user information labels Dec 9, 2019
@thealjey
Copy link
Author

thealjey commented Dec 9, 2019

When you select an item from the drop-down menu, it becomes highlighted, if you click on it again it gets removed instead of being added again as a duplicate (which is what I want).
The component dataset does not contain duplicated items, every item is represented only once in the drop-down.
I need to be able to add as many of the same item to the "value" array as I want by selecting items in the menu.

@oliviertassinari
Copy link
Member

What do you think of using the filterSelectedOptions prop with a new object anytime you add one?

@thealjey
Copy link
Author

thealjey commented Dec 9, 2019

What do you mean?
That prop only removes selected items from the menu, making them unavailable.
Do you suggest I immediately "unhide" it by adding a duplicate to the "options"?
I would then have to remove the duplicate when the original is shown again in the list somehow.
That sounds like such a hack.
I guess it might work, it's just not a very elegant solution.
Maybe I should search for a different component.

@oliviertassinari
Copy link
Member

oliviertassinari commented Dec 9, 2019

Yeap, it wouldn't be a straightforward approach. I haven't benchmark how the other solutions solve this problem. If you could look at this, it would be awesome.

@jzaynal
Copy link

jzaynal commented Jun 18, 2021

@thealjey this issue/question is really old but still wanted to share my piece in case it helps anyone. So I unintentionally landed in the situation you are after and that was a problem for me rather than a desired effect, but I suppose you can benefit from it.

This component checks for 'referential' equality when determining what is selected and what is not. So if you were to make sure your options are always generated on the fly rather than a constant list, and also make sure the option items are objects and not primitives, you can achieve what you want. For example:

<Autocomplete
  multiple
  value={[{ id: 1, value: "One"}, {id: 2, value: "Two"}, {id: 3, value: "Three"}]}
  getOptionLabel={(item) => item.value}
  {...rest}
/>

you will get what you want. This is because when Autocomplete checks whether an item selected, it will always get false as {id: 1, value: "One"} !== {id: 1, value: "One"} if they aren't stored in a variable. Their references are different if they're new objects at every render loop.

I hope this helps someone.

@ezescigo
Copy link

@thealjey this issue/question is really old but still wanted to share my piece in case it helps anyone. So I unintentionally landed in the situation you are after and that was a problem for me rather than a desired effect, but I suppose you can benefit from it.

This component checks for 'referential' equality when determining what is selected and what is not. So if you were to make sure your options are always generated on the fly rather than a constant list, and also make sure the option items are objects and not primitives, you can achieve what you want. For example:

<Autocomplete
  multiple
  value={[{ id: 1, value: "One"}, {id: 2, value: "Two"}, {id: 3, value: "Three"}]}
  getOptionLabel={(item) => item.value}
  {...rest}
/>

you will get what you want. This is because when Autocomplete checks whether an item selected, it will always get false as {id: 1, value: "One"} !== {id: 1, value: "One"} if they aren't stored in a variable. Their references are different if they're new objects at every render loop.

I hope this helps someone.

Hi @jzaynal ! I'm trying to implement exactly this case (autocomplete with multiple chips/options that can be selected more than once), but I don't see how to use your hack to do it.

What I am trying to accomplish is an autocomplete input to help the user "build" a formula, Excel alike. So, for example, the user start writing, the input gives him some options to select (like products), and operands (like +-*), and the user can play around building a formula, selecting Products and operands to form something like "Product1+Product2+10". That's why I need to allow duplicate options.

@jakeyizle
Copy link

I solved this by setting:

isOptionEqualToValue={(option, value) => false}

the value is still there in the onChange event, though you do get bunch of console warnings about it.

@elarouche
Copy link

Just wanted to add to the solution @jakeyizle mentioned. For the people using mui v4, you will have to use getOptionSelected instead of isOptionEqualToValue. Hope this helps someone save some time.

@BrandonSigil
Copy link

Thanks, @elarouche and @jakeyizle. That worked great for me, I also didn't need to use option and value, it worked as intended with isOptionEqualToValue={() => false}

@plostvik
Copy link

plostvik commented Feb 10, 2023

I solved this by setting:

isOptionEqualToValue={(option, value) => false}

the value is still there in the onChange event, though you do get bunch of console warnings about it.

Thanks @jakeyizle!
Is there any possible way to disable warnings in console?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: autocomplete This is the name of the generic UI component, not the React module! discussion
Projects
None yet
Development

No branches or pull requests

9 participants