Search code examples
reactjstypescriptreact-typescript

How to handle multiple checkboxes in React?


I am new to react. I have got a task to:

  • Display multiple checkboxes.
  • Checkboxes names can be shuffled in the future. (Client can decide which checkbox value to be displayed at the top and so on).
  • Display checkboxes based on order no.
  • There will be a submit button below the checkbox which will be disabled on load. Force the user to tick all the check boxes only then the button should be enabled.
  • On click of save button, send the data to backend. (For the time being I will log to console).

I am using react with typescript.
I have attached a snapshot for reference. Multiple checboxes example
So far I have done this:

import React, { useState } from "react";

interface Data {
  name: string;
  order: number;
}

const MyCheckBoxList: Data[] = [
  {
    order: 0,
    name: "Angular",
  },
  {
    order: 1,
    name: "React",
  },
  {
    order: 2,
    name: "Java",
  },
];

const MultipleCheckBoxComponent = () => {
  const [checked, setChecked] = useState(false);

  return (
    <div>
      <h3>Multiple checbox </h3> <br />
      <ul>
        {MyCheckBoxList.map(({ name, order }, index) => {
          return (
            <li key={index}>
              <div>
                <div>
                  <input
                    type="checkbox"
                    id={`custom-checkbox-${index}`}
                    name={name}
                    value={name}
                  />
                </div>
              </div>
            </li>
          );
        })}
      </ul>
      <button type="submit">Save</button>
    </div>
  );
};

export default MultipleCheckBoxComponent;

Can anybody tell me:
How do I display the check boxes based on order number (as I have mentioned in point 3) and how to achieve point 4?(the button should enable only when all the checkboxes are tick)

Solution

  • You can sort your data based on your requirements while setting to state, i.e as a default value for the state.

    const [data, setData] = useState(
      MyCheckBoxList.sort((a, b) => a.order - b.order)
    );
    

    You need to validate each and every checkbox value and then only you can enable your button. For you have to store the value of each and every item. For that, you can create a simple component that can render your check box, and there you can update the checkbox value along with the main data.

    Finally, validate your updated data so that you can enable your submit button or not.

    const isVerified = useMemo(() => {
        return data.every((d) => d.checked);
    }, [data]);
    
    return (
        <div className="App">
            {data.map((obj, index) => (
            <li key={index}>
                <Checkbox
                obj={obj}
                onChange={(item) => {
                    setData(data.map((d) => (d.order === item.order ? item : d)));
                }}
                />
            </li>
        ))}
    </div>)
    

    And this is my checkbox component.

    const Checkbox = ({ obj, onChange }) => {
      return (
        <>
          <input
            type="checkbox"
            id={`custom-checkbox-${obj.index}`}
            name={obj.name}
            value={obj.checked}
            onChange={() => onChange({ ...obj, checked: !obj.checked })}
          />
          {obj.name}
        </>
      );
    };
    
    

    Attaching the sandbox link so that you can update your logic based on that.

    Edit dreamy-curran-4qggdc