Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change material-ui select value?

Let's start by consider this little snippet:

import "./styles.css";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemSecondaryAction from "@material-ui/core/ListItemSecondaryAction";
import ListItemText from "@material-ui/core/ListItemText";
import Checkbox from "@material-ui/core/Checkbox";
import Select from "@material-ui/core/Select";
import React, { Component } from "react";

class WidgetList extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  onChangeTag = (event, item) => {
    item.tag = event.target.value;
    console.log("changing tag", event.target, item.name);
  };

  render() {
    const { allItems } = this.props;
    const { selectedItems } = this.props;

    return (
      <List>
        {allItems.map((item) => {
          return (
            <ListItem
              key={item.name}
              role={undefined}
              dense
              button
              disableRipple
            >
              <ListItemIcon>
                <Checkbox
                  edge="start"
                  checked={selectedItems.has(item)}
                  tabIndex={-1}
                  disableRipple
                />
              </ListItemIcon>
              <ListItemText primary={`${item.name}`} />
              <ListItemSecondaryAction>
                <Select
                  native
                  value={item.tag}
                  onChange={(e) => this.onChangeTag(e, item)}
                >
                  <option value={0}>foo</option>
                  <option value={1}>bar</option>
                  <option value={2}>baz</option>
                </Select>
              </ListItemSecondaryAction>
            </ListItem>
          );
        })}
      </List>
    );
  }
}

let allItems = [
  { name: "1", tag: 0 },
  { name: "2", tag: 1 },
  { name: "3", tag: 2 }
];
let selectedItems = new Set([allItems[0], allItems[1]]);

export default function App() {
  return (
    <div className="App">
      <WidgetList allItems={allItems} selectedItems={selectedItems} />
    </div>
  );
}

I'd like to understand what's the way to change the value of the select widgets when clicking a different one. Right now no matter which one you select the widget won't change.

To see what I mean you can play with it on this sandbox, no matter if you select foo, bar, baz values on the select widget the widget itself won't update.

like image 850
BPL Avatar asked Sep 10 '20 15:09

BPL


People also ask

How do I change the default value in material UI dropdown?

To set the default value in React Material-UI select box, we can set the initial value of the state that we use as the Select 's value prop's value. The initial value must match one of the value prop of values of MenuItem . to define the value state with useState . We set value 's initial value to "50k-100k" .

How do I change the Select icon in material UI?

To change the dropdown icon in React Material UI select field, we can set the IconComponent prop to a function that returns the icon component we want to render. We set the Select 's IconComponent prop to a function that returns the Person icon component. And we add some MenuItem components to add some choices.

What is MUI select?

The MUI Select component is an input/dropdown combo that comes with dozens of configurable props. In this tutorial I will customize the dropdown position, the default and placeholder values, add multiselect, and add labels and helper text, and more. MUI Select with Dropdown Offset and Placeholder Value.

How to use material-UI select with array of objects as options?

In this short article, we would like to show how to use in React project, Material-UI Select component with array of objects as options. By default, the select component doesn't use an options array, so it is necessary to add items inside using JSX notation. Presented solution uses controlled component mode ( value and onChange ).

How to set the default value in react material-UI select box?

To set the default value in React Material-UI select box, we can set the initial value of the state that we use as the Select ‘s value prop’s value. The initial value must match one of the value prop of values of MenuItem. to define the value state with useState. We set value ‘s initial value to "50k-100k".

How do I set the age of a material UI object?

If you take a look at the Select Api of Material UI here, you could do it easily. As explained above, you need to pass the default value in your state variable: const [age, set Age] = React.useState (10); // < --------------(Like this) .

How do I change the default value of an uncontrolled component?

With an uncontrolled component, you often want React to specify the initial value, but leave subsequent updates uncontrolled. To handle this case, you can specify a defaultValue attribute instead of value. You need to update allItems value on onChange for working of onChange select i.e


2 Answers

You need to change your approach to store selected items state so that it can handle that efficiently.

The main mistake was in this line:

item.tag = event.target.value;

You cannot do that because the item is immutable.

I have updated the code from your sandbox to make the select work properly.

import "./styles.css";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemSecondaryAction from "@material-ui/core/ListItemSecondaryAction";
import ListItemText from "@material-ui/core/ListItemText";
import Checkbox from "@material-ui/core/Checkbox";
import Select from "@material-ui/core/Select";
import React, { Component } from "react";

class WidgetList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      allItems: [],
      selectedItems: {}
    };
  }

  onChangeTag = (event, item) => {
    this.setState({
      selectedItems: {
        ...this.state.selectedItems,
        [selectedItems[item.tag.toString()]]: event.target.value
      }
    });
  };

  render() {
    const { allItems } = this.props;
    const { selectedItems } = this.props;

    return (
      <List>
        {allItems.map((item) => {
          return (
            <ListItem
              key={item.name}
              role={undefined}
              dense
              button
              disableRipple
            >
              <ListItemIcon>
                <Checkbox
                  edge="start"
                  checked={selectedItems.has(item)}
                  tabIndex={-1}
                  disableRipple
                />
              </ListItemIcon>
              <ListItemText primary={`${item.name}`} />
              <ListItemSecondaryAction>
                <Select
                  native
                  value={selectedItems[item.tag.toString()]}
                  onChange={(e) => this.onChangeTag(e, item)}
                >
                  <option value={0}>foo</option>
                  <option value={1}>bar</option>
                  <option value={2}>baz</option>
                </Select>
              </ListItemSecondaryAction>
            </ListItem>
          );
        })}
      </List>
    );
  }
}

let allItems = [
  { name: "1", tag: 0 },
  { name: "2", tag: 1 },
  { name: "3", tag: 2 }
];
let selectedItems = new Set([allItems[0], allItems[1]]);

export default function App() {
  return (
    <div className="App">
      <WidgetList allItems={allItems} selectedItems={selectedItems} />
    </div>
  );
}
like image 95
Hashir Baig Avatar answered Sep 28 '22 20:09

Hashir Baig


You can achieve the same result without using state (as what suggested by most answers) by implementing an uncontrolled component. This way data will be handled by the DOM and not by React.

Just change the value prop on your Select component to defaultValue.

<Select
  native
  defaultValue={item.tag}
  onChange={(e) => this.onChangeTag(e, item)}
>
  <option value={0}>foo</option>
  <option value={1}>bar</option>
  <option value={2}>baz</option>
</Select>

From the docs

With an uncontrolled component, you often want React to specify the initial value, but leave subsequent updates uncontrolled. To handle this case, you can specify a defaultValue attribute instead of value.

Edit crimson-haze-9gpec

like image 31
bertdida Avatar answered Sep 28 '22 20:09

bertdida