Reactjs – Controlling Multiple Checkboxes

Im building a CheckAllBoxes component in Reactjs. I have a list of items

fruits = {orange, apple, grape}

A general <SelectBox /> component to display and toggle the HTML checkbox

I need to build a <Fruits /> component to list all the fruits and each of item has its own <SelectBox />

Then I need to build a <SelectAll /> component which has a <SelectBox /> and when it is checked, it will toggle all the <CheckBox /> of <Fruits />

If any fruit is unchecked again, then the <SelectAll /> should be unchecked too.

The result should look something like this:

enter image description here

How can I get the <SelectAll /> to control other checkboxes ?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Here is the quick example on how you could do it:

import React, { Component } from 'react';

export default class SelectBox extends Component {
  constructor() {
    super();

    this.handleClick = this.handleClick.bind(this);
    this.state = {
      allChecked: false,
      checkedCount: 0,
      options: [
        { value: 'selectAll', text: 'Select All' },
        { value: 'orange', text: 'Orange' },
        { value: 'apple', text: 'Apple' },
        { value: 'grape', text: 'Grape' }
      ]
    };
  }

  handleClick(e) {
    let clickedValue = e.target.value;

    if (clickedValue === 'selectAll' && this.refs.selectAll.getDOMNode().checked) {
      for (let i = 1; i < this.state.options.length; i++) {
        let value = this.state.options[i].value;
        this.refs[value].getDOMNode().checked = true;
      }
      this.setState({
        checkedCount: this.state.options.length - 1
      });

    } else if (clickedValue === 'selectAll' && !this.refs.selectAll.getDOMNode().checked) {
      for (let i = 1; i < this.state.options.length; i++) {
        let value = this.state.options[i].value;
        this.refs[value].getDOMNode().checked = false;
      }
      this.setState({
        checkedCount: 0
      });
    }

    if (clickedValue !== 'selectAll' && this.refs[clickedValue].getDOMNode().checked) {
      this.setState({
        checkedCount: this.state.checkedCount + 1
      });
    } else if (clickedValue !== 'selectAll' && !this.refs[clickedValue].getDOMNode().checked) {
      this.setState({
        checkedCount: this.state.checkedCount - 1
      });
    }
  }

  render() {
    console.log('Selected boxes: ', this.state.checkedCount);

    const options = this.state.options.map(option => {
      return (
        <input onClick={this.handleClick} type='checkbox' name={option.value} key={option.value}
               value={option.value} ref={option.value} > {option.text} </input>
      );
    });


    return (
      <div className='SelectBox'>
        <form>
          {options}
        </form>
      </div>
    );
  }
}

I’m sorry for the ES6 example. Will add ES5 example when I find more time, but I think you can get the idea on how to do it.
Also you definitely want to break this down into 2 components. Then you would just pass your options as props to the Child component.

Method 2

I would recommend reading Communication between Components

Now in your example you have a communication between two components that don’t have a parent-child relationship. In these case you could use a global event system. Flux works great with React.

In your example I would make FruitStore with the component Fruit listening to store. The FruitStore contains a list with all fruits and if they are selected or not. Fruit will saves it’s content with setState().

Fruit passes to it’s children their status per props. example: <CheckBox checked={this.state.fruit.checked} name={this.state.fruit.name}/>

Checkbox should fire when clicked a FruitAction.checkCheckbox(fruitName).

The FruitStore will then update the Fruit component and so on.

It take some time to get into this unidirectional architecture, but it’s worth learning it. Try starting with the Flux Todo List Tutorial.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x