Search code examples
reactjsmaterial-uiplaceholdermultiple-select

Material UI Multi-Select different code value and visible value - show keys instead values


I am using Material UI Multiple Select based on documentation example. I need to save id of the selected option and show name, so I render object. When I used example from documentation with placeholder, i see ids instead names of selected. See: https://codesandbox.io/s/kxz5yqmrzv?from-embed

const names = [
  { id: "a", name: "Oliver Hansen" },
  { id: "b", name: "Van Henry" },
  { id: "c", name: "April Tucker" },
  { id: "d", name: "Ralph Hubbard" },
  { id: "e", name: "Omar Alexander" },
  { id: "f", name: "Carlos Abbott" },
  { id: "g", name: "Miriam Wagner" },
  { id: "h", name: "Bradley Wilkerson" },
  { id: "i", name: "Virginia Andrews" },
  { id: "j", name: "Kelly Snyder" }
];

          <Select
            multiple
            displayEmpty
            value={this.state.name}
            onChange={this.handleChange}
            input={<Input id="select-multiple-placeholder" />}
            renderValue={selected => {
              if (selected.length === 0) {
                return <em>Placeholder</em>;
              }

              return selected.join(", ");
            }}
            MenuProps={MenuProps}
          >
            <MenuItem disabled value="">
              <em>Placeholder</em>
            </MenuItem>
            {names.map(name => (
              <MenuItem
                key={name.id}
                value={name.id}
                // style={getStyles(name, this)}
              >
                {name.name}
              </MenuItem>
            ))}
          </Select>

Solution

  • The Select is just doing what you have told it to do in your renderValue function:

                renderValue={selected => {
                  if (selected.length === 0) {
                    return <em>Placeholder</em>;
                  }
                  // This will return a comma-separated list of the values.
                  return selected.join(", ");
                }}
    

    You can let Material-UI figure out the correct display by leaving renderValue undefined when you have selected values:

                renderValue={
                  this.state.name.length > 0
                    ? undefined
                    : () => <em>Placeholder</em>
                }
    

    Edit Material demo

    It would also be possible to do a more complicated renderValue that uses your names data structure to convert the values to names, but this is only necessary if you want to do something different than the default rendering of the selected values (such as in the Chip demonstration).