Help to capture change in checkbox field

Asked

Viewed 68 times

0

I have the following code that searches the product and creates the row in the table the way I want and then stores the data in a Json to be sent by post.

It only works when I input a new product. But I needed to store Json whenever I check a checkbox I create with jquery. But I’m not finding the command that I do it. I’ve tried every kind of command. Even test the console to show a message when I click on the checkbox, but it shows no message. Can anyone help me on how to capture the change in the checkbox?

have tried $( "input[type=checkbox]" ).on( "click", armazenarCampos); But does not update.

Follows the code that generates the table:

var codigo = $("#codigo_barras");
codigo.on("keydown",function(e){
      if(e.which == 13) {
          e.preventDefault();
          $.get("controle/pedido-troca-pendente-busca-produto.php?codigo="+codigo.val(),geraLinha);
      }
});

function geraLinha(data){
  var produto = jQuery.parseJSON(data);
  if(produto.id_produto!=0){
      var linha  = $("<tr>").addClass("linha");
      var colunaProduto = $("<td>").text(produto.produto);
      var colunaTamanho = $("<td>").text(produto.tamanho);
      var colunaPreco = $("<td>").text(produto.preco);
      var colunaUsuario = $("<td>").text(produto.usuario);
      var colunaDefeito = $("<td>");
      var colunaRemove = $("<td>");

      var campoIdProduto = $("<input>").addClass("id_produto").attr("type","hidden").attr("value",produto.id_produto);
      var campoTamanho = $("<input>").addClass("tamanho").attr("type","hidden").attr("value",produto.tamanho);
      var campoPreco = $("<input>").addClass("preco").attr("type","hidden").attr("value",produto.preco);
      var campoTipoCobranca =$("<input>").addClass("tipo_cobranca").attr("type","hidden").attr("value",produto.tipo_cobranca);
      var campoIdTabela = $("<input>").addClass("id_tabela").attr("type","hidden").attr("value",produto.id_tabela);
      var campoDefeito = $("<input>").addClass("defeito").attr("type","checkbox").attr("value","true");

      var link = $("<a>").addClass("botao-remover").addClass("btn").addClass("btn-danger").addClass("glyphicon").addClass("glyphicon-trash").attr("href","#");

      colunaDefeito.append(campoDefeito);
      colunaRemove.append(link);

      linha.append(colunaProduto);
      linha.append(colunaTamanho);
      linha.append(colunaPreco);
      linha.append(colunaUsuario);
      linha.append(colunaDefeito);
      linha.append(colunaRemove);

      linha.append(campoIdProduto);
      linha.append(campoTamanho);
      linha.append(campoPreco);
      linha.append(campoTipoCobranca);
      linha.append(campoIdTabela);

      $("#troca-pendente").append(linha);
      codigo.val("");

  }else{
    $("#erro").toggle();
    setTimeout(function(){
        $("#erro").toggle();
    },2000);
  }

  armazenarCampos();
}

function armazenarCampos() {
    if($('.linha').length>0){
    var produtos = [];

        $('.linha').each(function(){
            var id_produto = $(this).find(".id_produto").val();
            var tamanho = $(this).find(".tamanho").val();
            var preco = $(this).find(".preco").val();
            var tipo_cobranca = $(this).find(".tipo_cobranca").val();
            var id_tabela = $(this).find(".id_tabela").val();
            if($(this).find("input:checked").val()){
              var defeito = 1;
            }else{
              var defeito = 0;
            }

            var produto = {
              id_produto:id_produto,
              tamanho:tamanho,
              preco:preco,
              tipo_cobranca:tipo_cobranca,
              id_tabela:id_tabela,
              defeito:defeito
            };
          produtos.push(produto);
        });

        $("#produtos-troca").attr("name","produtos-troca").attr("value",JSON.stringify(produtos));
    }
}

jquery generated html:

<tbody id="troca-pendente">
    <tr class="linha">
        <td>165 Caramelo</td>
        <td>34</td>
        <td>39.90</td>
        <td>Admin</td>
        <td><input class="defeito" type="checkbox" value="true"></td>
        <td><a class="botao-remover btn btn-danger glyphicon glyphicon- 
            trash" href="#"></a></td>
        <input class="id_produto" type="hidden" value="7">
        <input class="tamanho" type="hidden" value="34"><input class="preco" 
               type="hidden" value="39.90">
        <input class="tipo_cobranca" type="hidden" value="1">
        <input class="id_tabela" type="hidden" value="3">
    </tr>
    <tr class="linha">
         <td>01 Preto</td>
         <td>38</td>
         <td>39.90</td>
         <td>Admin</td>
         <td><input class="defeito" type="checkbox" value="true"></td>
         <td><a class="botao-remover btn btn-danger glyphicon glyphicon- 
             trash" href="#"></a></td>
         <input class="id_produto" type="hidden" value="8">
         <input class="tamanho" type="hidden" value="38">
         <input class="preco" type="hidden" value="39.90">
         <input class="tipo_cobranca" type="hidden" value="1">
         <input class="id_tabela" type="hidden" value="3">
      </tr>
  </tbody>
  • create a class in the checkbox to access for $('. sua_class') and then use the $change event ('. sua_class'). on('change', Function(){...});

  • $('.'default'). on('change',Function(){ console.log("clicked"); }); and does not work. Shows nothing in log

  • gave the log doing this?

  • Shows nothing. Does it have to do with being inside a <td>?

  • Got it, you’re creating the dynamite checkbox. So you have to link the event to the checkbox after creating it. So try $('. defect'). bind('change', Function (){...});

  • I attached the html generated in the post. Even the bind did not work

  • you are setting the event after the inputs are created?

  • I don’t know if I understood your question, but I put $( "input[type=checkbox]" ).on( "click", Function()? console.log("entered");} ); at the end of the jquery code

  • Solved with the answer below.

Show 4 more comments

1 answer

1


How you are generating the checkboxes dynamically, when you run $("input[type=checkbox]").on( "click", armazenarCampos) they don’t exist yet.

Then you’ll be listening to the event click only of input[type=checkbox] that are already on the screen, and not of those that will exist in the future.

To work with events in dynamic elements there is a technique called Event Delegation, which I explain in more depth in the question: Difference between click, bind, live, delegate, Trigger and on functions'?.

To use jQuery event delegation just use the method jQuery.on() making Handler of events stay in a parent element, which is already in HTML, listen to events of the child elements.

In your case you can use:

$("#troca-pendente").on("click", ".defeito", armazenarCampos);
// ^ Elemento pai                 ^ Target do evento

Example without delegation:

let template = `
<label>
    <input type="checkbox"> Checkbox dinâmico
</label>
`;

$('#add').on('click', function() {
    $(document.body).append(template);
});

// Handler de eventos no próprio input
$('input').on('change', function() {
    $(this).closest('label').toggleClass('active', this.checked);
});
label {
    display: block;
}

label.active {
    color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button id='add'>Add</button>
<label>
    <input type="checkbox"> Checkbox já existente
</label>


Example with delegation:

let template = `
<label>
    <input type="checkbox"> Checkbox dinâmico
</label>
`;

$('#add').on('click', function() {
    $(document.body).append(template);
});

// Handler de eventos em um elemento pai (delegação de eventos)
$('body').on('change', 'input', function() {
    $(this).closest('label').toggleClass('active', this.checked);
});
label {
    display: block;
}

label.active {
    color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button id='add'>Add</button>
<label>
    <input type="checkbox"> Checkbox já existente
</label>

  • Got it. So while I’m dynamically assembling the table and I’d already have to put the event in the checkbox. I did so: line.find(".defect"). click(store Fields); inside the generate functionLine() and it worked now. Thank you

  • On the contrary, that would not be performative. You would have to use event delegation, that way an element would have the event Handler for all checkboxes that are on the screen and the future.

  • Have you tried $("#troca-pendente").on("click", ".defeito", armazenarCampos); as I put it in the reply?

  • It worked out just like you said with this command. Sorry about the flushing. I think I’ll have to study a little more Jquery and css selectors. Because I needed to resolve this urgent. Thanks for the willingness, it helped a lot. Hug.

  • Read my explanation about delegation events that I wrote in the reply. There it is very detailed for you to understand.

Browser other questions tagged

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