1
votes

I'm following this CodeSandBox example of how i can do a multiple material select.

This is my array that have all the possible options:

const permissionsGroupList = [
    { name: 'Sellers' },
    { name: 'Admins' }
];

This is my state that have my selected options:

const [groupPermissions, setGroupPermissions] = useState([]);

My function that add the selected option:

const handleChangeGroupPermissions = event => {
    setGroupPermissions(event.target.value);
};

My template component:

<InputLabel id="mult-check-permissions">Grupo de permissões</InputLabel>
  <Select
    labelId="mult-check-permissions"
    id="demo-mutiple-checkbox"
    multiple
    label="Grupo de permissões"
    onChange={handleChangeGroupPermissions}
    value={groupPermissions}
    input={<Input disableUnderline={true} />}
    renderValue={selected =>
      selected.map(value => <Chip key={value.id} label={value.name} />)
    }
  >
    {permissionsGroupList.map(permissionGroup => (
      <MenuItem
        key={permissionGroup.name}
        value={{ name: permissionGroup.name }}
      >
        <Checkbox
          checked={groupPermissions.some(
            group => group.name === permissionGroup.name
          )}
        />
        <ListItemText primary={permissionGroup.name} />
      </MenuItem>
    ))}
  </Select>

In the example, when i select a already selected option, the element is removed from the array groupPermissions. In my case, when i click in an already selected option, this element is putting again inside the array.

There's something more that i have to do to get a similar result of the sandbox example?

2

2 Answers

1
votes

I see that the sandbox Select gets data as an array of strings so you can simply map permissionsGroupList as an array of strings and not use the name property.

const Select = MaterialUI.Select;
const Input = MaterialUI.Input;
const Chip = MaterialUI.Chip;
const MenuItem = MaterialUI.MenuItem;
const Checkbox = MaterialUI.Checkbox;
const ListItemText = MaterialUI.ListItemText;

const permissionsGroupList = [
  { name: 'Sellers' },
  { name: 'Admins' },
].map(p => p.name);//data in sandbox is NOT an array of objects

const App = () => {
  const [
    groupPermissions,
    setGroupPermissions,
  ] = React.useState([]);

  const handleChangeGroupPermissions = e => {
    setGroupPermissions(e.target.value);
  };
  return (
    <Select
      labelId="mult-check-permissions"
      id="demo-mutiple-checkbox"
      multiple
      label="Grupo de permissões"
      value={groupPermissions}
      input={<Input disableUnderline={true} />}
      onChange={handleChangeGroupPermissions}
      renderValue={selected =>
        selected.map(val => <Chip key={val} label={val} />)
      }
    >
      {permissionsGroupList.map(permissionGroup => (
        <MenuItem
          key={permissionGroup}
          value={permissionGroup}
        >
          <Checkbox
            checked={groupPermissions.includes(
              permissionGroup
            )}
            value={permissionGroup}
          />
          <ListItemText primary={permissionGroup} />
        </MenuItem>
      ))}
    </Select>
  );
};
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@material-ui/[email protected]/umd/material-ui.production.min.js"></script>
<div id="root"></div>
0
votes

Yes, your solution is only adding a new item into your groupPermissions array.

What you should do:

  • Check if the value is already present in groupPermissions
  • If NOT, add it.
  • If YES, remove it.

So your handle option should be something like:

const handleChangeGroupPermissions = event => {
    const { value } = event.target;

    if (groupsPermissions.includes(value) {
        // deep clone from your object array
        const newGroupsPermissions = JSON.parse(JSON.stringify(groupPermissions ));
        newGroupsPermissions = newGroupsPermissions.filter(item => {
            return item.name !== value;
        });
        setGroupPermissions(newGroupsPermissions);
    } else {
        setGroupPermissions([...groupsPermissions, { name: value }]);
    }
};