Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React input checkbox select all component

I'm trying to build a proper react input checkbox select all component. The idea is that there is a component <InputCheckboxAll> and <InputCheckbox> and I'd be able to check the <InputCheckboxAll> and all of the <InputCheckbox> would be selected as well.

I'm having two issues.

  • If <InputCheckboxAll> is checked I can't unselect any of the <InputCheckbox>.
  • If all of the <InputCheckbox> are checked then <InputCheckboxAll> should be checked.

Here's the example.

var InputCheckboxAll = React.createClass({
  handleChange: function (event) {
    this.props.handleChange(event)
  },
  render: function () {
    return (
    <input
           type='checkbox'
           {...this.props}
           onChange={this.handleChange} />
    )
  }
})

var InputCheckbox = React.createClass({
  getInitialState: function () {
    return {
      checked: this.props.checked
    }
  },
  render: function () {
    var checkedValue = this.props.allChecked ? true : this.state.checked
    return (
    <input
           checked={checkedValue}
           type='checkbox'
           {...this.props}/>
    )
  }
})

var Test = React.createClass({
  getInitialState: function () { return {allChecked: false}; },
  handleChange: function (event) {
    var $elm = $(event.target)
    var checked = $elm.prop('checked')
    this.setState({
      allChecked: checked
    })
  },
  render: function () {
    return (
    <div>
      Select All: <InputCheckboxAll handleChange={this.handleChange}/><br/>
      <InputCheckbox allChecked={this.state.allChecked}/><br/>
      <InputCheckbox allChecked={this.state.allChecked}/><br/>
      <InputCheckbox allChecked={this.state.allChecked}/><br/>
    </div>
    )
  }
})

React.render(<Test/>, document.body)
like image 919
ThomasReggi Avatar asked Sep 17 '15 23:09

ThomasReggi


People also ask

How do you make select all checkbox in React?

list. map(item => <div> <input key={item.id} type="checkbox" name={item.name} value={item.name} checked={item. isChecked} onChange={this. handleChange} /> <label>{item.name}</label> </div> ) } render(){ return( <div> <input type="checkbox" value="checkAll" checked={this.

How do I select multiple checkboxes in React?

In our below example, we are going to take an array of one category, which will contain React, Laravel, PHP, Angular, etc. We will show dynamic multiple checkboxes by using the map loop. We will make a variable named "checkedItems" to store the information of the checkbox, which is selected by the user.

How do you select all checkbox in React JS with hooks?

If we override the checked parameter by setting it to checked={checkAll} we can click the All checkbox, and both checkbox 1 and two gets checked off.


1 Answers

I think there could be some modifications to your implementation to achieve the desired results in a more React'esque form.

What you should get rid of first, is the InputCheckboxAll checkbox class, and the allChecked prop of the InputCheckbox class. A checkbox is a relatively dumb element, it should not know about concepts such as Everything is selected.

Instead, the checkbox should be implemented as an item that is simply either checked or unchecked.

var InputCheckbox = React.createClass({
  getDefaultProps: function () {
    return {
      checked: false
    }
  },
  render: function () {
    return (
    <input
           checked={this.props.checked}
           type='checkbox'
           {...this.props}/>
    )
  }
})

The state of your app (concepts such as All Selected) should be managed from the main App, keeping lower level elements stateless. The state of the main app can simply represent the checked status of each of your checkboxes:

  getInitialState: function () { 
      return {
        // 3 checkboxes, all initialized as unchecked
        checked: [false, false, false]
      }; 
  },

Now, you can recreate the render function to draw 3 checkboxes, plus your select all checkbox. Each <InputCheckbox> can be binded to its own data in the this.state.checked array. When the <Inputcheckbox> changes, we bind an index to the change handler, so we know which array element to modify.

  render: function () {
    // Recalculate if everything is checked each render, instead of storing it
    var isAllChecked = this.state.checked.filter(function(c) {
        return c;
    }).length === this.state.checked.length;

    return (
    <div>
      Select All: <InputCheckbox 
               onChange={this.selectAll} 
               checked={isAllChecked}/><br/>

      <InputCheckbox 
               checked={this.state.checked[0]} 
               onChange={this.handleChange.bind(this, 0)}/><br/>
      <InputCheckbox 
               checked={this.state.checked[1]} 
               onChange={this.handleChange.bind(this, 1)}/><br/>
      <InputCheckbox 
               checked={this.state.checked[2]} 
               onChange={this.handleChange.bind(this, 2)}/><br/>
    </div>
    )
  }

You don't need to store any state related to All Selected. Instead, it would be better to recalculate if everything is selected or not during every render. When the Select All checkbox is checked, we simply set every element of this.state.checked to true.

This also has the advantage of when you manually select all the checkboxes, the select all checkbox will check itself.

Here's a sample implementation: https://jsfiddle.net/rsupvxry/

like image 139
J3Y Avatar answered Sep 28 '22 03:09

J3Y