Adrian
Adrian

Reputation: 86

Changing checkbox value on button click - react

How to change checkbox value not only by clicking on that checkbox input but on the whole button that wraps input and span?

    const statuses = ["Draft", "Pending", "Paid"];

     const [checkedState, setCheckedState] = useState(
     new Array(statuses.length).fill(false)
    );

     const handleCheckboxChange = (position: number) => {
       const updatedCheckedState = checkedState.map((item, index) =>
         index === position ? !item : item
       );
       setCheckedState(updatedCheckedState);
     };

        {statuses.map((status, index) => (
              <button key={index}>
                <input
                  type="checkbox"
                  onChange={() => handleCheckboxChange(index)}
                />
                <span>{status}</span>
              </button>
            ))}

Upvotes: 1

Views: 1960

Answers (2)

Robin
Robin

Reputation: 5427

Move your handleCheckboxChange function to the button and use checked property to input for handling check-uncheck dynamically. As you see, in the checked property I give the value dynamically like this checked={checkedState[index]}.

import { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  const statuses = ["Draft", "Pending", "Paid"];

  const [checkedState, setCheckedState] = useState(
    new Array(statuses.length).fill(false)
  );

  const handleCheckboxChange = (position) => {
    const updatedCheckedState = checkedState.map((item, index) =>
      index === position ? !item : item
    );
    setCheckedState(updatedCheckedState);
  };

  return (
    <>
      {statuses.map((status, index) => (
        <button key={index} onClick={() => handleCheckboxChange(index)}>
          <input type="checkbox" checked={checkedState[index]} />
          <span>{status}</span>
        </button>
      ))}
    </>
  );
}

And another way is - just use label instead of button. In this case you need to give proper styles to the label.

  return (
    <>
      {statuses.map((status, index) => (
        <label key={index}>
          <input
            type="checkbox"
            onChange={() => handleCheckboxChange(index)}
            checked={checkedState[index]}
          />
          <span>{status}</span>
        </label>
      ))}
    </>
  );

Upvotes: 3

irous
irous

Reputation: 489

You can just put the handler on the button instead of the input checkbox.
The reason is event in javascript will go from outer tag to inner tag. If you click on a button the event will fired in button before fired in button's children.
For details, see event bubbling and capturing

<button key={index} onClick={() => handleCheckboxChange(index)}>
                <input
                  type="checkbox"
                  //onChange={() => handleCheckboxChange(index)}
                  checked={checkedState[index]} 
                />
                <span>{status}</span>
              </button>

Upvotes: 0

Related Questions