0

I am working on a react component and I have 3 checkboxes. My requirement is that when 3rd checkbox is checked, any of the first 2 checkboxes that was checked previously should become unchecked and disabled. And when 3rd checkbox is unchecked, any checkbox that was checked previously, should get checked again.

First two checkboxes are dynamically populated from an array like this :

{credits.map((section, i) => (
          <p key={i}>
            <input
              disabled={this.state.checkedChkBox === "noneApply"}
              id={`amtChk${i + 1}`}
              type="checkbox"
              name="amountCheck"
              value={`${section.amount} - ${section.date}`}
            />
            <label htmlFor={`amtChk${i + 1}`} id={`amtLbl${i + 1}`}>
              {section.amount}
            </label>
          </p>
        ))}

3rd checkbox looks like this

<input onChange={evt => this.noneApplyChk(evt)} id="noneApply" type="checkbox" name="noneApplyCheck" value="noneApply" />
        <label htmlFor="noneApply" id="noneApplyLbl">
          None apply
        </label>

In my constructor, I have defined a state to handle disabling of first 2 checkboxes.

constructor(props) {
super(props);
this.state = { checkedChkBox: "" };

}

This is how my noneApplyChk function looks like

noneApplyChk(evt) {
if (this.state.checkedChkBox === "noneApply") {
  this.setState({ checkedChkBox: "" });
} else {
  this.setState({ checkedChkBox: evt.target.id });
}

}

It does the disabling/enabling of first 2 checkboxes well, but I am still not able to find a way to check/uncheck first 2 checkboxes on uncheck/check of the 3rd checkbox. I also tried checked={this.state.checkedChkBox !== "noneApply" || this.state.checkedChkBox !== ""} on the first 2 checkboxes along with onChange event. That didn't help either.

Please let me know if anyone has any ideas.

PS: I want to do it the react way and not the jquery way.

2 Answers 2

1

Here is an example.

Here when tea selected then coffee will unselect and if coffee selected then tea will be unselected.

import { useState } from "react";

  export default function App() {
  const [isCheckedTea, setIsCheckedTea] = useState(false);
  const [isCheckedCoffee, setIsCheckedCoffee] = useState(false);

  
  const handleChangeTea = () => {
    setIsCheckedTea(!isCheckedTea);
    if (isCheckedCoffee) {
      setIsCheckedCoffee(!isCheckedCoffee);
    }
  }
  
 const handleChangeCoffee = () => {
      setIsCheckedCoffee(!isCheckedCoffee);
      if (isCheckedTea) {
        setIsCheckedTea(!isCheckedTea);
      }
    }

  return (
    <div >
      <div >
        <input
          type="checkbox"
          id="tea"
          name="tea"
          value="tea"
          checked={isCheckedTea}
          onChange={handleChangeTea }
        />
        Tea
      </div>
      <div >
        <input
          type="checkbox"
          id="coffee"
          name="coffee"
          value="cofee"
          checked={isCheckedCoffee}
          onChange={handleChangeCoffee}
        />
        Coffee
      </div>
      <div >
        Tea checkbox is {isCheckedTea ? "checked" : "unchecked"}.
        <br />
        Coffee checkbox is {isCheckedCoffee ? "checked" : "unchecked"}.
      </div>
    </div>
  );
}
    
Sign up to request clarification or add additional context in comments.

Comments

-1

Here's one approach:

import React from "react";
import ReactDOM from "react-dom";

class App extends React.Component {
  // some example state
  state = {
    a: { curr: false, prev: false, disabled: false },
    b: { curr: false, prev: false, disabled: false },
    c: false
  };

  toggleOthers = () => {
    if (this.state.c) {
      this.setState({
        a: { curr: false, prev: this.state.a.curr, disabled: true },
        b: { curr: false, prev: this.state.b.curr, disabled: true }
      });
    } else {
      this.setState({
        a: {
          curr: this.state.a.prev,
          prev: this.state.a.curr,
          disabled: false
        },
        b: { curr: this.state.b.prev, prev: this.state.b.curr, disabled: false }
      });
    }
  };

  toggleA = () => {
    this.setState({
      a: { curr: !this.state.a.curr, prev: !this.state.a.curr }
    });
  };

  toggleB = () => {
    this.setState({
      b: { curr: !this.state.b.curr, prev: !this.state.b.curr }
    });
  };

  toggleC = () => {
    this.setState(
      {
        c: !this.state.c
      },
      () => {
        this.toggleOthers();
      }
    );
  };

  render() {
    return (
      <React.Fragment>
        <input
          type="checkbox"
          onChange={this.toggleA}
          checked={this.state.a.curr}
          disabled={this.state.a.disabled}
        />
        <input
          type="checkbox"
          onChange={this.toggleB}
          checked={this.state.b.curr}
          disabled={this.state.b.disabled}
        />
        <input
          type="checkbox"
          onChange={this.toggleC}
          checked={this.state.c.curr}
        />
      </React.Fragment>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

CodeSandbox here.

1 Comment

Thanks @Colin. It works well, but the problem is I don't have a fix number of checkboxes. As you can see in my code above, except for the last "none apply" checkbox, I am getting all others dynamically. So, that number could be 2 or 20 or anything. In such a case, I don't think I can define state like a: { curr: false, prev: false, disabled: false }, b: { curr: false, prev: false, disabled: false },c: { curr: false, prev: false, disabled: false }, d: { curr: false, prev: false, disabled: false },.

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.