0

I have to create a button that activates when a check box is checked and disables when unchecked. I was able to achieve this by the following code.

import React from "react";
import "./styles.css";
import{useState} from 'react'

export default function App() {

  const [change, setChange] = useState(true);
function buttonHandler(){
  setChange(!change)
}

  return (
    <div className="App">
      <button disabled={change}>Click Me</button>

      <input type="checkbox" onChange={buttonHandler}/>
      <input type="checkbox" onChange={buttonHandler}/>
      <input type="checkbox" onChange={buttonHandler}/>
      
    </div>
  );
}

Now I have another challenge where I have to keep it disabled if more than 1 check box is checked. I tried to use object and array manipulation but it does not work. Any advice on how this can be achieved.

1
  • @Andy yes. if no checkbox is checked then also the button should be disabled Commented Nov 21, 2021 at 4:31

2 Answers 2

2
import React from "react";
import{useState} from 'react'

export default function App() {

  const [checkboxStatus, setCheckboxStatus] = useState(Array(3).fill(false));

  function buttonHandler(index){
    let status = [...checkboxStatus];
    status[index] = !status[index]
    setCheckboxStatus(status)
  }

  return (
    <div className="App">
      <button disabled={checkboxStatus.filter(status => status === true).length != 1}>Click Me</button>
      {Array(3).fill(0).map((_, index) => <input type="checkbox" checked={checkboxStatus[index]} onChange={() => buttonHandler(index)}/>)}
    </div>
  );
}

You can do that by keeping track of the status of the checkbox rather than tracking the status of the button. This is because if you know the status of all the checkboxes, you can easily calculate the status of the button.

I have also taken the liberty of converting the checkbox to map it since the content is the same. You can do the same by passing the index to each of them. Something like <input type="checkbox" onChange={() => buttonHandler(0}/> and so on for each of the inputs.

Sign up to request clarification or add additional context in comments.

1 Comment

@Andy If more than one checkbox is enabled OP needs the button to be disabled.
0

Wrap your input elements in a parent element like form or div.

Maintain state; an array that contains each box status (either true or false). When a box is changed call the handleChange which will update the state.

The button disabled property should call a function called isDisabled which will check to see if there are zero boxes checked or more than one box checked, returning true if the condition is matched.

const { useEffect, useState } = React;

function Example() {

  const [boxes, setBoxes] = useState([]);

  // In the text I suggested wrapping the inputs in
  // a parent element. This was so we could use the following
  // code to find its index within the list of inputs
  // without adding any more code to the JSX
  // Cribbed from https://stackoverflow.com/a/39395069/1377002
  function handleChange(e) {

    // Destructure the children from the parent of
    // the element that was changed (ie all the input elements)
    const { parentNode: { children } } = e.target;

    // Find the index of the box that was changed
    const index = [...children].indexOf(e.target);

    // Copy the state
    const newState = [...boxes];

    // Toggle the boolean at the index of
    // the `newState` array
    newState[index] = !newState[index];

    // Set the state with the updated array
    setBoxes(newState);
  }

  // `filter` the boxes that return true.
  // Return true if the length is 0 or > 1.
  function isDisabled() {
    const len = boxes.filter(box => box).length;
    return len === 0 || len > 1;
  }

  return (
    <div className="App">
      <button disabled={isDisabled()}>Click Me</button>
      <form>
        <input type="checkbox" onChange={handleChange}/>
        <input type="checkbox" onChange={handleChange}/>
        <input type="checkbox" onChange={handleChange}/>
      </form>
    </div>
  );

}

ReactDOM.render(
  <Example />,
  document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Additional documentation

3 Comments

That worked like a charm but I have another challange. Actually my check boxes are inside table> tbody > tr > td (one checkbox in each tr >td) tag so picking parent will not work. somehow we need to count check boxes in table .
That probably merits a new question. You can link back to this answer though to help explain the issue.

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.