简体   繁体   中英

Dynamic React form with multiple values

I'm trying to create a dynamic React form where users can select multiple values from a dropdown menu which then gets saved. I managed to find this example however implementing and adding the attribute multiple doesn't seem to work. Any ideas? Thanks.

Expected result: The user should be able to select multiple values such as Item A and Item B. They can then add another select option but this time choose Item B for example, preserving the last values set.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { values: [] };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  createUI() {
    return this.state.values.map((el, i) => (
      <div key={i}>
        <select
          multiple={true}
          value={el || ""}
          onChange={this.handleChange.bind(this, i)}
        >
          <option value="">Select</option>
          <option value="10">Item A</option>
          <option value="20">Item B</option>
        </select>{" "}
        <input
          type="button"
          value="remove"
          onClick={this.removeClick.bind(this, i)}
        />
      </div>
    ));
  }

  handleChange(i, event) {
    let values = [...this.state.values];
    values[i] = event.target.value;
    this.setState({ values });
  }

  addClick() {
    this.setState((prevState) => ({ values: [...prevState.values, ""] }));
  }

  removeClick(i) {
    let values = [...this.state.values];
    values.splice(i, 1);
    this.setState({ values });
  }

  handleSubmit(event) {
    alert("A name was submitted: " + this.state.values.join(", "));
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        {this.createUI()}
        <input
          type="button"
          value="add more"
          onClick={this.addClick.bind(this)}
        />
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("container"));

You need to save the selections of Select and in the value attribute you need to pass the selected value options.

Working Example - CodeSandbox Link

Code -

handleChange(i, e) {
    let target = e.target;
    let name = target.name;
    let value = Array.from(target.selectedOptions, (option) => option.value);
    this.setState({
      [name]: value
    });
  }

  createUI() {
    return this.state.values.map((el, i) => (
      <div key={i}>
        <select
          name="selectOptions"
          multiple={true}
          value={this.state.selectOptions}
          onChange={this.handleChange.bind(this, i)}
        >
          <option value="">Select</option>
          <option value="10">Item A</option>
          <option value="20">Item B</option>
        </select>{" "}
        <input
          type="button"
          value="remove"
          onClick={this.removeClick.bind(this, i)}
        />
      </div>
    ));
  }

The only problem that I see is the multiple value you set to select . You only need set it true when you're passing array as value property. But you're not doing it. So remove the multiple={true} and you're good to go.

Your approach seems to be fine. At the end, when for example the user selects A , select , B , the this.state.values would log ["10", "", "20"] .

PS: If you're a new React developer and the project is new I highly recommend you using React Hooks and get rid of all this , bind and class components.

If I understand correctly you want make each selections independent for each select box and should be able to submit as whole.

you can update the handleChange method with array of selected value.

  handleChange(i, event) {
    let values = [...this.state.values];

    // change
    values[i] = Array.from(
      event.target.selectedOptions,
      (option) => option.value
    );

    this.setState({ values });
  }

you can following this code link CodeSandbox

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM