2

How can I prevent a <select> element from closing it's dropdown automatically after an option has been selected, i.e. I want to keep the option dropdown open even after a selection has been made.

I've tried invoking event.stopPropagation() and event.preventDefault() in the onChange handler for the <select> but neither worked.

Here is a fiddle with the basic components. I want to implement the functionality I described above.

Edit: I tried applying the stopPropagation() (as mentioned in the possible dulicate) to the <option>'s click handler, and that didn't work either. To me, it seems like there might a React-specific way to handle this case.

Alan Thomas
  • 1,006
  • 2
  • 14
  • 31
  • 3
    Possible duplicate of [Keeping the dropdown open after selecting dropdown element](http://stackoverflow.com/questions/30237189/keeping-the-dropdown-open-after-selecting-dropdown-element) – Jon Uleis Jan 05 '17 at 21:21

1 Answers1

1

According to this answer, it’s not really possible with a native <select> element—at least not quite like you’d expect. So I see a couple of possibilities:

  1. Create a “fake” dropdown menu with an unordered list or any other non-form element, as in the answer that Jon Uleis pointed out in the comment above.

  2. If you’d still prefer to use the native <select> element, there’s a slightly hacky approach which involves setting the size attribute of the element on change (and optionally, removing it on blur).

    Here’s a quick example of what that might look like in React:

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isFocused: false };

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

  handleChange(e) {
    this.setState({ isFocused: true });
  }

  handleBlur(e) {
    this.setState({ isFocused: false });
  }

  render() {
    return (
      <select
        onChange={this.handleChange}
        onBlur={this.handleBlur}
        size={this.state.isFocused
          ? this.props.options.length
          : false}>
        {this.props.options.map((option, index) => (
          <option key={option}>{option}</option>
        ))}
      </select>
    );
  }
}

const options = [
  'This should “stay open”',
  'on change.',
  'It should also “collapse”',
  'on blur.'
];

ReactDOM.render(
  <Hello options={options} />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>
Community
  • 1
  • 1
peterjmag
  • 6,041
  • 1
  • 30
  • 27