Calculus response as NaN

0

I'm trying to get data from the database, for each input, to make calculations with each other in real time and give me a final value before registering the form.

I have a table and in that table, a part of tr is added dynamically. there is a select that, when selecting an item, pulls the value of that item in the database and shows the value, allowing the amount to be changed when choosing the quantity, this part is working.

What I could not do is get the result of the total value of the items, and decrease from another field that comes from the database with value of royallties for example. does the final result appear as NaN as if something in the code was not set as a number could help me?

var value = elemento.parentElement.parentElement.querySelector('td > input#valor_unitario').value; 
var valor = parseFloat(value.replace("R$","").replace(",","."));
var total = parseInt(qnt) * parseFloat(valor);

cell_total.value  = "R$ " + total.toFixed(2);

var total = parseFloat(value.replace("R$","").replace(",","."));
var royallties = parseFloat(value.replace(",",".").replace("","%"));
var valorroyallties = parseFloat(total) - ((parseFloat(total)* parseFloat(royallties))/100);
var valorfinal = parseFloat(total) - parseFloat(valorroyallties);

cell_valorfinal.value  = "R$ " + valorfinal.toFixed(2);
    
asked by anonymous 04.04.2017 / 17:24

4 answers

1

This code of your var valor = parseFloat(value.replace("R$","").replace(",",".")); gives you trouble when the user types $ 1,400.00 because it will turn your number into 1,400.00 that Javascript considers NaN.

A simple solution would be to remove all the characters from the value and turn the representation into pennies. I explain.

Instead of trying to save a float of $ 1400.00 at 1400.00, you could save an entire 140000, which represents the total in CENTS.

So, your code could look like the example below:

var value = elemento.parentElement.parentElement.querySelector('td > input#valor_unitario').value; 
var valor = parseInt(value.replace("R$","").replace(",","").replace(".","");
var total = qnt * valor; //Valor total em CENTAVOS

cell_total.value  = "R$ " + (total / 100); 

var total = parseInt(value.replace("R$","").replace(",","").replace(".",""));
var royallties = parseInt(value.replace(",","").replace(".","").replace("","%"));
var valorroyallties = total - ((total * royallties)/100); //Divido por 100 pois neste caso, é a porcentagem
var valorfinal = total - valorroyallties; //Valor em CENTAVOS

cell_valorfinal.value  = "R$ " + (valorfinal / 100); //valor em centavos retornando para decimal

Whenever possible, avoid using parseFloat because it can return decimals with an approximation that does not match the correct value.

    
04.04.2017 / 17:47
1

Great that you have already understood what NaN is, in short means that the variable is not a number.

The code has two errors: the first one is exactly in the part of the royallties. Note that you are using the same value variable (in this code snippet) in both total and royallties, I believe you are trying to get the royallties value of the wrong variable. The second error is found in its replace("","%")) which is inverted.

var total = parseFloat(value.replace("R$","").replace(",","."));

var royallties = parseFloat(value.replace(",",".").replace("","%"));

Following the example if we have

var value = "R$ 10,00";

when performing conversion

var total = parseFloat(value.replace("R$","").replace(",","."));

Gets a value of 10, however when running

var royallties = parseFloat(value.replace(",",".").replace("","%"));

If you use the variable value , which is "$ 10.00", not doing the expected operation, in case the replaces made generate the string "% R $ 10.00" which generates a NaN at the time of ParseFloat ("% R $ 10.00").

The correct would be to get a variable for example HTML royallties that had the following default "20.5%" and in that value you would execute the code correcting the replace ("%", ""));

var royalltiesConvertido = parseFloat(royallties.replace(",",".").replace("%",""));

Some ideas to avoid getting lost in the DOM fetch process and manipulating the values:

  • Separate the element search (QuerySelector Usage) from the manipulation.
  • Create semantic names (think about the contents of the variable, we can have a value that has a String and a value with the value already converted into float that helps when using variables.

Some ideas:

var valorString = elemento.parentElement.parentElement.querySelector('td > input#valor_unitario').value; 

var valorFloat = parseFloat(value.replace("R$","").replace(",","."));
    
04.04.2017 / 18:19
0

This part of the table where the whole field is that is repeated in another tr dynamically:

<tr class="linhas">
                <td colspan="4">
                    <select style="width:355px;" name="descricao[]" id="nome" onchange="listanome(this)">
                        <option value="">Selecione..</option>
                                    <?php
                                        include_once '../conexaobancodedados.php';

                                        $sql = "select * from  tabelapreco left outer join unidades on unidades.id_unidade = tabelapreco.id_unidade order by 'nome_tabela'";

                                        $result=  mysql_query($sql,$con);
                                        if(@mysql_num_rows($result)>0){

                                        while($row =  mysql_fetch_array($result)){

                                        ?>
                                        <option value="<?php echo $row["id_tabela"];?>"><?php echo $row["nome_tabela"];?> (<?php echo $row["nome_unidade"];?>)</option>

                                        <?php           
                                        }
                                        }else{
                                            ?>
                                            <option value="">Sem Cadastro de Equipamento</option>
                                            <?php 
                                        }

                                        ?>
                    </select>
                </td>
                <td><input type="number" value="1" min="1" style="width:50px;text-align: center;" size="1" name="qtd[]" id="qnt"></td>
                <td class="resultado2"><input size="10" readonly="true" style="background-color:#cccccc;color:black;"></td>
                <td><input type="text" size="10" name="valortotal[]" value="R$ 0.00" style="text-align: center;" id="total" onKeyPress="return(MascaraMoeda(this,'.',',',event))"></td>
                <td class="resultado3"><input size="10" readonly="true" style="background-color:#cccccc;color:black;"></td>
                <td class="resultado4"><input size="6" readonly="true" style="background-color:#cccccc;color:black;"></td>
                <td><input size="16" name="transporte[]" id="transporte" value="R$ 0.00" style="text-align: center;" onKeyPress="return(MascaraMoeda(this,'.',',',event))"></td>
                <td><input size="11" name="desconto[]" id="desconto" value="0.00 %" style="text-align: center;" onKeyPress="return(MascaraMoeda(this,'.',',',event))"></td>
                <td><input size="16" name="valorfinal[]" id="valorfinal" value="R$ 0.00" style="text-align: center;" onKeyPress="return(MascaraMoeda(this,'.',',',event))"></td>
                <td><a href="#" class="removerCampo" title="Remover linha"><input type="button" name="Excluir" style="width:70px;background-color:red;"></a></td>
            </tr>
            </tbody>
            <tfoot>
                <tr>
                       <td colspan="13">
            <center><a href="#" class="adicionarCampo" title="Adicionar item"><input type="button" name="adicionar" value="Adicionar"></a></center>
                       </td>
                </tr>

            </tfoot>

and this part the scritps that add dynamically and that does the search in the database of the items and their values and also the calculation:

<script type="text/javascript">
    function listanome(elemento){

        var nome       = elemento.value;
        var cell_valor = elemento.parentElement.parentElement.querySelector('.resultado2');
        var cell_total = elemento.parentElement.parentElement.querySelector('td > input#total');
        var cell_valorfinal = elemento.parentElement.parentElement.querySelector('td > input#valorfinal');
        var cell_royallties = elemento.parentElement.parentElement.querySelector('.resultado3');
        var qnt = elemento.parentElement.parentElement.querySelector('td > input#qnt').value;
        qnt = (qnt != '')? parseInt(qnt): 0;

        var nome = elemento.value;
        var cell = elemento.parentElement.nextElementSibling.nextElementSibling;

        var nome2 = elemento.value;
        var cell2 = elemento.parentElement.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling;

        var nome3 = elemento.value;
        var cell3 = elemento.parentElement.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling;

        $(document).on('change', 'input#qnt', function(){
            var qnt        = $(this).val();
            qnt        = (qnt != '')? parseInt(qnt): 0;

            var valor      = $(this).parents('td').siblings().children('input#valor_unitario').val();
            valor      = parseFloat(valor.replace("R$","").replace(",","."));

            var royallties = $(this).parents('td').siblings().children('input#royallties').val();
            royallties      = parseFloat(royallties.replace(",",".").replace("","%"));

            var cell_total = $(this).parents('td').siblings().children('input#total');
            var total      = (qnt * valor);
            var valorroyallties = total - ((total * royallties)/100);

            var cell_valorfinal = $(this).parents('td').siblings().children('input#valorfinal');
            var valorfinal = total - valorroyallties;

            cell_total.val("R$ " + total.toFixed(2).replace(".",","));
            cell_valorfinal.val("R$ " + valorfinal.toFixed(2).replace(".",","))
        });



         if(nome != ''){
              var dados = {
                listanome : nome
              }
              $.post('../BUSCAR_BANCO/busca_preco.php', dados, function(retorna){
                cell_valor.innerHTML = retorna;
                var value = elemento.parentElement.parentElement.querySelector('td > input#valor_unitario').value; 
                var valor = parseFloat(value.replace("R$","").replace(",","."));

                var total = parseInt(qnt) * parseFloat(valor);

                cell_total.value  = "R$ " + total.toFixed(2);


              });
            }else{
              alert("Sem Equipamento Selecionado");    
            }

        if(nome2 != ''){
                    var dados2 = {
                        listanome2 : nome2
                    }
                    $.post('../BUSCAR_BANCO/busca_royallties.php', dados2, function(retorna){
                        cell2.innerHTML = retorna;
                        var value = elemento.parentElement.parentElement.querySelector('td > input#valor_unitario').value; 
                        var total = parseFloat(value.replace("R$","").replace(",","."));
                        var royallties = parseFloat(value.replace(",",".").replace("","%"));
                         var valorroyallties = parseFloat(total) - ((parseFloat(total)* parseFloat(royallties))/100);
                         var valorfinal = parseFloat(total) - parseFloat(valorroyallties);
                         cell_valorfinal.value  = "R$ " + valorfinal.toFixed(2);

                    });
        }else{
        alert("Sem Equipamento Selecionado");    
        }

        if(nome3 != ''){
                    var dados3 = {
                        listanome3 : nome3
                    }
                    $.post('../BUSCAR_BANCO/busca_imposto.php', dados3, function(retorna){
                        cell3.innerHTML = retorna;
                    });
        }else{
        alert("Sem Equipamento Selecionado");    
        }



    }
    </script>
    
04.04.2017 / 18:06
0

I changed leaving td direct showing values in Reals, I was able to play the value of the royallties and the value of the tax on top of the final value, and how do I get the value of the transport and discount to be typed and tb play on top of the value Last? can you help me?

SCRIPT:

<script type="text/javascript">
        $(function () {
          function removeCampo() {
                $(".removerCampo").unbind("click");
                $(".removerCampo").bind("click", function () {
                   if($("tr.linhas").length > 1){
                        $(this).parent().parent().remove();
                   }
                });
          }

            $(".adicionarCampo").click(function () {
                novoCampo = $("tr.linhas:first").clone();
                novoCampo.find("input").val("");
                novoCampo.find("input#qnt").val('1');
                novoCampo.find("input#total").val('R$ 0.00');
                novoCampo.find("input#royallties").val('R$ 0.00');
                novoCampo.find("input#imposto").val('R$ 0.00');
                novoCampo.find("input#transporte").val('R$ 0.00');
                novoCampo.find("input#desconto").val('R$ 0.00');
                novoCampo.find("input#valorfinal").val('R$ 0.00');
                novoCampo.insertAfter("tr.linhas:last");
                removeCampo();
          });
        });
    </script>

<script type="text/javascript">
    function listanome(elemento){

        var nome       = elemento.value;
        var cell_valor = elemento.parentElement.parentElement.querySelector('.resultado2');
        var cell_total = elemento.parentElement.parentElement.querySelector('td > input#total');
        var cell_royallties = elemento.parentElement.parentElement.querySelector('td > input#royallties');
        var cell_imposto = elemento.parentElement.parentElement.querySelector('td > input#imposto');
        var cell_valorfinal = elemento.parentElement.parentElement.querySelector('td > input#valorfinal');
        var qnt = elemento.parentElement.parentElement.querySelector('td > input#qnt').value;
        qnt = (qnt != '')? parseInt(qnt): 0;

        var nome = elemento.value;
        var cell = elemento.parentElement.nextElementSibling.nextElementSibling;

        $(document).on('change', 'input#qnt', function(){
            var qnt        = $(this).val();
            qnt        = (qnt != '')? parseInt(qnt): 0;

            var valor      = $(this).parents('td').siblings().children('input#valor_unitario').val();
            valor      = parseFloat(valor.replace("R$","").replace(",","."));

            var cell_total = $(this).parents('td').siblings().children('input#total');
            var total      = (qnt * valor);

            var cell_royallties = $(this).parents('td').siblings().children('input#royallties');
            var royallties     = (total * 11.62)/100;

            var cell_imposto = $(this).parents('td').siblings().children('input#imposto');
            var imposto     = (total * 4.65)/100;

            var cell_valorfinal = $(this).parents('td').siblings().children('input#valorfinal');
            var valorfinal = total + royallties + imposto;

            cell_total.val("R$ " + total.toFixed(2).replace(".",","));
            cell_royallties.val("R$ " + royallties.toFixed(2).replace(".",","));
            cell_imposto.val("R$ " + imposto.toFixed(2).replace(".",","));
            cell_valorfinal.val("R$ " + valorfinal.toFixed(2).replace(".",","));

        });



         if(nome != ''){
              var dados = {
                listanome : nome
              }
              $.post('../BUSCAR_BANCO/busca_preco.php', dados, function(retorna){
                cell_valor.innerHTML = retorna;
                var value = elemento.parentElement.parentElement.querySelector('td > input#valor_unitario').value; 
                var valor = parseFloat(value.replace("R$","").replace(",",".")); 
                var total = parseInt(qnt) * parseFloat(valor);

                var royallties = (parseFloat(total) * 11.62)/100;
                var imposto = (parseFloat(total) * 4.65)/100;
                var valorfinal = parseFloat(total) + parseFloat(royallties) + parseFloat(imposto);

                cell_total.value  = "R$ " + total.toFixed(2);
                cell_royallties.value = "R$ " + royallties.toFixed(2);
                cell_imposto.value = "R$ " + imposto.toFixed(2);
                cell_valorfinal.value  = "R$ " + valorfinal.toFixed(2);
              });
            }else{
              alert("Sem Equipamento Selecionado");    
            }

    }
    </script>

HTML HTML TR:

<tr class="linhas">
                <td colspan="4">
                    <select style="width:355px;" name="descricao[]" id="nome" onchange="listanome(this)">
                        <option value="">Selecione..</option>
                                    <?php
                                        include_once '../conexaobancodedados.php';

                                        $sql = "select * from  tabelapreco left outer join unidades on unidades.id_unidade = tabelapreco.id_unidade order by 'nome_tabela'";

                                        $result=  mysql_query($sql,$con);
                                        if(@mysql_num_rows($result)>0){

                                        while($row =  mysql_fetch_array($result)){

                                        ?>
                                        <option value="<?php echo $row["id_tabela"];?>"><?php echo $row["nome_tabela"];?> (<?php echo $row["nome_unidade"];?>)</option>

                                        <?php           
                                        }
                                        }else{
                                            ?>
                                            <option value="">Sem Cadastro de Equipamento</option>
                                            <?php 
                                        }

                                        ?>
                    </select>
                </td>
                <td><input type="number" value="1" min="1" style="width:50px;text-align: center;" size="1" name="qtd[]" id="qnt"></td>
                <td class="resultado2"><input size="10" value="R$ 0.00" readonly="true" style="text-align: center;background-color:#cccccc;color:black;"></td>
                <td><input type="text" size="10" name="valortotal[]" readonly="true" value="R$ 0.00" style="background-color:blue;color:white;text-align: center;" id="total" onKeyPress="return(MascaraMoeda(this,'.',',',event))"></td>
                <td><input type="text" size="10" name="royallties[]" id="royallties" value="R$ 0.00" onKeyPress="return(MascaraMoeda(this,'.',',',event))" readonly="true" style="background-color:#cccccc;color:black;text-align: center;"></td>
                <td><input type="text" size="6" name="imposto[]" id="imposto" value="R$ 0.00" onKeyPress="return(MascaraMoeda(this,'.',',',event))" readonly="true" style="background-color:#cccccc;color:black;text-align: center;"></td>
                <td><input size="16" name="transporte[]" id="transporte" value="R$ 0.00" style="text-align: center;" onKeyPress="return(MascaraMoeda(this,'.',',',event))"></td>
                <td><input size="11" name="desconto[]" id="desconto" value="R$ 0.00" style="text-align: center;" onKeyPress="return(MascaraMoeda(this,'.',',',event))"></td>
                <td><input size="16" name="valorfinal[]" id="valorfinal" value="R$ 0.00" style="background-color:blue;color:white;text-align: center;" onKeyPress="return(MascaraMoeda(this,'.',',',event))"></td>
                <td><a href="#" class="removerCampo" title="Remover linha"><input type="button" name="Excluir" style="width:70px;background-color:red;"></a></td>
            </tr>
            </tbody>
            <tfoot>
                <tr>
                       <td colspan="13">
            <center><a href="#" class="adicionarCampo" title="Adicionar item"><input type="button" name="adicionar" value="Adicionar"></a></center>
                       </td>
                </tr>

            </tfoot>
    
05.04.2017 / 21:27