RJL
RJL

Reputation: 37

Check if all checkboxes are checked and console.log("all checked") Javascript/React

The following component is meant to be a To-Do list. I got multiple checkboxes. As soon as all checkboxes are checked, a console.log("all checked") should appear.

My idea is to check if the todo.lengh === checked.length, but it doesn't work.

Problem: trying to console.log(checked.length) doesn't work either so there must be the problem.

Can someone help me how to reach the checked.length?

import React from 'react';
import { AiOutlinePlusCircle } from 'react-icons/ai';
import { useState } from 'react';

function Checkboxes() {
  const [todo, setToDo] = React.useState('');
  const [todos, setToDos] = React.useState([]);
  const [checked, setChecked] = useState(false);

  function handleToDoSubmit(e) {
    e.preventDefault();

    const newToDo = {
      id: new Date().getTime(),
      text: todo,
      completed: false,
    };

    setToDos([...todos].concat(newToDo));
    setToDo('');
  }

  function toggleCompleteToDo(id) {
    const updatedToDos = [...todos].map((todo) => {
      if (todo.id === id) {
        todo.completed = !todo.completed;
      }
      return todo;
    });
    setToDos(updatedToDos);
  }

  function allChecked(checked) {
    if (todo.length === checked.length) {
      console.log('all checked');
    }
  }

  return (
    <div className="ToDoList">
      <form className="goalInputToDo" onSubmit={handleToDoSubmit}>
        <input
          className="goalInput"
          type="text"
          onChange={(e) => setToDo(e.target.value)}
          value={todo}
        />
        <button className="AddGoalBtn" type="submit">
          .
          <AiOutlinePlusCircle size="2em" />
        </button>
      </form>

      {todos.map((todo) => (
        <div className="goalItem">
          <div key={todo.id}>
            <div>{todo.text}</div>
            <input
              type="checkbox"
              onChange={() => {
                toggleCompleteToDo(todo.id), allChecked(todo.checked);
              }}
              checked={todo.completed}
            />
          </div>
        </div>
      ))}
    </div>
  );
}
export default Checkboxes;

Upvotes: 1

Views: 2751

Answers (1)

Zsolt Meszaros
Zsolt Meszaros

Reputation: 23161

todo is a string, checked is a boolean, so I'm not sure how you wanted to use them to check if all the checkboxes are checked. What you could do instead is to check your todos array and check if every single item's completed prop is true.

You can use Array#every() to do this. It tests whether all elements in the array pass the test implemented by the provided function:

function allChecked() {
  return todos.every(item => item.completed)
}

function App() {
  const [todo, setToDo] = React.useState('');
  const [todos, setToDos] = React.useState([{
    id: new Date().getTime(),
    text: 'First item',
    completed: false,
  }]);

  function handleToDoSubmit(e) {
    e.preventDefault();

    const newToDo = {
      id: new Date().getTime(),
      text: todo,
      completed: false,
    };

    setToDos(todos.concat(newToDo));
    setToDo('');
  }

  function toggleCompleteToDo(id) {
    const updatedToDos = todos.map((item) => {
      if (item.id === id) {
        item.completed = !item.completed;
      }
      return item;
    });
    setToDos(updatedToDos);
  }

  function allChecked() {
    if (!todos.length) return false;
    return todos.every((item) => item.completed);
  }

  return (
    <div className="ToDoList">
      <form className="goalInputToDo" onSubmit={handleToDoSubmit}>
        <input
          className="goalInput"
          type="text"
          onChange={(e) => setToDo(e.target.value)}
          value={todo}
        />
        <button className="AddGoalBtn" type="submit">
          Add
        </button>
      </form>

      {todos.map((item) => (
        <div className="goalItem">
          <div key={item.id}>
            <input
              type="checkbox"
              onChange={() => {
                toggleCompleteToDo(item.id), allChecked(item.checked);
              }}
              checked={item.completed}
            />
            <span>{item.text}</span>
          </div>
        </div>
      ))}
      <p>All checked: {allChecked() ? 'Yes' : 'No'}</p>
    </div>
  );
}


ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
<div id="root"></div>
<script src="https://unpkg.com/react/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script>

Upvotes: 1

Related Questions