Check active React checkbox

Asked

Viewed 99 times

0

Hello, I need to check if one or more checkboxes are or are marked, to submit the form. The form can only be submitted if one or more checkboxes are checked(s).

Follows my code:

import React, { useEffect, useState } from 'react'

import Button from '../../components/button/Button'
import './Professor.css'

const professores = [
  {
    id: 1,
    nome: 'Marco Castro',
  },
  {
    id: 2,
    nome: 'Maike Brito',
  },
  {
    id: 3,
    nome: 'Loiane Groner',
  },
  {
    id: 4,
    nome: 'Vinicius Dacal',
  },
  {
    id: 5,
    nome: 'Leonardo Moura',
  },
]

const turmas = [
  {
    id: 1,
    turma: 'Matutino',
  },
  {
    id: 2,
    turma: 'Vespertino',
  },
  {
    id: 3,
    turma: 'Noturno',
  },
]

function Professor() {
  const [infoProf, setInfoProf] = useState('')
  const [infoTurma, setInfoTurma] = useState({})
  const [values, setValues] = useState([])

  function handleSubmit(event) {
    event.preventDefault()

    if (!infoProf.trim()) {
      return alert('Obrigatório a escolha de um professor!')
    }

    // const teste = values.map((item) => item.turma)

    console.log(infoTurma)
    setValues([...values, { nome: infoProf, turma: infoTurma }])

    clearChange()
  }

  function clearChange() {
    setInfoProf('')
    setInfoTurma('')
  }

  return (
    <div className="form-professor">
      <h1>Cadastro de Professores</h1>
      <form onSubmit={handleSubmit}>
        <label htmlFor="" className="label-professor">
          Professor
        </label>
        <select
          className="select-professor"
          value={infoProf}
          onChange={(e) => setInfoProf(e.target.value)}
          data-testid="select-professor"
        >
          <option value="0">Selecione um Professor</option>
          {professores.map((professor) => (
            <option
              value={professor.nome}
              key={professor.id}
              data-testid="option-professor"
            >
              {professor.nome}
            </option>
          ))}
        </select>
        <div className="check-grup">
          <h2>Slecione quais Turmas</h2>
          {turmas.map((item) => (
            <div
              className="checkbox-professor"
              key={item.id}
              data-testid="checkbox_id"
            >
              <input
                name={item.turma}
                id={item.turma}
                type="checkbox"
                checked={infoTurma[item.turma] || false}
                onChange={(e) =>
                  setInfoTurma({
                    ...infoTurma,
                    [e.target.name]: e.target.checked,
                  })
                }
              />
              <label htmlFor={item.turma}>{item.turma}</label>
            </div>
          ))}
        </div>

        <Button text="Enviar" />
      </form>

      <div className="list-containerProfessor">
        <ul className="list-cardsProfessor">
          {values.map((item, index) => (
            <li key={index} data-testid="todo-listProfessor">
              <div className="list-turmaProfessor">
                <p>{item.nome}</p>
                <p>{Object.keys(item.turma).join(', ')}</p>
              </div>
            </li>
          ))}
        </ul>
      </div>
    </div>
  )
}

export default Professor
  • saw the answer worked out for you?

1 answer

0


Had some errors and data disconnected between the base information with those that were in the form and this is bad because, the data to be sent is different from the natural state of the component.

A second state was created to store the chosen classes, which in the method onChange of those checkbox have to check if it is addition or removal and with that if the quantity is greater than zero you can submit this form.

Another observation when passing the information of a state needs to use a new copy (for being a array which is a type by reference) not to be deleted immediately after its addition in the state values.

The example below demonstrates this:

const professores = [
  {
    id: 1,
    nome: 'Marco Castro',
  },
  {
    id: 2,
    nome: 'Maike Brito',
  },
  {
    id: 3,
    nome: 'Loiane Groner',
  },
  {
    id: 4,
    nome: 'Vinicius Dacal',
  },
  {
    id: 5,
    nome: 'Leonardo Moura',
  },
]

const turmas = [
  {
    id: 1,
    turma: 'Matutino',
  },
  {
    id: 2,
    turma: 'Vespertino',
  },
  {
    id: 3,
    turma: 'Noturno',
  },
]

function Professor() {
  const [infoProf, setInfoProf] = React.useState('');
  const [infoTurma, setInfoTurma] = React.useState([]);
  const [values, setValues] = React.useState([]);  
  function handleSubmit(event) {
    event.preventDefault()
    if (!infoProf.trim()) {
      alert('Obrigatório a escolha de um professor!');
      return;
    }    
    if (infoTurma.length === 0) {
      alert('Obrigatório a escolha da turmas!');
      return;
    }
    setValues([...values, { nome: infoProf, turma: [...infoTurma ]}]);
    clearChange()
  }

  function clearChange() {
    setInfoProf('')
    setInfoTurma([])
  }

  return (
    <div className="form-professor">
      <h1>Cadastro de Professores</h1>
      <form onSubmit={handleSubmit}>
        <label htmlFor="" className="label-professor">
          Professor
        </label>
        <select
          className="select-professor"
          value={infoProf}
          onChange={(e) => setInfoProf(e.target.value)}
          data-testid="select-professor"
        >
          <option value="0">Selecione um Professor</option>
          {professores.map((professor) => (
            <option
              value={professor.nome}
              key={professor.id}
              data-testid="option-professor"
            >
              {professor.nome}
            </option>
          ))}
        </select>
        <div className="check-grup">
          <h2>Selecione quais Turmas</h2>
          {turmas.map((item) => (
            <div
              className="checkbox-professor"
              key={item.id}
              data-testid="checkbox_id"
            >
              <input
                name={item.turma}
                id={item.turma}
                type="checkbox"
                checked={infoTurma.includes(item.turma)}
                onChange={(e) => {
                  if (e.target.checked) { // add
                    setInfoTurma([
                      ...infoTurma,
                      e.target.name
                    ]);
                  } else { // delete
                    setInfoTurma(
                      infoTurma.filter(x => 
                        x !== e.target.name                      
                      )
                    )
                  }                  
                }}
              />
              <label htmlFor={item.turma}>{item.turma}</label>
            </div>
          ))}
        </div>

        <button>Enviar</button>
      </form>

      <div className="list-containerProfessor">
        <ul className="list-cardsProfessor">
          {values.map((item, index) => (
            <li key={index} data-testid="todo-listProfessor">
              <div className="list-turmaProfessor">
                <p>{item.nome}</p>
                <p>{Object.keys(item.turma).join(', ')}</p>
              </div>
            </li>
          ))}
        </ul>
      </div>
    </div>
  )
}

ReactDOM.render( <Professor/> , document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<div id="root">...</div>

  • Thank you @novic, it worked out here. Vlw even, hugs;

  • if useful, check as answer! @Emersonmoreira

Browser other questions tagged

You are not signed in. Login or sign up in order to post.