Executando verificação de segurança...
1

Validação de campos com javascript (dúvida)

Preciso de ajudar para resolver um problema de validação. A situação é o seguinte:

Tenho 'N' linhas contendo cada uma, um checkbox e um campo numérico logo ao lado. Porém, o campo numérico por padrão vem como 'disabled', pois ele só será ativado para inserção de dados caso o checkbox ao lado seja ativado. (interação essa que já fiz utilizando o código abaixo)

const checkboxesColuna1 = document.querySelectorAll('.checkbox-coluna-1');

checkboxesColuna1.forEach(checkbox => {
  checkbox.addEventListener('click', () => {
    const checkboxCorrespondente = checkbox.parentNode.parentNode.querySelector('.checkbox-coluna-2');
    console.log(checkboxCorrespondente);
    if (checkbox.checked) { 
      checkboxCorrespondente.disabled = false;
    }else{
      checkboxCorrespondente.disabled = true;
    }
  });
});

Porém, agora eu preciso validar quando os campos numéricos estiverem ativos se a soma dos valores que foram colocado neles resulta em 100. ou seja, se eu tenho dois campos numéricos ativados, um com 60 e outro com 40 de valor colocado, o usuário vai conseguir enviar o formulário, caso a soma não resulte em 100 (ex: 30 e 20), não será possível enviar o formulário.

OBS: São 'N' linhas, pois essas linhas estão vindo do banco. logo, não é um valor fixo.

Carregando publicação patrocinada...
2

Para situações como essa, porque gastar neurônios e tempo se você tem a IA. Segue a resposta do ChatGPT para você :

Coloquei exatamente sua dúvida integral e ele me retornou:

Para resolver o problema de validação, você pode adicionar um evento de escuta para detectar quando um dos campos numéricos é preenchido ou alterado. Quando isso acontecer, você pode percorrer todos os campos numéricos ativados e somar seus valores. Se a soma for igual a 100, permita que o usuário envie o formulário. Caso contrário, exiba uma mensagem de erro informando que a soma dos valores deve ser igual a 100.

Aqui está um exemplo de como você pode fazer isso:

Adicione uma classe aos campos numéricos para facilitar a seleção:

<input type="checkbox" class="checkbox-coluna-1">
<input type="number" class="campo-numerico coluna-2" disabled>

Adicione um evento de escuta para detectar quando um campo numérico é preenchido ou alterado:

const camposNumericos = document.querySelectorAll('.campo-numerico');

camposNumericos.forEach(campo => {
  campo.addEventListener('change', () => {
    const camposAtivados = document.querySelectorAll('.campo-numerico:not([disabled])');
    let soma = 0;
    camposAtivados.forEach(campoAtivado => {
      soma += parseInt(campoAtivado.value);
    });
    if (soma !== 100) {
      alert('A soma dos valores deve ser igual a 100');
      // ou exiba a mensagem de erro em algum elemento na página
    }
  });
});

O código acima seleciona todos os campos numéricos e adiciona um evento de escuta para detectar quando um deles é preenchido ou alterado. Em seguida, ele seleciona todos os campos numéricos ativados (aqueles que não estão desabilitados) e soma seus valores. Se a soma for diferente de 100, exibe uma mensagem de erro. Se a soma for igual a 100, o usuário pode enviar o formulário.


Do mais acho que a explicações ficou clara, não ?
Ele adicionou um listener no evento de click de cada checkbox, contando o total adicionado.
Com esse valor em mãos ele controlou quando chegou a 100 ;)

Por fim acho que uma solução total seria :

const checkboxesColuna1 = document.querySelectorAll('.checkbox-coluna-1');
const camposNumericos = document.querySelectorAll('.campo-numerico');

checkboxesColuna1.forEach(checkbox => {
  checkbox.addEventListener('click', () => {
    const checkboxCorrespondente = checkbox.parentNode.parentNode.querySelector('.checkbox-coluna-2');
    console.log(checkboxCorrespondente);
    if (checkbox.checked) { 
      checkboxCorrespondente.disabled = false;
    } else {
      checkboxCorrespondente.disabled = true;
      checkboxCorrespondente.value = ""; //limpa o campo quando o checkbox é desmarcado
      validarSomaCampos();
    }
  });
});

camposNumericos.forEach(campo => {
  campo.addEventListener('change', () => {
    validarSomaCampos();
  });
});

function validarSomaCampos() {
  const camposAtivados = document.querySelectorAll('.campo-numerico:not([disabled])');
  let soma = 0;
  camposAtivados.forEach(campoAtivado => {
    soma += parseInt(campoAtivado.value) || 0; // trata valores vazios ou inválidos como zero
  });
  if (soma !== 100) {
    alert('A soma dos valores deve ser igual a 100');
    // ou exiba a mensagem de erro em algum elemento na página
  }
}

Ou algo mais charmoso :

const checkboxesColuna1 = document.querySelectorAll('.checkbox-coluna-1');

function updateCheckbox() {
  const checkboxCorrespondente = this.parentNode.parentNode.querySelector('.checkbox-coluna-2');
  checkboxCorrespondente.disabled = !this.checked;
}

function validateForm() {
  const checkboxes = document.querySelectorAll('.checkbox-coluna-2:checked');
  const total = Array.from(checkboxes).reduce((acc, curr) => acc + Number(curr.value), 0);
  return total === 100;
}

checkboxesColuna1.forEach(checkbox => {
  checkbox.addEventListener('click', updateCheckbox);
});

const form = document.querySelector('form');
form.addEventListener('submit', e => {
  if (!validateForm()) {
    e.preventDefault();
    alert('A soma dos valores deve ser igual a 100.');
  }
});

Acho que é isso. IA a favor do dev !!!

1

Cara, que massa. Devo confessar que as vezes me esquece que IAs como ChatGPT e atéo próprio github Copilot são tão poderosas.

O Código funcionou como esperado. Porém só um adendo. Esse código do jeito que está aí ele mostra um alert para o usuário dizendo que a soma tem que ser igual a 100. Ok. Porém, o usuário ainda pode enviar o formulário depois de fechar o pop-up de alert. But, resolvi isso colocando que caso a condição não seja atendida, o botão de envio seja desativado. Aí sim fica show de bola.

Mas muito massa essa sua ajuda e acho que vou começar a usar mais as IAs. kkkkk ><

1

rsrs isso ai Ramon. Fiz questão de te responder justamente para demonstrar que sua solução estava a poucos cliques rs. Se for utilizada corretamente pode gerar otimos benefícios e ganho de produtividade. Ela não é o ser supremo e infalível mas dá uma boa ajuda se soubermos utilizar rs. Fico feliz que tenha dado certo por ai.

Qualquer me chama lá no Linkedin. Tmj !

Grande abraço !