SebMaz
SebMaz

Reputation: 608

React-Select how to keep default behavior of menu open/close plus add to open menu on button click?

I have a react-select component to preform search on an api , and a button to start the search.

i've tried to set menuIsOpen={true} after button click but it ruins the original focus blur behavior the menu is no longer closing on blur. tried to set .focus() on the input it didn't open the menu.

current original behavior menu is opening on focus and closing on blur , i want to keep this plus i want to open the menu after i click the button.

Upvotes: 2

Views: 13895

Answers (5)

Jahanzeb Awan
Jahanzeb Awan

Reputation: 182

I used onMenuOpen onMenuClose props

import React, { useState } from 'react';
import Select from 'react-select';

const options = [
  { value: 'chocolate', label: 'Chocolate' },
  { value: 'strawberry', label: 'Strawberry' },
  { value: 'vanilla', label: 'Vanilla' },
];

const CustomSelect = () => {
  const [menuIsOpen, setMenuIsOpen] = useState(false);

  const toggleMenu = () => {
    setMenuIsOpen((prev) => !prev);
  };

  return (
    <div>
      <Select
        options={options}
        menuIsOpen={menuIsOpen}
        onMenuOpen={() => setMenuIsOpen(true)}
        onMenuClose={() => setMenuIsOpen(false)}
      />
      <button onClick={toggleMenu}>
        {menuIsOpen ? 'Close Menu' : 'Open Menu'}
      </button>
    </div>
  );
};

export default CustomSelect;

Upvotes: -1

Bhavin Thummar
Bhavin Thummar

Reputation: 1293

This option is good option without managing the state.

openMenuOnFocus={true}

This also work on tab button click because when click on tab button then dropdown have the focus.

Upvotes: 1

guy dadon
guy dadon

Reputation: 322

If you want to preserve the focus out behaviour you should do something like this add a ref at the constructor

    constructor(props) {
        super(props);
        this.state = { open: false }
        this.selectRef = React.createRef();
    }

then add this close method

close() {
        this.setState({ open: false });
        this.selectRef.current.blur();
    }

and on the select component

<Select
    closeMenuOnSelect={props.closeMenuOnSelect || true}
    openMenuOnClick={() => this.setState({ open: true })}
    onFocus={() => this.setState({ open: true })}
    onBlur={() => this.setState({ open: false })}
    menuIsOpen={this.state.open}
    onInputChange={() => {
        if (props.closeMenuOnSelect) {
        this.close();
    }
    }}
    ref={this.selectRef}
    >
</Select>

Upvotes: 2

OlegSuncrown
OlegSuncrown

Reputation: 21

I am using this function in React, to keep open only one tab, so as you open another one, previous will be closed.

const openSingleTab = (id) => {
    const newData1 = data.map((item) => {
        if(item.id === id){
          return {...item, isOpened: !item.isOpened}
        }
        return {...item, isOpened: false}
      })

    setData(newData1)
  }

Upvotes: 0

Laura
Laura

Reputation: 8630

To achieve what you want you will need to use a controlled menuIsOpen props.

I think the easiest way to keep all the native functionality of react-select is to use a combination of the props onInputChange and onFocus like the following code:

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      menuIsOpen: false
    };
  }

  onInputChange = (options, { action }) => {
    if (action === "menu-close") {
      this.setState({ menuIsOpen: false });
    }
  };

  openMenu = () => {
    this.refs.focus();
    this.setState({ menuIsOpen: true });
  };

  render() {
    return (
      <div className="App">
        <Select
          ref={r => {
            this.refs = r;
          }}
          options={options}
          onFocus={this.openMenu}
          onInputChange={this.onInputChange}
          menuIsOpen={this.state.menuIsOpen}
        />

        <button onClick={this.openMenu}>Open Select</button>
      </div>
    );
  }
}

Here a live example.

Upvotes: 5

Related Questions