1

i want to built an multi select checkbox dropdown in react with es6 my requirement is as below specified in image

enter image description here

I tried doing this click here but it is not working.

1
  • I tried semantic UI, but I have not found any dropdown like this Commented Nov 28, 2017 at 7:05

2 Answers 2

5

You can use one parent component that will keep values in its state and toggle list items. Then you can create component for each list item that will keep active property in state that you can toggle on click.

class ListItem extends React.Component {
  constructor(props) {
    super(props);
    this.state = {active: false}
  }
  
  render() {
    return (
      <a
      onClick={() => {
        this.setState(prevState => {
          let newState = !prevState.active;
          this.props.handleClick(newState, this.props.value);
          return {active: newState}
        })
      }}
      className={!this.state.active ? '' : 'selected'}
      href="#">
      {this.props.value}</a>
    )
  }
}

class Select extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      showList: false,
      value: []
    }
    
    this.handleItemClick = this.handleItemClick.bind(this)
  }
  
  componentDidMount() {
    document.addEventListener('mousedown', (e) => {
      if(!this.node.contains(e.target)) {
        this.setState({showList: false})
      }
    })
  }
  
  componentWillUnmount() {
     document.removeEventListener('mousedown');
  }
  
  renderValue() {
    let {value} = this.state;
    if(!value.length) return "Select..."
    else return value.join(', ')
  }
  
  toggleList() {
    this.setState(prevState => ({showList: !prevState.showList}))
  }
  
  handleItemClick(active, val) {
    let {value} = this.state;
    
    if(active) value = [...value, val]
    else value = value.filter(e => e != val);
    
    this.setState({value})
  }
  
  
  render() {
    return (
      <div 
      ref={node => this.node = node}
      className="select">
        <button onClick={this.toggleList.bind(this)}>
          <span className="select_value">
            {this.renderValue()}
          </span>
        </button>
        
        <div
        className={"select_list " + (!this.state.showList && 'hide')}>
          <ListItem handleClick={this.handleItemClick} value="Lorem" />
          <ListItem handleClick={this.handleItemClick} value="Ipsum" />
          <ListItem handleClick={this.handleItemClick} value="Dolor" />
        </div>
      </div>
    )
  }
}

ReactDOM.render(
  <Select />,
  document.getElementById('container')
);
button {
  background: white;
  width: 100%;
  padding: 10px 15px;
  border: 1px solid rgba(0, 0, 0, .1);
  border-radius: 5px;
  cursor: pointer;
  text-align: left;
}
.select_list {
  width: 100%;
  background: white;
  border: 1px solid rgba(0, 0, 0, .1);
  border-radius: 5px;
}

.select_list a {
  padding: 10px 15px;
  display: flex;
  color: black;
  text-decoration: none;
  position: relative;
  align-items: center;
}

.select_list a:before {
  width: 15px;
  height: 15px;
  content: '';
  border: 1px solid rgba(0, 0, 0, .1);
  border-radius: 5px;
  margin-right: 10px;
  display: block;
}

.select_list a.selected:before {
  background: #0493D1;
  content: '✓';
  color: white;
  font-size: 11px;
  text-align: center;
  line-height: 15px;
}

.hide {
  display: none;
}
<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="container"></div>

Sign up to request clarification or add additional context in comments.

8 Comments

thanks for your replay but dropdown ui is not reflecting as shown in the answer
document.removeEventListener('mousedown'); this lines give me error whenever i switch from one component to another. "Failed to execute 'removeEventListener' on 'EventTarget': 2 arguments required, but only 1 present."
I passed a empty function as a 2nd parameter and the issue is resolved but now whenever i switch component it gives me error on componentDidMount() function "TypeError: Cannot read property 'contains' of null". please help me @NenadVarcar
The problem is probably coming from event listener on document that i used on componentDidMount and that is for option to close modal when you click outside of it. But I can't tell you exactly why is that happening without your code example. Event listener should be removed on componentWillUnmount, so you can ether remove that functionality or try to implement it in some other way if you can't fix it like it is now.
Set display block on pseudo element.
|
1

Semantic-UI React Approach

After much digging, I found an old conversation between eugenetumachov and Semantic-UI developers(?). One of the users provided incredibly helpful code that answers this question using Semantic-UI's Dropdown component.

This is done by making use of Dropdown's Dropdown.Menu and Dropdown.Item. Then looping through your options via map to create checkboxes. The only downside is that the workaround does not seem to allow scrolling and will require more CSS. Additionally, based on CSS the checkbox items' background color may turn transparent if you double-click on the dropdown, and the dropdown will collapse on mouse hover. You can bypass the transparency issue by using a class or style property for your Dropdown.Menu and Dropdown.Item.

Semantic-UI developer's response to this type of question appears to be a flat "no" or a

Active items are automatically removed from the Dropdown menu. So you cannot show a "checked" state for an item in the menu.

You could create a similar component out of an Input as a trigger for a Popup containing a Menu or List of Checkboxes.

  1. Are dropdowns with checkboxes possible? #2417
  2. eugenetumachov's workaround

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.