sujon
sujon

Reputation: 367

How to select group based checkbox antd in reactjs

I want to select a group based checkbox. The problem is that when I click on the group, the entire checkbox is selected. I don't want to select the entire checkbox. this is my Initial State.

const plainOptions = ["can_view", "can_create", "can_update"];
state = {
  checkedList: [],
  indeterminate: true,
  checkAll: false
};

Method: onchange method basically works each individual checkbox.

onChange = checkedList => {
  console.log(checkedList);
  this.setState({
    checkedList,
    indeterminate:
      !!checkedList.length && checkedList.length < plainOptions.length,
    checkAll: checkedList.length === plainOptions.length
  });
};

This method works for selected all checkbox

onCheckAllChange = e => {
  console.log(e.target.checked);
  this.setState({
    checkedList: e.target.checked ? plainOptions : [],
    indeterminate: false,
    checkAll: e.target.checked
  });
};
{
  ["group", "topGroup"].map(item => (
    <div className="site-checkbox-all-wrapper">
      <Checkbox
        indeterminate={this.state.indeterminate}
        onChange={this.onCheckAllChange}
        checked={this.state.checkAll}
      >
        {item}
      </Checkbox>
      <CheckboxGroup
        options={plainOptions}
        value={this.state.checkedList}
        onChange={this.onChange}
      />
    </div>
  ));
}

However, my accepted Data format is

{group:["can_view","can_create"],topGroup:["can_view","can_create"}

I want to get this format output when user selected on the checkbox

Here is the code sandbox : https://codesandbox.io/s/agitated-sea-1ygqu

Upvotes: 0

Views: 516

Answers (1)

3limin4t0r
3limin4t0r

Reputation: 21150

The reason both groups change when you click something in one of them is because both groups use the same internal state.

["group", "topGroup"].map(item => (
  <div className="site-checkbox-all-wrapper">
    <Checkbox
      indeterminate={this.state.indeterminate}
      onChange={this.onCheckAllChange}
      checked={this.state.checkAll}
    >
      {item}
    </Checkbox>
    <CheckboxGroup
      options={plainOptions}
      value={this.state.checkedList}
      onChange={this.onChange}
    />
  </div>
));

Both the group and topGroup use the same this.state.checkList state.


The easiest way to solve this is by extracting each group into its own component. This way they have their own state separate of each other.

Edit stackoverflow-a-60764570-3982562-v1


You could also opt to keep one component, but you must manage multiple internal states. You could for example use state = { checkList: [[], []] } where the first sub-array is to store the group state and the second sub-array is to store the topGroup state.

If groups are dynamic you can simply map over the groups and create your states that way:

state = { checkList: groups.map(() => []) };

You would also need to manage multiple indeterminate and checkAll states. This can be avoided when you deduce those from the checkList state. For example:

isIndeterminate(index) {
  const checkList = this.state.checkList[index];
  return checkList.length > 0 && checkList.length < plainOptions.length;
}

This would also avoid conflicting state, since there is one source of truth.

Upvotes: 1

Related Questions