Gonzalo
Gonzalo

Reputation: 355

Material UI Select Multiple Selection in Array

I created a Select using React that allows the user to select multiple options. The problem is that the Select displays the ID of the selected item, instead of their name. How can I change the code in a way that the Select display the names separated by commas (now shows the IDs separated by commas), while keeping the array of ids for later processing.

Any idea how to fix it? Here is the code to CodeSanbox

I have the following array in a Material UI Select:

const names = [
  { id: "1", value: "Oliver Hansen" },
  { id: "2", value: "Van Henry" },
  { id: "3", value: "Omar Alexander" }
];

This is the code that renders the Multiple Select:

<Select
          labelId="demo-mutiple-checkbox-label"
          id="demo-mutiple-checkbox"
          multiple
          value={personName}
          name="first"
          onChange={handleChange}
          input={<OutlinedInput label="Tag" />}
          renderValue={(selected) => selected.join(", ")}
        >
          {names.map((name) => (
            <MenuItem key={name.id} value={name.id}>
              <Checkbox checked={personName.indexOf(name.id) > -1} />
              <ListItemText primary={name.value} />
            </MenuItem>
          ))}
        </Select>

Upvotes: 2

Views: 12942

Answers (5)

KJ Sudarshan
KJ Sudarshan

Reputation: 3232

Update the Menu Items' value to be a object instead of an id.

    <Select
      labelId="demo-mutiple-checkbox-label"
      id="demo-mutiple-checkbox"
      multiple
      value={personName}
      name="first"
      onChange={handleChange}
      input={<OutlinedInput label="Tag" />}
      renderValue={(selected) => selected.map((item) => item.value)?.join(",")}
    >
      {names.map((name) => (
        <MenuItem key={name.id} value={name}>
          <Checkbox
            checked={personName.find((p) => p.id === name.id) !== undefined}
          />
          <ListItemText primary={name.value} />
        </MenuItem>
      ))}
    </Select>

Upvotes: 0

Catur Wicaksono
Catur Wicaksono

Reputation: 258

the simple steps I did, just focus on the renderValue property, on the Select component:

renderValue={(selected) => names.find((val) => val.id === selected).value}

the logic I use, find the value in the 'names' array, where the id is the selected id, then take the 'value' value in the 'names' array, to display.

Upvotes: 1

Mahdi Farahani
Mahdi Farahani

Reputation: 31

just you can do this:

renderValue={
    (selected) => 
        names.filter( name => selected.includes(name.id) )
            .map( record => record.name )
            .join(", ")
} 

Upvotes: 2

Junaid Faryad
Junaid Faryad

Reputation: 1707

To show the selected user's names, you can update the map part, where currently, you're using id.

You can update this to use the name.value to store/show the person's names.

{names.map((name) => (
   <MenuItem key={name.value} value={name.value}>
     <Checkbox checked={personName.indexOf(name.value) > -1} />
     <ListItemText primary={name.value} />
   </MenuItem>
 ))}

Updated Sandbox

Upvotes: 1

Vinibr
Vinibr

Reputation: 834

I found one possible solution for your issue.

check if it works for you.

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import { Input, OutlinedInput } from "@material-ui/core";
import InputLabel from "@material-ui/core/InputLabel";
import FormControl from "@material-ui/core/FormControl";
import Select from "@material-ui/core/Select";
import MenuItem from "@material-ui/core/MenuItem";
import ListItemText from "@material-ui/core/ListItemText";
import Checkbox from "@material-ui/core/Checkbox";

const useStyles = makeStyles((theme) => ({
  formControl: {
    margin: theme.spacing(1),
    minWidth: 300
  },
  selectEmpty: {
    marginTop: theme.spacing(2)
  }
}));

const names = [
  { id: "1", value: "Oliver Hansen" },
  { id: "2", value: "Van Henry" },
  { id: "3", value: "Van Henry" }
];

export default function NativeSelects() {
  const classes = useStyles();
  const [personName, setPersonName] = React.useState([]);

  const handleChange = (event) => {
    const {
      target: { value }
    } = event;
    setPersonName(
      // On autofill we get a the stringified value.
      typeof value === "string" ? value.split(",") : value
    );
  };

  return (
    <div>
      <FormControl className={classes.formControl}>
        <InputLabel htmlFor="age-native-simple">
          Names here to select from
        </InputLabel>
        <Select
          labelId="demo-mutiple-checkbox-label"
          id="demo-mutiple-checkbox"
          multiple
          value={personName}
          name="first"
          onChange={handleChange}
          input={<OutlinedInput label="Tag" />}
          renderValue={(selected) => selected.map(obj=> names[obj - 1].value).join(", ")}
        >
          {names.map((name) => (
            <MenuItem key={name.id} value={name.id}>
              <Checkbox checked={personName.indexOf(name.id) > -1} />
              <ListItemText primary={name.value} />
            </MenuItem>
          ))}
        </Select>
      </FormControl>
    </div>
  );
}

Updated Code

Upvotes: 5

Related Questions