jQuery – Calcular produtos/valores do formulário

  • Autor do post:
  • Categoria do post:PHP DEV

jQuery – Calcular  produtos/valores do formulário

Vamos ver um exemplo simples de como calcular automaticamente o valor total dos itens em um formulário.
A idéia: O cálculo é realizado em tempo real conforme o usuário informa a quantidade de determinados itens, cada item/produto terá o valor em um índice do array no PHP.
Em princípio, o array possui valores fixos, no entanto, partimos da idéia de que esse array seja resultante de uma consulta no banco.

Utilizaremos jQuery e PHP para realizar o cálculo.

Vamos começar pelo bom e velho HTML contendo o formulário com os supostos códigos dos produtos.

<form name="produto" id="produto">
<label>Produto 1:</label>
<input type="text" name="produto_1" id="produto_1" />

<label>Produto 2:</label>
<input type="text" name="produto_2" id="produto_2" />

<label>Produto 3:</label>
<input type="text" name="produto_3" id="produto_3" />

<label>Produto 4:</label>
<input type="text" name="produto_4" id="produto_4" />

<label>Produto 5:</label>
<input type="text" name="produto_5" id="produto_5" />

<label>Produto N:</label>
<input type="text" name="produto_n" id="produto_n" />

<label>Valor Total:</label>
<span id="total"></span>
<input type="hidden" name="total_compra" id="total_compra" />
</form>

Perceba que o elementos possuem NAME e ID com os supostos nomes ou códigos dos produtos, o negócio está aí!
Os nomes utilizados em name e id devem corresponder aos indíces do array que veremos a seguir.
Temos também um campo hidden que armazena o valor total para utilizarmos ao submetermos o formulário.

Vamos ver agora como monitorar os campos com o método .bind() do jQuery e enviar ao PHP os valores contidos em cada campo do formulário.
Chamei o arquivo Javascript de calculo.js, vejamos:

$(document).ready(function(){
// monitorando o evento change dos campos
$('#produto input').bind('change',function(){
// enviando os valores atuais dos campos ao PHP
$.post('calculo.php',{
// serializando o formulario
dataForm: $("#produto").serialize()
},
function(data){
// obtendo o retorno do PHP / atualizando o valor
$('#total').html(data)
// informando o total ao campo hidden
// sera utilizado ao submeter o form
$('#total_compra').val(data)
})
})

// realiza o calculo no inicio ou após um refresh
$.post('calculo.php',{
dataForm: $("#produto").serialize()
},
function(data){
$('#total').html(data)
$('#total_compra').val(data)
})
})

Acredito que os comentários no código bastam, mas…

O evento $(document).ready(function(){ //code }) é como o velho window.onload, ou seja, irá realizar os precidementos contidos dentro do block ao carregar o documento.
Dentro desse bloco nós utilizamos o $(‘#produto input’).bind(‘change’,function(){ //code }) para monitorar o evento change dos campos, ou seja, a cada vez que o campo tiver seu valor alterado as ações contidas no monitoramente serão realizadas, nesse caso a ação é realizada por:
$.post(‘calculo.php’,{//post vars },function(data){ //code })

Esse cara, o $.post é quem envia por post os dados para o PHP, passamos à ele a var dataForm contendo os dados serializados do formulário através de $(“#produto”).serialize(), esse pega todos os valores dos campos existentes no formulário de ID produto e serializa passando à var dataForm que por sua vez é enviada ao PHP.
Sei que ficou um pouco redundante mas as vezes a redundancia fixa o raciocínio (nem acredito que eu disse isso, mas também olha a hora).

Após enviar os dados via post o retorno é armazenado na var data que está em function(data) e esse valor nada mais é que o cálculo dos campos retornados do PHP, apenas isso.

E porque aparecem 2 vezes o bloco abaixo?

$.post('calculo.php',{
dataForm: $("#produto").serialize()},
function(data){
$('#total').html(data)
$('#total_compra').val(data)
})

Eu explico, claro!

Acontece que o primeiro bloco está dentro do .bind() e irá acontecer apenas se algum campo tiver seu valor alterado.
O segundo ocorre na inicialização para realizar o primeiro cálculo que retornará 0(zero), mas isso também está aí porque se o usuário der um refresh na tela depois de ter alterado algum campo o valor que aparece no total irá desaparecer, isso porque o valor está em um elemento span, no entanto o mesmo valor está contido em um campo oculto, campo do tipo hidden que deve ser utilizado para recuperar o valor total dos itens ao submetermos o formulário.

Quando ocorre o $(‘#total’).html(data) o valor está sendo passado ao elemento span apenas para visualização do usuário, não poderia ser um campo input text para que o usuário não alterasse o valor total.  :0

No entanto, após setar o valor do elemento span é chamado também o $(‘#total_compra’).val(data) que guarda o valor no campo oculto.

Tá legal, vamos ver como o cálculo realmente é feito, até agora só vimos como enviar e recuperar o valor mas como é realizada a soma, ainda não.
E chegou a vez do PHP mostrar sua arte também, ué!

Chamei o arquivo PHP de calculo.php


<?php
// Indices e valores dos produtos
$valor = array(
'produto_1' => 20,
'produto_2' => 10.50,
'produto_3' => 15,
'produto_4' => 30,
'produto_5' => 20,
'produto_n' => 2.50
);
// valor total inicial = 0
$total = 0;
// passando os dados do form para um array
$params = array();
parse_str($_POST['dataForm'], $params);
// calculando o valor dos produtos e somando ao total
foreach($params as $item => $value)
{
if(isset($valor[$item]) && !empty($item))
$total += $valor[$item] * $value;
}
// retornando o total calculado e formatado BRL
echo number_format($total,2, ',', '.');
?>

Como está comentado no código, o array de nome $valor contém em seus índices os códigos dos itens (que devem ser iguais ao do formulário para que ocorra o cálculo correto) e também os valores dos mesmos.
Seria assim:
o produto_1 custa 20 rúpias.

Importante: os valores devem ser separados por ponto(.) e não vírgula(,) para que o cálculo ocorre corretamente, não se esqueça disso para não ficar sofrendo aí.
obs: E eu escrevo como se alguém fosse utilizar mesmo o código kas kas kas kas.

Enfim,

A linha parse_str($_POST[‘dataForm’], $params); passa para um array os valores recebidos do jQuery através do dataForm: $(“#produto”).serialize(), lembra né? blz!
Após passar para o array $params realizamos a verificação if(isset($valor[$item]) && !empty($item)), ou seja, verificamos se existe no array $valor o índice contido em $params.
No foreach nos percorremos todos os índices de $params que nada mais é que os campos do form e verificamos se existe aquele índice no array $valor.
Para fixar a idéia:
$param são os campos do formulário e $valor é o array que contém os índices de mesmo nome que os campos do form, então:
$params[‘produto_1’] = valor[‘produto_1’]

E a partir disso vamos somando/multiplicando ao $total como a linha:
$total += $valor[$item] * $value;

Essa linha diz o seguinte:
$total += $valor[‘produto_1’] * $quantidade_digitada_no_produto_1

O echo retorna o jQuery o total calculado, no jQuery é retornado esse valor em function(data), lembra né? blz!
Obs: o valor só atualizado quando o campo é alterado e isso implica em você “sair” daquele campo, mudar de o focu do cursor!

Bom, fica aí a demo para você curtir: demo   |  fontes

Links:
jQuery $.post
PHP  parse_str
PHP numer_format

Abraços e até logo++,

Este post tem 54 comentários

  1. Vagner Guedes

    Seria de grande proveito, se eu soubesse php, hahahah, eh nois irmao.

    1. Rafael Clares

      Hahaha é só trocar o calculo.php por calculo.aspx só tem 4 linhas mesmo hehehehe.
      Abs irmão, até mais.

  2. Darlan

    Me diz uma coisa se eu tiver um formulario maior, onde eu some várias linhas, eu mudo a quantidade de arrays?
    Eu sou noob em php e estou apanhando justamente nisso

    1. Rafael Clares

      Darlan, exatamente isso!
      Se você adicionar no formulario o produto_x você precisa adicionar no array.
      Ex:

      No array:

      ‘produto_x’ => 10.50

      Em outra oportunidade farei esse exemplo com BD ao invés de Array.

      Abs

    1. Rafael Clares

      Rapaz, a resposta é a mesma!
      Sim o script faz isso, você precisa adicionar mais indices no array (nomes e valores).
      Os indíces devem possuir os nomes dos campos do formulário, como no exemplo do post.

  3. Darlan

    Vlw, vc é fera mesmo, eu vou tentar aqui e postarei o resultado, vou deixar de ser um noob hehehehe, muito o brigado mesmo por responder

  4. luiz

    Se eu quiser que o usuário mesmo digite o valor do produto como que faço?

    1. Rafael Clares

      Terá que adicionar o campo valor e receber esse valor do campo no array onde originalmente estão os valores.
      Você terá que criar um array a partir dos campos com os valores dos produtos.;

      array ( ‘produto_1_valor’ => $_POST[‘produto_1_valor’])

      supondo que produto_1_valor é o campo que adicionou no formulário para inserção do valor e o array criado no local do array que contém os preços fixos.

  5. Helder Smith

    E no caso de funcionar como select ao invés do input, como seria? Por exemplo eu vi que passar os dados pelo input, só que eu precisaria jogar por seleção no caso de vários produtos, tentei mudar a parte input por select mais não tive resultado. Eu vi que funciona bem até com o radiobuton, mais o selection tem ao invés de input option e aí não adiciona o valor. Agradeço por uma sugestão e parabéns pelo script. meu email: [email protected]

    1. Rafael Clares

      Helder, nesse caso você pode criar o select normalmente, acontece que o nome/id do select deve estar contido também no calculo.php que possui os nomes dos campos!

      1. Helder Smith

        Olá Rafel obrigado pela resposta amigo, mais me perdi aqui porque por exemplo, estou usando está função não para contar por quantidade e sim por produto.

        Neste caso meu código ficou assim.

        http://vargasinformatica.com.br/monte-seu-pc/ Está sem layout sem nada só para amostra. Só que por exemplo isso é para amostra em um pc e não acesso a todos na net. Só que com o select ficaria menor a página devido a quantidade de produto a escolher.

        No meu caso ficou assim.

        $valor = array(
        ‘Monitor_20_sansung’ => 650.00,
        ‘Monitor_18_sansung’ => 590.00,
        ‘Monitor_15_sansung’ => 520.00,
        ‘Processador_intel_dual_core’ => 325.00,
        ‘Processador_intel_quad_core’ => 420.00,
        ‘Impressora_hp_multfuncional_fax’ => 350.00
        );

        Só que com o select que eu usei assim.

        Escolha o Monitor
        Monitor Sansung 20″
        Monitor Sansung 18″
        Monitor Sansung 15″

        Ele não contabiliza. O que vi é que ele pega tudo que vem do input, só que não consegui pelo select.

        Eu coloquei o nome e id do select como produto que é o mesmo nome do form. Só que não entendi a parte de incluir no array acima, como ficaria, poderia me mandar pelo menos uma amostra, usando os dados acima.

        Fico grato pela ajuda.

        Att

        Helder Smith

      2. Helder Smith

        01 = O select não pegou aqui, estou tentando colocar novamente:

        02 =
        03 = Escolha o Monitor
        04 = Monitor Sansung 20″
        06 = Monitor Sansung 18″
        08 = Monitor Sansung 15″
        10 =

        vamos ver se agora aparece.

        aguardo…

      3. Helder Smith

        Acho que só tirando algumas tags, apague os comentários que não deram certo o select por favor.

        select name=”produto” class=”VariationSelect” id=”produto” style=”width: 246;height:22″
        option value=””>Escolha o MonitorMonitor Sansung 20″Monitor Sansung 18″Monitor Sansung 15″</option
        select

        1. Rafael Clares

          Então cara, mas se você não setar os “value” do option não vai aparecer nada mesmo mesmo
          option value=”produto X”
          option value=”produto Y”

          Testa ai com value no option pra ver

  6. Helder Smith

    Gostaria de Agradecer ao grande amigo Rafael Clares, pela ajuda na modificação do script em questão. Parabéns pelo blog. Continue assim. Obrigado mesmo.

  7. Aline

    Olá Rafael gostei de seus posts.. sou um pouco leiga no assunto estou aprendendo agora… adorei esse exemplo.. mais estou com a mesma dúvida do colega acima.. o usuário deverá digitar o preço do produto, no caso é somente um produto .. só que não estou conseguindo “pegar” o valor digitado pelo usuário =/..
    Veja meu código

    Quantidade de Plantas:

    Valor Muda (Unidade):

    …..

    calculo.php

    $preco = $_POST[‘preco’]; //o post não tem nadaa =/

    $valor = array(
    ‘quantidade’ => $preco,

    );

    Obrigada

    1. Rafael Clares

      Aline, me mande o código em [email protected] para eu ver como está.
      Tente explicar no e-mail o que deveria acontencer.
      Ah, não respondo dúvidas por email, nem os abro. Apenas envie o código para eu ver ok
      Até logo,

  8. Aline

    Rafael obrigada pela ajuda.. Já mandei o código modificado no seu email…

    de como “deveria acontecer”.

    O raciocínio é simples mais não consigo fazer…

    No seu exemplo definimos o preço do produto no próprio código.

    Ex: ‘produto_1’ => 3, (três seria o valor que vou atribuir ao preço do produto_1)

    Gostaria de ao invés de atribuir um valor fixo para o produto_1 que eu atribuísse o valor digitado pelo usuário na na input preco.

    Obrigada pela ajuda!

  9. Aline

    Rafael era exatamente isso!
    Obrigada pela ajuda! TCC salvo por você nos 45 min do segundo tempo!
    =)

  10. metropoledigitalon

    opa amigo tudo bem? como seria para pegar estes valores escolhidos e somados pelo usuário para um email?

    desde já agradeço…flw

    1. Rafael Clares

      Olá, de uma procurada no blog por “enviar email” ok ;

      1. Helder Smith

        Amigo Rafael, gostaria de saber se é possível fazer multiplicação ao invés de soma, por exemplo. Tenho uma lista de produtos com determinados preços, preciso que faça a multiplicação do valor do produto x a quantidade x porcentagem = valor total . Acha qe é possível isso com php. Se sim sabe me dá uma dica. Grato

        1. Rafael Clares

          Helder, mas é isso que o sistema faz, você precisa mudar alguns parâmetros no calculo.php para ficar de acordo com o que você deseja mas no geral ele multiplica a quantidade de produtos x preço;
          O que acontece é que após multiplicar quantidade x preço ele efetua também a somatória no final; Dê uma olhada com calma que irá entender!

  11. leomuniz1

    Cara, me desculpe, sou um bocado leigo no assunto.
    Gostaria de saber como enviar as quantidades de cada produto, e a soma total por e-mail. Olhei lá o tópico enviando e-mail, mas não entendi como fazer a junção de um com o outro. Pode me ajudar?

    1. Rafael Clares

      Leo, infelizmente é preciso ter algum conhecimento em PHP para unir os scripts.

  12. thiagonzo

    Gostei muito do script. Tava tendo dificuldades para fazer isso com input. Tem como acrescentar um campo de desconto. Ele pegaria o valor total e calcularia o desconto e mostraria em outro campo. O valor do desconto eu seleciono num select ou digito num input? Como poderia fazer isso?

    1. Rafael Clares

      Thiago, tem que adicionar o campo e alterar o calcular.php para receber os valores do campo desconto e efetuar o cálculo, é matemática básica né ?
      Você adicionar um campo com um valor que será descontado do valor total, não tem muita coisa particular da linguagem de programação, são as 4 operações básicas da matemática, não tem como errar.

  13. Angolfur Lems

    Primeiramente Rafael, parabéns pelo post!
    Agradeço alguma ajuda que puderes fazer sobre a dúvida que tenho, bem diversa, é que me deparei com a seguinte situação:
    A partir de seu exemplo e de outros, criei um programa que efetua um cálculo fatorial e outro que calcula Baskara.
    Ambas funcionam e retornam os valores esperados. Mas tive uma idéia, criei uma outra aplicação, uma listview, chamando estas duas aplicações.
    Ambas carregam normalmente, voltam para a tela inicial clicando no botão back, mas não calculam… 🙁
    Das duas uma, ou falta algo ou fiz algo errado no programa da listview.
    Obrigado, um abraço!

    1. Rafael Clares

      Fala velho, cara desculpe a demora em responder..tá corrido aqui. Cara tem como você colocar o código no pastebin e postar aqui o link para eu ver como está?
      Só imaginando pela sua descrição não consigo te ajudar, preciso ver algo;
      Abs

  14. Joao Roberto Velozo

    Meu amigo tudo bem? fiz todo o procedimento inclusive o download do código mas não funciona, tem algum banco de dados ou coisa parecida??? abraços [email protected]

    1. Rafael Clares

      João, “não funciona” é muito genérico, assim não consigo te ajudar!
      Tente me dizer o que ocorre, se aparece algum erro (ver erros no console de erros firefox ou chrome shift+ctrl+j);

  15. Joao Roberto Velozo

    XMLHttpRequest cannot load file:///C:/Users/Jo%C3%A3oVelozo/Downloads/form_calc%20(1)/myFormCalc/calculo.php. Origin null is not allowed by Access-Control-Allow-Origin.

    1. Rafael Clares

      Nossa…. sério que está chamando um arquivo nesse caminho? numa pasta com (1) e tudo mais? Rapaz, começou mal viu.
      Cara, primeira coisa de tudo, crie seus sites, sistemas e coisas, em pastas sem espaços, acentos, estrelas, etc…
      Exemplo:
      joaovelozo/
      – calculo.php
      Começa novamente com um caminho de arquivo mais curto.
      Sei que minha pergunta pode parecer estúpida mas eu tenho que perguntar, você está usando um servidor web ou está apenas abrindo o arquivo baixado diretamente no browser?

  16. Marcelo

    Olá Rafael, preciso implementar uma ferramenta semelhante no formulário de pedido do meu site. Gostaria de saber se vc faz o trabalho. Em caso positivo, por favor entre em contato. grato.

    1. Rafael Clares

      Marcelo, faço sim, é claro!
      Pode me enviar os detalhes em [email protected], fico no aguardo!
      Abraço,

  17. Rafael Dering

    Excelente, me ajudou bastante para poder desenvolver o calculo de conversão.
    Obrigado.

  18. André

    Prezado
    E como seria se estes resultados viessem do banco de dados? Esta lista para array()

    1. Rafael Clares

      Desculpe a demora em responder, estive ausente por algum tempo.
      André, os dados vindos do banco podem ser convertidos em array. Basta que os campos tenha os nomes(índices) como no array de exemplo;

  19. fábio

    olá pessoal , alguem pode ma ajudar, estou desenvolendo um sisitema para um bar, onde já criei a página onde cadastra e edita o produto, com nome , codigo e preço , gostaria a gora de uma página simples para listar esses produtos e ao lado de cada um cum caixa para adicionar quantidade e no fim me dar o valor total, como se fosse para calcular somente, posso pagar pela ajuda, favor entrar em conato comigo por email [email protected] ., urgente

    1. Rafael Clares

      Fábio, se ninguém se pronunciar aí, envie um e-mail para [email protected] com mais informações e link para eu te passar o custo.;

  20. Mauricio

    Olá pessoal, uma dúvida que acho que é parecido com a da Aline mas como não vi a resposta vou mandar novamente.

    O usuário digita um valor e uma quantidade, preciso multiplicar isso para ter um total. Tentei com js via onkeyup mas no ie não funcionou.

    Alguem tem uma pista de como posso fazer isso?

    Obrigado,

    Maurício

  21. Paulo

    Amigo… Otimo post…

    Me ajudou muito, porém preciso substituir o array pelos dados cadastrado em meu banco de dados. Seria possível enviar um exemplo.

    Obrigado.

  22. Alison SIlva

    Ótimo post muito bom, o exemplo com o banco quando sai ??

  23. Bruno

    ÓTIMO SCRIPT, SERÁ QUE PODE ME AJUDAR?

    usando o mesmo raciocinio como faria para o usuario escrever um numero e der resultado em 3 variaveis

    exemplo

    escreva sua quantidade de frutas ____

    variavel 1 seria ”MAÇA” com valor 1,10 unidade
    Variavel 2 seria ”PERA” com valor 1,20 unidade
    variavel 3 seria ”MANGA” com valor 1,00 unidade

    E CADA UMA DELAS TERIA SEU VALOR FIXO SÓ QUE OCULTO

    no mesmo estilo do seu script só que o resultado seria em tempo real em cada campo

    exemplo O usuario digita ”15”

    e abaixo aparece os campos ja com a soma da quantidade

    maça: 16,50
    pera: 18,00
    manga: 15,00

    como faria? tentei usar só nao sei como ao inves de 1 resultado dar um só campo de valor e um resultado para cada um de 3 ou mais resultados em tempo real

    Desde ja agradeço

  24. Jacinto

    Alo galera. tava googlando, e direpente vim cair aque e parece que o assunto esta mas amenos a minha duvida.
    Estou a tentar implementar um calculos baseados em cidades e bairros para taxis.
    Exemplo eu tenho um Escolha a cidario de janeiro e quando seleciono a cidade, tenho de ser redirecionaods os bairros existentes nesta cidade bairro x
    Ate aque não tenho problema, como fazer isso.
    Agora o meu problema, esta como eu calculo um preço mediante a cidade e o bairro, tendo em conta que uma cidade pode ter varios bairros.
    o preçp é baseado em:
    preço total = Combustivel+ deslocação+Garantia * iva
    Tendo em consideração que o preço de combustivel varia consoante os bairros, o resto dos preços são constantes.
    Espero que tenha ajudado a esclarecer melhor a minha duvida

  25. Marcello Caetano

    Olá, tive que reviver esse utilíssimo post. Recebi o link pelo Face em uma comu sobre o assunto onde postei uma dúvida: “Ter um valor em uma div ou input e dividir o valor em outros quatros campos, tbm, divs ou inputs.”

    Seus códigos me atenderiam, mas gostaria de fazer o contrário, ter um campo input e nele adicionar o valor, e nos outros inputs sair a divisão(não é só isso, antes de mostrar os valores será feito outros cálculos para ser divido proporcionalmente sendo que no final a divisão tem que ter 100%, mas isso irei fazer depois).

    Como posso fazer isso com seus códigos(somente a parte da divisão, sem a proporção)?

    Vlw!

  26. Oliveira Ferreira

    Bacana este script! ajuda agente a ter uma luz no aprendizado
    Gostaria de saber se é possível usar isso com 3 combos dinamicos
    produto, sabor e tamanho
    para o produto selecionado é carregado os sabores e tamanos nos combos
    Depois atualizar o valor unitário no campo de acordo com o produto e tamanho para ser multiplicado pela quantidade
    Seria interessante a possibilidade de adicionar vários produtos
    Tem como?
    Grato

  27. viannav

    Olá, muito obrigado pelo post. Ajudou muito a minha vida. A única pergunta que tenho é sobre uma mudança no código. Gostaria de saber se no lugar da pessoa colocar a quantidade sobre um produto, ela apenas marcar a opção e automaticamente já aparece o resultado. Como se fosse num cardápio de restaurante, por exemplo. Tentei modificar mas não consegui, mudei de text pra checkbox mas não realizou a soma. Pode me ajudar?

    Desde já, obrigado!

  28. Gerson

    Clares, eu precisaria de mais um campo “quantidade” em cada linha. Desse modo, cada valor seria multiplicado pelo valor desse segundo campo e no final o resultado total.

    Como poderia fazer ?

  29. Emerson

    Oi pessoal

    na linha $(‘#produto input’).bind(‘change’,function(){

    para que os resultados saiam na hora, ao invés de clicar no próximo campo para obter o resultado é interessante abranger todas as características de eventos que possam acontecer(veja abaixo):

    $(‘#produto input’).bind(‘focus blur change keyup’,function(){

    fica a dica!

  30. Alexandre Olinto

    baixei os fontes deste script, porém (uso firefox) ele não atualiza o valor total

  31. Mariana Cotta

    Pq a sua demo funciona e quando baixei os fontes ele não atualiza o valor total

    1. Rafael Clares

      Certamente seu servidor local deve ter algo pendente de configuração.

Os comentários estão encerrados.