How to add and search BD products with JSON in HTML dynamic fields?

Asked

Viewed 1,185 times

3

Personal I cannot get values from performing research with JSON and database after adding new dynamic product line with Javascript.

HTML form, the product is searched by code:

<form id="adicionarformProdutos" method"post" action"" enctype="multipart/form-data">
     <a href="#" id="adicionarProduto">Adicionar Faixa</a>      
    <fieldset class="fieldsetProduto">
        <legend>Produto 1</legend>
        <div class="produtos">
            <label for="codProduto1">Código:</label><input type="text" id="codProduto1" size="5" name="codProduto[1]" />
            <label for="nomeProduto1">Nome:</label> <input type="text" id="nomeProduto1" size="9" disabled name="nomeProduto[1]" />
            <label for="qtProduto1">Qt.:</label> <input type="number" min="1" max="999" size="1" id="qtProduto1" name="qtProduto[1]" onblur="calcValor()" />
            <label for="valorProduto1">Valor und. R$:</label> <input type="text" id="valorProduto1" disabled name="valorProduto[1]" size="6" onkeypress="mascara(this,float)" />
        </div>
     </fieldset>
</form>

JSON section that searches the products and fills the other variables:

//-----------------------------------------------------
//Funcao: functionjson
//Autor: Rafael Assmann <[email protected]>
//Sinopse: Json para capturar código do produto e reali
//zar a busca no banco de dados e preencher os demais campos deste produto
//Parametro:
//   codProduto[] : código do produto digitado para pesquisa
//Retorno: nomeProduto[], qtProduto[] e valorProduto[] : informações do BD
//-----------------------------------------------------
$(document).ready(function(){
    $("input[name='codProduto[1]']").blur(function(){
         var nomeProduto = $("input[name='nomeProduto[1]']");
         var qtProduto = $("input[name='qtProduto[1]']");
         var valorProduto = $("input[name='valorProduto[1]']");

         $( nomeProduto ).val('Carregando...');
         $( qtProduto ).val('Carregando...');
         $( valorProduto ).val('Carregando...');

             $.getJSON(
                 'function.php',
                 { codProduto: $( this ).val() },
                 function( json ) 
                 {
                      $( nomeProduto ).val( json.nomeProduto );
                      $( qtProduto ).val("1");
                      $( valorProduto ).val( json.valorProduto);
                 }
             );
     });
});

Excerpt where you add more products, than where JSON interaction does not work:

$(function () {
    var i = 1;
    $("#adicionarProduto").click(function () {
        i++;
        novoProduto = $(".fieldsetProduto:first").clone();
        novoProduto.find("input").each(function () {
            $(this).val("")
        });

        $("#adicionarformProdutos").append("
        " + novoProduto.html().replace(/1/g, i) + "")
    });
});

Insert in the database, OBS: the variables that are fed by JSON seem to be empty:

<?php
$Ficha = filter_input(INPUT_GET,'id');
?>

<div id="painelcadastro2" align="center">
<?php   if (isset($_GET['cadastra']) && $_GET['cadastra'] == 'add') {
  $datacompra = implode("-", array_reverse(explode("/",$_GET['datacompra'])));
  $nomeProduto = filter_input(INPUT_GET, 'nomeProduto1');
  $qtProduto = filter_input(INPUT_GET, 'qtProduto1');
  $valorProduto = filter_input(INPUT_GET, 'valorProduto1');
  $parcelas = filter_input(INPUT_GET, 'select_parcelas');
  $entrada = filter_input(INPUT_GET, 'entrada');
  $total = filter_input(INPUT_GET, 'total');
  $pagamento = "CREDIARIO";
  $cadastra = mysql_query("INSERT INTO t_cadcontratos (Ficha, DataContrato, QuantParcelas, ValorContrato, Entrada, Saldo, DescricaoProduto, QuantProdutos, FormaPagamento) 
                          VALUES ('$Ficha', '$datacompra', '$parcelas', '$valorProduto', '$entrada', '$total', '$nomeProduto', '$qtProduto', '$pagamento')");
  if($cadastra == '1') {
        echo "Venda Crediário realizada com sucesso !";
  }else{
        echo "Erro ao realizar a venda Crediário, tente novamente !";
  }
}
?>

Function.php

<?php
/**
 * função que devolve em formato JSON os dados do cliente
 */
function retorna( $nome, $db )
{
    $sql = "SELECT `identProduto`, `codProduto`, `qtProduto`, `nomeProduto`, `valorProduto` FROM `t_estoque` WHERE `codProduto` = '{$nome}' ";

         $query = $db->query( $sql );

         $arr = Array();
         if( $query->num_rows )
         {
             while( $dados = $query->fetch_object() )
             {
                 $arr['nomeProduto'] = $dados->nomeProduto;
                 $arr['qtProduto'] = $dados->qtProduto;
                 $arr['valorProduto'] = $dados->valorProduto;
             }
         }else{
             $arr['nomeProduto'] = 'produto não encontrado';
         }
         if($arr['qtProduto'] == 0)
            $arr['nomeProduto'] = 'sem estoque';

         return json_encode( $arr );
    }

/* só se for enviado o parâmetro, que devolve os dados */
if( isset($_GET['codProduto']) )
{
    $db = new mysqli('localhost', 'root', '', 'buchm613_buchmann');
    echo retorna( filter ( $_GET['codProduto'] ), $db );
}

function filter( $var ){
    return $var;//a implementação desta, fica a cargo do leitor
}

How can I proceed to fill in the dynamically added fields via the Javascript section above?

  • I edited the question to improve the indentation of the last code - which was difficult to read - but I kept the undue line break inside the string, not to change the original code. Is your code right? If so, there was no build error in Javascript?

  • 1

    By the way, that line $("#adicionarformProdutos").append("" + novoProduto.html().replace(/1/g, i) + "") - even corrected - improperly alters various properties of your code, such as the attribute min. Behold that example, each time a new product is added its minimum quantity is equal to the product index (i.e. product 4 has minimum quantity 4, 5 has minimum quantity 5, etc).

  • Understood the minimum quantity part, thank you mgibsonbr, I will check a solution for this but my problem this when I add new product indexes, my json just doesn’t work, I know I name different inputs when I add but I don’t know the correct treatment in the JSON section to perform the BD search, have any idea?

  • Yes, I’m writing an answer now, soon I post.

  • ok! for now I just changed the input number to text by how much of the minimum quantity, I don’t have to use the type number at this time, I await return!

  • hello @mgibsonbr in this example of jsFiddle that mentioned below to add fields (tracks) know me how to remove them?

  • What I usually do is put next to the created element a link or button to remove it, and a function click which - by having a reference to the element - can simply call novoElemento.detach() (or remove). But in your case, with all these numerical codes that increase with each cloning, it gets a little more complicated... Unfortunately, I have nothing to suggest about. :(

Show 2 more comments

2 answers

3

I suggest a new approach as @mgibsonbr referred to the way it’s going to change properties you don’t want.

Create a function that returns the clone with the right product number.

Something like:

function novoProduto(nr){
    var html = '<fieldset class="fieldsetProduto">' +
        '<legend>Produto ' + nr + '</legend>' +
        '<div class="produtos">' +
        '<label for="codProduto' + nr + '">Código:</label><input type="text" id="codProduto' + nr + '" size="5" name="codProduto[' + nr + ']" />' +
        '<label for="nomeProduto' + nr + '">Nome:</label> <input type="text" id="nomeProduto' + nr + '" size="9" dis' + nr + 'bled name="nomeProduto[' + nr + ']" />' +
        '<label for="qtProduto' + nr + '">Qt.:</label> <input type="number" min="1" max="999" size="1" id="qtProduto1" name="qtProduto[' + nr + ']" onblur="calcValor()" />' +
        '<label for="valorProduto' + nr + '">Valor und. R$:</label> <input type="text" id="valorProduto' + nr + '" disabled name="valorProduto[' + nr + ']" size="6" onkeypress="mascara(this float)" />' +
        '</div>' +
        '</fieldset>';
    return html;
}

There whenever you want a new element you just have to do novoProduto(i).

Another suggestion related to code maintenance is: instead of using $("input[name='codProduto[1]']").blur(function(){ etc... that will force you to have a similar code for each new product, I suggest to use so:

function carregarJSON() {
    var index = this.id.slice(-1);
    var self = this;
    var nomeProduto = $("input[name='nomeProduto[" + index + "]']");
    var qtProduto = $("input[name='qtProduto[" + index + "]']");
    var valorProduto = $("input[name='valorProduto[" + index + "]']");

    $(nomeProduto).val('Carregando...');
    $(qtProduto).val('Carregando...');
    $(valorProduto).val('Carregando...');

    $.getJSON(
        'function.php', {
        codProduto: self.value
    },

    function (json) {
        $(nomeProduto).val(json.nomeProduto);
        $(qtProduto).val(nr);
        $(valorProduto).val(json.valorProduto);
    });
}

$(document).ready(function () {
    $(document).on("blur", "input[name^='codProduto[']", carregarJSON);
});

Notice also that I removed the this within the $getJSON. If I’m not mistaken the thisthere not tip more for your input but yes for the jquery function.

And by the way, optimization suggestion here too:

$(function () {
    var i = 1;
    $("#adicionarProduto").click(function () {
        i++;
        $("#adicionarformProdutos").append(novoProduto(i))
    });
});

If you keep the code you have here, I don’t think you need the .each(). Suffice:

novoProduto.find("input").val("") //não precisa do .each() aqui
  • 1

    +1 for the excellent refactoring suggestion, but I’m afraid that doesn’t solve the AP problem - note that the blur is only added to the elements that are already on the page, not on those that are dynamically added.

  • @mgibsonbr truth. I forgot this detail, I will correct. I saw now your answer too. ++

  • 1

    Fixed , I used delegation for these inputs: $(document).on("blur", "input[name^='codProduto[']", carregarJSON);

3


Your code $("input[name='codProduto[1]']").blur(...) only assigns a Handler pro event blur of the elements that are already on the page from the beginning - that is, the first product. If you want to do this for a new product, I suggest using the method on (or live, if it is a very old version of jQuery).

First, add a class to your input to facilitate your selection (for some reason I don’t know, the selector .produtos > input:first is not working as I expected):

<input class="codigoProduto" type="text" id="codProduto1" size="5" name="codProduto[1]" />

Second, when you clone don’t just take the elemento.html (that would be the innerHTML). Instead, update the HTML and then add the element itself (taking care not to overwrite too much, as pointed out in the comments, but here I will ignore it):

//$("#adicionarformProdutos").append("" + novoProduto.html().replace(/1/g, i) + "")
novoProduto.html(novoProduto.html().replace(/1/g, i));
$("#adicionarformProdutos").append(novoProduto)

Third, use the on:

$(document).on("blur", ".codigoProduto", function(){

Finally, select the right elements to update - not just the first:

 var parent = $(this).parent();
 var nomeProduto = parent.children("input:eq(1)");
 var qtProduto = parent.children("input:eq(2)");
 var valorProduto = parent.children("input:eq(3)");

Example in jsFiddle. I would also like to mention that it is not necessary to use the operator $ again in $( nomeProduto ), etc, because they are already jQuery objects. But also does not disturb...

  • Very good @mgibsonbr, thank you! but the moment I change for "$(Document). on("Blur", ". codigoProduct", Function(){" can no longer search products, I use Jquery as follows: "<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>"

  • @Rafaelassmann O on is only available from jQuery 1.7. If you can’t update your jQuery. try replacing the call from on for $(document).delegate(".codigoProduto", "blur", function() { and see if it resolves. There is also the live, but if the delegate work is better this way.

  • It worked yes, I was trying with . delegate but the parameters in the wrong orders, all right now @mgibsonbr thank you so much again! if it is possible to pay attention to this other question http://answall.com/questions/35489/como-trata-select-por-id-de-clientes-entre-duas-p%C3%A1ginas-php/35494#35494 ++

  • @Rafaelassmann Sorry, I understand jQuery but I don’t know anything about PHP... Anyway, it seems to me that the answer you already received there is on the right track: if page A sent to page B, you need to preserve the contents of A somehow. Repeating them in a Hidden input in B is a means; placing them in a cookie is another. The details (and security) of each alternative will depend on your particular case.

  • perfect, I’ll follow in this line, again thank you!

  • guy went to write in the database the values captured in JSON and the inputs seem to be empty, I added the snippet where I do the Insert in the database!

  • @Rafaelassmann id of the input that is sent in a POST, and yes the name (I even thought that was the reason for these "crazy" names that you were putting - codProduto[1] etc). Also, if you are submitting the form via POST you have to search for the variables in $_POST, not in the $_GET. I think (again, I don’t know PHP, but I’ve seen some code around) that with names you are using you will receive on your server something like an array called codProduto, another called nomeProduto, etc..

  • P.S. If the problem persists, I suggest opening another question to it, before it becomes one "chameleon question"... :)

  • tranquil @mgibsonbr your comment gave me an idea and it worked all, hug!

  • Back to JSON, when I do research and the product is not found my html fields still remain written "Loading...", I made a treatment in the file Function.php but I could not solve, can you help me? I added Function.php to the question.

Show 5 more comments

Browser other questions tagged

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