vault
vault

Reputation: 134

How to change the available values of a <Select> on input from another <Select>

[Not jQuery] I have two Selects's and a list of elements and wish to map the available options on the second Select based on the current value of the first select

<Select options={sources} defaultValue={sources[0]} onChange={() => {
                // change value of select below
            }}/>

<Select options={mediums} defaultValue={mediums[0]} name="mediumSelect"/>

I'm not sure how to do this without jquery and currently interning at a company that does not use jquery at all. Any input is appreciated

Upvotes: 0

Views: 627

Answers (4)

Alvin Theodora
Alvin Theodora

Reputation: 946

You could set the value of first Select to your component state, then apply your custom own logic for the second Select values according to first Select value

const sources = ["A", "B"];
const mediumsA = ["C", "D"];
const mediumsB = ["E", "F"];
class Todo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {     
      selectedMedium: ""
    };
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.setState({
      selectedMedium: e.target.value
    });
  }

  render() {
    //your logic to your mediums var
    const mediums = this.state.selectedMedium === "B" ? mediumsB : mediumsA;

    return (
      <div>
        <Select
          options={sources}
          defaultValue={sources[0]}
          onChange={this.handleChange}
        />
        <Select options={mediums} defaultValue="" name="mediumSelect" />
      </div>
    );
  }
}



const Select = ({ options, onChange })=> {
    return (
      <select onChange={onChange}>
        {options.map(data => {
          return <option>{data}</option>;
        })}
      </select>
    );
};


ReactDOM.render(<Todo />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Upvotes: 1

Harsh kurra
Harsh kurra

Reputation: 1216

Something like this... Here, listen on change of source select component and update the options array of the second input, don't forget to check if an element already exists in an array on not

       <Select  
          options={sources}
          value={this.state.selectedSource}
          onChange={evt => {
            this.setState({
              mediums: [...this.state.mediums, evt.target.value],
              selectedSource: evt.target.value
            });
          }}
        />
        <Select
          options={sources}
          value={this.state.selectedMediums}
          onChange={evt => {
            this.setState({
              selectedMediums: evt.target.value
            });
          }}
        />

With Native HTML elements

    <select
      value={this.state.selectedSource}
      onChange={evt => {
        this.setState({
          mediums: [...this.state.mediums, evt.target.value],
          selectedSource: evt.target.value
        });
      }}
    >
      {this.state.sources.map(value => {
        return (
          <option value={value} key={value}>
            {value}
          </option>
        );
      })}
    </select>
    <select
      value={this.state.selectedMediums}
      onChange={evt => {
        this.setState({
          selectedMediums: evt.target.value
        });
      }}
    >
      {this.state.mediums.map(value => {
        return (
          <option value={value} key={value}>
            {value}
          </option>
        );
      })}
    </select>

Upvotes: 3

Lee
Lee

Reputation: 418

It looks like you are using reactjs. Although with any framework I think it is possible to follow these steps:

  1. Make mediums variable is global variable
  2. in the event onChange of first Select assigns a value to mediums
  3. render the second Select based on the variable mediums

Upvotes: 0

Austin Greco
Austin Greco

Reputation: 33554

The simplest answer is to set some piece of state and use it in the second component:

<Select options={sources} defaultValue={sources[0]} onChange={(e) => {
  this.setState({
    value1: e.target.value
  });
}}/>

// modify whatever you need based on `this.state.value1`
<Select options={mediums} defaultValue={mediums[0]} name="mediumSelect"/>

There are many different ways to do this, depending on if you're using redux, etc. But this should get you started. You should definitely do some reading about the basics of react & forms.

Upvotes: 3

Related Questions