6

I have the following Code using https://ant.design/components/checkbox/, and Trying to uncheck when a checkbox has been checked. I don't want to check all if button is click, just Uncheck all or the one checkbox selected.

constructor(props) {
        super(props);
        this.state = {
            checked: true,
        }
        this.onChange = this.onChange.bind(this);
    }


    onChange(value) {
        this.props.onChangeSession(value)
    }

    onChangeBox = e => {
        this.setState({
            checked: e.target.checked,
        });
    };

    unChecked = () => {
        this.props.onChangeSession([])
        this.setState({
            checked: false
        });
    };


    render () {
        const {
            data,
        } = this.props
        return  (
            <div>
                <Button type="primary" size="small" onClick={this.unChecked}>
                   Uncheck
                </Button>
                <Checkbox.Group 
                    style={{ width: '100%' }} 
                    onChange={this.onChange}>
                    <div>
                        <div className="filter-subhead">Track</div>

                        {data.map(i => 
                            <div className="filter-item">
                                <Checkbox
                                checked={this.state.checked}
                                onChange={this.onChangeBox}
                                value={i}>{i}</Checkbox>
                            </div>
                        )}                     
                    </div>
                </Checkbox.Group> 
            </div>

        )
    }

Any help will be appreciate!

Mandoxsy
  • 103
  • 2
  • 3
  • 9

2 Answers2

5

Working Link

The toggle on the checkbox wasn't working due to Checkbox.Group, you can simply use Checkbox


Regarding Checkbox State:

You can't have a single state for all the checkboxes, so you will need to have an array of bool which will serve as the state for each checkbox item.

In the example, I have initialized checkbox state on componentDidMount and it creates an array ([false,false,false,...]) and the exact same thing is used for resetting on Uncheck. (Possibility of refactoring in my code)

User assigned state will decide whether to check the checkbox or not.

import React from "react";
import ReactDOM from "react-dom";
import { Button, Checkbox } from "antd";
import "antd/dist/antd.css";
import "./index.css";

let data = [3423, 3231, 334234, 55345, 65446, 45237];

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      checkboxArray: []
    };
    // this.onChange = this.onChange.bind(this);
  }

  componentDidMount() {
    let createEmptyArray = new Array(data.length).fill(false);
    this.setState({ checkboxArray: createEmptyArray });
  }

  onChange(e) {
    console.log(e.target);
  }

  onChangeBox = (e, i) => {
    let checkBoxCurrentState = this.state.checkboxArray;
    checkBoxCurrentState[i] = !checkBoxCurrentState[i];
    this.setState({
      checkboxArray: checkBoxCurrentState
    });
  };

  unChecked = e => {
    let resetArray = new Array(data.length).fill(false);
    this.setState({
      checkboxArray: resetArray
    });
  };

  render() {
    const { data } = this.props;
    return (
      <div>
        <Button type="primary" size="small" onClick={this.unChecked}>
          Uncheck
        </Button>

        <div>
          <div className="filter-subhead">Track</div>
          {data.map((i, index) => (
            <div className="filter-item">
              <Checkbox
                checked={this.state.checkboxArray[index] ? true : false}
                onChange={e => this.onChangeBox(e, index)}
                value={index}
              >
                {JSON.stringify(this.state.checkboxArray[index])}
              </Checkbox>
            </div>
          ))}
        </div>
        {JSON.stringify(this.state.checkboxArray)}
      </div>
    );
  }
}

ReactDOM.render(<App data={data} />, document.getElementById("root"));

Simple copy and paste the above code and add props where required.

And if you want to user Checkbox.Group, will need to update the onChange method of CheckBox.Group

let data = ['Apple', 'Pancakes', 'Butter', 'Tea', 'Coffee'];
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      checkboxArray: []
    };
    // this.onChange = this.onChange.bind(this);
  }

  componentDidMount() {
    let createEmptyArray = new Array(this.props.data.length).fill(false);
    this.setState({ checkboxArray: createEmptyArray });
  }

  onChangeBox = (e, i) => {
    let checkBoxCurrentState = this.state.checkboxArray;
    checkBoxCurrentState[i] = !checkBoxCurrentState[i];
    this.setState({
      checkboxArray: checkBoxCurrentState
    });
  };

  unChecked = () => {
    let resetArray = new Array(data.length).fill(false);
    this.setState({
      checkboxArray: resetArray
    });
  };

  render() {
    const { data } = this.props;
    return (
      <div>
        <button onClick={this.unChecked}>Clear All</button>
        {this.props.data.map((single, index) => (
          <div>
            <input
              type="checkbox"
              id={index}
              name="scales"
              checked={this.state.checkboxArray[index]}
              onChange={e => this.onChangeBox(e, index)}
            />
            <label for={index}>{single}</label>
          </div>
        ))}
      </div>
    );
  }
}

ReactDOM.render(<App data={data} />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Dhaval Jardosh
  • 7,151
  • 5
  • 27
  • 69
  • Yeah Thats exactly the issue I'm facing. I know I can access e.target.checked through onChangeBox, but still not sure how to set false to checked. Using only react could be a good option. I still want to figure out how to do it using antd though. Thanks @DhavalJardosh ! – Mandoxsy Jun 21 '19 at 18:59
  • @Mandoxsy, check my edit, have removed the `Checkbox.Group` and everything works fine, you should probably go with that approach. – Dhaval Jardosh Jun 21 '19 at 20:21
  • This is great! yeah I see that checked works fine if we remove checkbox.group. The reason I'm using checkbox.group is because I have more than one with different values, and have to pass and array of all values selected in order to filter it later. Could I still use this approach and add the values selected to an array in order to send all values selected? – Mandoxsy Jun 21 '19 at 21:22
  • I'm not sure, but you can give it a try and we can definitely resolve if there are any issues. – Dhaval Jardosh Jun 21 '19 at 21:26
0

If you're going to use a map to dynamically generate the checkboxes, using state to keep track of checked value will be tricky. You should not do this.

What you should do is not include the checked prop at all in the component.

<Checkbox
    onChange={this.onChangeBox}
    value={i}>{i}
</Checkbox>

The checkbox should still check even if you do not include the checked prop. It's a little strange, I know.

Instead just pass the value into the onChangeBox function and handle all your logic there and set a state value on change.

I just tested it out and it works.

Nicholas Porter
  • 2,588
  • 2
  • 23
  • 37
  • Thanks @NicholasPorter! I see what you mean about not including checked. I can still see checked in onChangeBox -> e.target.checked. I'm still not sure how to set e.target.checked to false to all checkbox when I trigger `toggleChecked()`. will you be able to help ? Thanks! – Mandoxsy Jun 21 '19 at 18:58