cosmic
cosmic

Reputation: 73

Can not deselect from MUI select Component. What's the right way?

I am trying to implement deselect option in material UI select component.My question is 'is there any prop that automatically deselect the selected object after clicking the selected Object?'

my code snippet:

<FormControl>
  <InputLabel>{t('typeUsers')}</InputLabel>
  <Select
    label={t('typeUsers')}
    value={filterUser}
    onChange={(e) => { setFilterUser(e.target.value); }}
  >
   {Object.values(users).filter((user) => (user.administrator === false)).map((user) => (<MenuItem key={user.id} value={user.id}>{user.name}</MenuItem>))}
 </Select>
</FormControl>

OR how can I add an additional MenuItem that sets selected Item deslected?

Upvotes: 2

Views: 5867

Answers (6)

Kaveri
Kaveri

Reputation: 1

Like others have already suggested to use onClick handler on menu item, I have resolved this issue by using the dataset property of the target object, as below:

<MenuItem
 key={someValue}
 value={someValue}
 onClick={(event) => {
 if (
    event.target.dataset.value === someValue
    ) {
       // reset someValue, eg, 
       setSomeValue('');
      }
 }}
 >
 {someValue}
</MenuItem>

Upvotes: 0

Selahadin Jemal
Selahadin Jemal

Reputation: 41

I've ran to the same issue recently, and I have found the solution is rather easy. my solution is to add an additional MenuItem inside the select and simply include a "None" or "Clear" option and give it an empty string in the value. it looks like this using your code:-

<FormControl>
  <InputLabel>{t('typeUsers')}</InputLabel>
  <Select
    label={t('typeUsers')}
    value={filterUser}
    onChange={(e) => { setFilterUser(e.target.value); }}
  >
    {/* Option for clearing the selection */}
    <MenuItem value="">
      <em>None</em>
    </MenuItem>

    {/* Other user options */}
    {Object.values(users).filter((user) => (user.administrator === false)).map((user) => (
      <MenuItem key={user.id} value={user.id}>
        {user.name}
      </MenuItem>
    ))}
  </Select>
</FormControl>

When this option is selected, the value will be an empty string i.e nothing selected! Hope it helps.

Upvotes: 1

Abensoukehal
Abensoukehal

Reputation: 21

You can use conditional rendering on your "Clear selection" MenuItem with an empty value.

{filterUser && (<MenuItem value=""><em>Clear selection</em></MenuItem>)}

This way, "clear selection" will be shown only if you have selected any option. Here's your fixed code:

<FormControl>
  <InputLabel>{t("typeUsers")}</InputLabel>
  <Select
    label={t("typeUsers")}
    value={filterUser}
    onChange={(e) => {
      setFilterUser(e.target.value);
    }}>
    {filterUser && (
      <MenuItem value="">
        <em>Clear selection</em>
      </MenuItem>
    )}
    {Object.values(users)
      .filter((user) => user.administrator === false)
      .map((user) => (
        <MenuItem key={user.id} value={user.id}>
          {user.name}
        </MenuItem>
      ))}
  </Select>
</FormControl>

Upvotes: 0

maja
maja

Reputation: 799

It's a bit of an hack, but it worked for me: I assigned an additional onClick handler to the MenuItem element, then listened for clickEvent.target.selected === true to check if the same item has been clicked while active.

If using typescript the handler could be something like this:

onClick={ (clickEvent) => {
  if ((clickEvent.target as HTMLOptionElement).selected === true) {
    // do my stateful reset
  }
} }

Upvotes: 1

dlwiest
dlwiest

Reputation: 655

Unfortunately, the onChange event doesn't fire if the user selects an item that's currently selected, as you found. I got around this by adding an onClick handler to the menu item and comparing its value to the current selection value, then setting the selection to undefined if they match.

Upvotes: 0

Anatol Zakrividoroga
Anatol Zakrividoroga

Reputation: 4518

Add the following menu item above where you iterate through users

<MenuItem key='clear' value='clear'>Clear selection</MenuItem>

And here is the onChange for the Select component

onChange={e => setFilterUser(e.target.value === 'clear' ? '' : e.target.value)}
<FormControl>
  <InputLabel>{t('typeUsers')}</InputLabel>
  <Select
    label={t('typeUsers')}
    value={filterUser}
    onChange={e => setFilterUser(e.target.value === 'clear' ? '' : e.target.value)}
  >
   <MenuItem key='clear' value='clear'>Clear selection</MenuItem>
   {Object.values(users).filter((user) => (user.administrator === false)).map((user) => (<MenuItem key={user.id} value={user.id}>{user.name}</MenuItem>))}
 </Select>
</FormControl>

Upvotes: 1

Related Questions