setState when changing value on a <select>

22.2k views Asked by At

I have two <select> inputs. I want to set the attribute as "disable" one of them at a specific value option from the other <select>.

The first one is:

<select ref="selectOption">
   <option selected value="1" >Option 1</option>
   <option value="2" >Option 2</option>
</select>

<select ref="selectTime" disabled={this.state.disabled}>
   <option value="a" >January</option>
   <option value="b" >Febreaury</option>
</select>

So, my idea is to set the state of the 2nd <select> as false when the option value = 2 from the first <select>

How can I do it? Or is there another way without react that I can do it? or with props? I'm pretty confused. I tried to do something like:

var option= ReactDom.findDOMNode(this.refs.selectOption).value;
if( option == '2' ) this.setState({disabled:true});

But it's not working. Tried to put it in componentDidUpdate but the component is not updating when I select a new value from the select, so that won't work. Ideas please.

EDIT:

I also have this solution with jquery but I want to use Reactjs.

$('#selectOption').change(function() {
    $('#selectTime').prop('disabled', false);
    if ($(this).val() == '2') {
        $('#selectTime').prop('disabled', true);
    }
})

I'm pretty confused on how to use ReactDom.findDOMNode(this.refs.selectOption) instead the jquery selectors

6

There are 6 answers

0
Rob M. On BEST ANSWER

Here is a minimal example of how you could accomplish this, add an onChange event handler to your first select, setState in the event handler based on the value:

handleChange(event) {
    let value = event.target.value;
    this.setState({
        disabled: value == '2'
    });
}
render() {
    return (
        <div>
            <select ref="selectOption" onChange={(e) => this.handleChange(e)}>
               <option selected value="1" >Option 1</option>
               <option value="2" >Option 2</option>
            </select>

            <select ref="selectTime" disabled={this.state.disabled}>
               <option value="a" >January</option>
               <option value="b" >Febreaury</option>
            </select>
        </div>
    )
}
1
jmac On

That would be the react way to achieve this:

export default class Test extends Component{

  constructor(props) {
    super(props)

    this.state = {
      selectOptionValue: '1'
    }
  }

  handleOnChange = (e) => {
    this.setState({
      selectOptionValue: e.target.value
    })
  }

  render(){
    return (
      <div>
        <select defaultValue = "1" onChange={this.handleOnChange}>
          <option value="1" >Option 1</option>
          <option value="2" >Option 2</option>
        </select>

        <select  disabled={ this.state.selectOptionValue === '2' }>
          <option value="a" >January</option>
          <option value="b" >Febreaury</option>
        </select>
      </div>
    )
  }
}
0
wackozacko On

If you want to keep it simple and use pure javascript, you could just use the following snippet.

document.querySelector('select[ref="selectOption"]').addEventListener('change', function(e) {
  document.querySelector('select[ref="selectTime"]').disabled = (e.target.value === '2') ? true : false;
})
<select ref="selectOption">
  <option selected value="1">Option 1</option>
  <option value="2">Option 2</option>
</select>

<select ref="selectTime">
  <option value="a">January</option>
  <option value="b">Febreaury</option>
</select>

0
An Nguyen On

How about onChange event from this ? For your convenience:

class FlavorForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 'coconut'};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

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

  handleSubmit(event) {
    alert('Your favorite flavor is: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Pick your favorite La Croix flavor:
          <select value={this.state.value} onChange={this.handleChange}>
            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

0
mununki On

Here's another approach to define which state variable needs to be set.

state = { someStateVariable : "" }

render() {
    return (
        <select onChange={event => this._setSelected({ someStateVariable: event.target.value })}>
            <option value="1">One</option>
            ...
        </select>
    );
}

_setSelected = newState => {
    this.setState(newState)
}
1
Asm Hijas On

Step 1 - Create state and set initial value an empty string

      const [category,setCategory] = useState('');

Step 2 Map youre options and check id in the option value === select value then set selected to true

  const renderedResults = results.map((result) => {
    const selected = category === result.id ? "true" : '';
    return (
      <option selected={selected} key={result._id} value={result._id}>{result?.name}</option>
      );
  });

Step 3

 <select
   onChange={(e) => {
    setCategory(e.target.value);
   }}
   className="form-select"
   aria-label={"Default select example"}
   >
   <option value="">Select a category</option>
     {renderedResults}
 </select>