Change element with jquery

Asked

Viewed 737 times

1

Hello, I have a problem, in the code below I have a table of products, where they have a value (R$) and an input for the customer to choose a quantity. I need that when the customer changes the quantity, it is multiplied by the product value and is shown in the total value field (element in the page footer).

This function is already working, however, only for the first item of the list of products, that is, from the moment I change the quantity of the first item, it is multiplied by the value and the field total value is updated, but when the next amount is set the total value field is not updated.

I don’t know what’s wrong, in case anyone can help, I really appreciate it, follow code: To save page, I left out the header where I refer to JS files and other documents.

Table: Product Valor Amount

                <tr id="produto">
                    <td><?=$produto['nomeProduto'] ?></td>
                    <td><div id="valor"><?=$produto['valorProduto']?></div></td>
                    <td>
                        <input id="quantidade" type="number" size="1" maxlength="2" max="10" min="0" step="0">
                    </td>
                </tr>

                <?php
                     endforeach;
                ?>
            </table>                
    <footer>
        <nav class="navbar navbar-default navbar-fixed-bottom">
            <label> Total: </label>
            <div id="total" class="navbar-right">
              R$ 0,00
            </div>
        </nav>
    </footer>

Function:

    function dinheiroTextoParaFloat(text) {  //"Transofram" em float.
    var limpaTexto = text.replace("R$", "").replace(",", ".");
    return parseFloat(limpaTexto);
}

function floatParaDinheiroTexto(value) { //"Transforma" em texto.
    var text = (value < 1 ? "0" : "") + Math.floor(value * 100);
    text = "R$ " + text;
    return text.substr(0, text.length - 2) + "," + text.substr(-2);
}

function leTotal() {                      
    var total = $("#total").text();      //Le o texto do elemento com ID total.
    return dinheiroTextoParaFloat(total); //Retorna o texto convertido em float. 
}

function escreveTotal(value) {
    var text = floatParaDinheiroTexto(value); //Armazena na variavel text o valor convertido em texto.
    $("#total").text(text); //escreve o total no elemento com id total.
}   

function calculaTotalProdutos(){
    var produtos = $("#produto");
    var totalProdutos = 0;

    for (var cont = 0; cont < produtos.length; cont++){
        var $produto = $(produtos[cont]);
        var quantidade = dinheiroTextoParaFloat(
            $produto.find("#quantidade").val());
        var valor = dinheiroTextoParaFloat(
            $produto.find("#valor").text());
        var subtotal = quantidade * valor;
        totalProdutos += subtotal;
    } 

    return totalProdutos;
}

$(document).ready(function() {
    $("#quantidade").change(function() {
        escreveTotal(calculaTotalProdutos());
    });

2 answers

2


You are using the same ID id="quantidade" in various elements, Ids must be unique (not repeated). Change the element by removing the ID and placing a class, change the id="quantidade" for class="quantidade" and also in javascript change $("#quantidade") for $(".quantidade").

Example:

function total(valor){
$('span').text(valor);
}

$('.quantidade').change(function(){
    var valor = 0;
    $('.quantidade').each(function(index, element){
        if (element.value == undefined || element.value == '' || isNaN(element.value))
            element.value = 0;
        valor += parseInt(element.value);
    });
	total(valor);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>Quantidades:</p>

<p>
<input class="quantidade" type="number" size="1" maxlength="2" max="10" min="0" step="0">
    
<input class="quantidade" type="number" size="1" maxlength="2" max="10" min="0" step="0">
    
<input class="quantidade" type="number" size="1" maxlength="2" max="10" min="0" step="0">
</p>

<p>Total: <span></span></p>

  • Why not do the calculations in PHP and the returns in javascript, much more safe and practical.

  • @Ivanferrer in the case this is only for viewing the client (not worth a request ajax since it can be done in javascript) of course when calculating really to play in the database should be done in PHP (at least so hope he is doing).

  • 1

    Wow! I forgot the detail of ID AHAHAHAH I used the classes and it worked. Excuse the ignorance!!

  • @Fred this is perfectly normal, happens in the best families. : Q If the answer corrected the problem mark it as accepted, thus ending the question. Just click on the icon next to the answer (below the votes).

0

The problem is you’re repeating the id of the element within its foreach, only he doesn’t take everyone’s collection id=produto and not at all id=quantidade because the id attribute is only represented by a single element, however you can use the class attribute, this way it will consider everyone on the list as if it were a collection, in this sense you can implement it this way and see if it works:

However, before starting the foreach, start the incredulous $count=0;.

                <tr id="produto_<?=$count?>" class="lista_produtos">
                    <td><?=$produto['nomeProduto'] ?></td>
                    <td><div id="valor_<?=$count?>"><?=$produto['valorProduto']?></div></td>
                    <td>
                        <input id="quantidade_<?=$count?>" class="qtde" type="number" size="1" maxlength="2" max="10" min="0" step="0">
                    </td>
                </tr>
                <?php
                     $count++;
                     endforeach;
                ?>
            </table>                
    <footer>
        <nav class="navbar navbar-default navbar-fixed-bottom">
            <label> Total: </label>
            <div id="total" class="navbar-right">
              R$ 0,00
            </div>
        </nav>
    </footer>

And in javascript:

function calculaTotalProdutos(){
    var produtos = $(".lista_produtos");
    var totalProdutos = 0;

    for (var cont = 0; cont < produtos.length; cont++){
        var $produto = $(produtos[cont]);
        var quantidade = dinheiroTextoParaFloat(
            $produto.find("#quantidade_"+cont).val());
        var valor = dinheiroTextoParaFloat(
            $produto.find("#valor_"+cont).text());
        var subtotal = quantidade * valor;
        totalProdutos += subtotal;
    } 

    return totalProdutos;
}

But if you prefer, you can do it this way:

http://jsfiddle.net/ivanferrer/qpg5cy83/1/

Browser other questions tagged

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