Insumare valori campuri intr-un formular folosind jQuery

Salutare,

Cum front-end-ul imi da tot timpul batai de cap, doresc sa va supun atentiei urmatoarea situatie.

Am preluat un proiect cu un formular in care campurile sunt de forma asta:

    <ul>
        <li class="basic">
            <h4 class="secondary-title" style="margin-top: 0px;">Produse</h4>
        </li>
        <li class="produs">
            <div class="label">
                &bull; Articulatii (60)                                        
            </div>
            <input class="short" type="text" class="cantitate" name="cantitate_23" value="" placeholder="Cantitate" /> -
            <input class="short" type="text" class="pret_unitar" name="pret_unitar_23" value="" placeholder="Pret unitar" /> 
        </li>
        <li class="produs">
            <div class="label">
                &bull; Articulatii (120)                                        
            </div>
            <input class="short" type="text" class="cantitate" name="cantitate_24" value="" placeholder="Cantitate" /> -
            <input class="short" type="text" class="pret_unitar" name="pret_unitar_24" value="" placeholder="Pret unitar" /> 
        </li>
        <li class="produs">
            <div class="label">
                &bull; Crema Reviflex                                        
            </div>
            <input class="short" type="text" class="cantitate" name="cantitate_29" value="" placeholder="Cantitate" /> -
            <input class="short" type="text" class="pret_unitar" name="pret_unitar_29" value="" placeholder="Pret unitar" /> 
        </li>
        <li class="produs">
            <div class="label">
                &bull; Cura de slabire (60)                                        
            </div>
            <input class="short" type="text" class="cantitate" name="cantitate_22" value="" placeholder="Cantitate" /> -
            <input class="short" type="text" class="pret_unitar" name="pret_unitar_22" value="" placeholder="Pret unitar" /> 
        </li>
        <li class="produs">
            <div class="label">
                &bull; Detoxifiant (60)                                        
            </div>
            <input class="short" type="text" class="cantitate" name="cantitate_3" value="" placeholder="Cantitate" /> -
            <input class="short" type="text" class="pret_unitar" name="pret_unitar_3" value="" placeholder="Pret unitar" /> 
        </li>
        <li class="produs">
            <div class="label">
                &bull; Detoxifiant (150)                                        
            </div>
            <input class="short" type="text" class="cantitate" name="cantitate_4" value="" placeholder="Cantitate" /> -
            <input class="short" type="text" class="pret_unitar" name="pret_unitar_4" value="" placeholder="Pret unitar" /> 
        </li>
        [...]
        <li>
            <div class="label">
                Valoare comanda
            </div>
            <input class="short" type="text" name="valoare_comanda" id="valoare_comanda" readonly="readonly" value="" />
        </li>
    </ul>

Ideea este ca utilizatorul trebuie sa introduca o valoare in campul cantitate, apoi un pret unitar, iar in final, in campul “valoare_comanda” trebuie sa se insumeze fiecare linie.

jQuery-ul l-am facut asa:

var total = 0;
$("body").on("keyup change", ".produs input", function() {
    var me = $(this);   
    var other = me.parent(".produs").find("input").not(me);
    if (other.val() != "" && me.val != "") {
        var total_produs = me.val() * other.val();     
        total += total_produs;                                                                                      
    }        
});                                                                     

Evident, in consola apare o valoare eronata, deoarece insumarea o face la fiecare keyup. Doar ca nu stiu cum as putea modifica snippet-ul jQuery astfel incat sa-l fac functional in conditiile in care cunostintele mele in domeniu sunt destul de limitate.

Orice sfat e binevenit.

Multumesc.

pai ai putea muta definitia la total in interiorul functiei. asa ar calculat corect la fiecare keyup.

  1. nu inteleg de ce ignori inputul activ. nu trebuie luat si ala in seaman cand faci totalul?
  2. selecteaza li-urile. faci un foreach pe fiecare si acolo cauti inputurile care te intereseaza si le inmultesti.

ps: astea-s variante extrem de simple, n-am stat sa analizez prea mult codul.

1 Like

How about…

$('.produs').on( 'blur', 'input', getTotal );

function getTotal() {
    var total = 0;
    $('.produs').each(function(i, produs){
        var qty = $('.cantitate', produs).val();
        var pret = $('.pret_unitar', produs).val();
        if( qty && pret ){
            total += qty * pret;
        }
    });
    return total;
}

Nu cred că poți face un total fără a itera fiecare element. Și pentru că se întâmplă așa, cred că cel mai bine faci update la blur.

2 Likes
if(isNaN(qty) || isNaN(pret)){
   return true;
}

ah, si ar trebui sa le convertesti in float-uri. conversia implicita o sa dea balarii daca faci adunari

1 Like

@iamntz, da, practic totalul pe un produs trebuie sa se calculeze doar cand a completat atat cantitatea, cat si pretul unitar. Iar apoi totalul pe produs se aduna la totalul general care o sa apara in campul valoare_comanda.

@Cosmin: @alescx are dreptate, nu uita să convertești în float. Uite aici exemplul corectat:

function getTotal() {
    var total = 0;
    $('.produs').each(function(i, produs){
        var qty  = $('.cantitate', produs).val();
        var pret = $('.pret_unitar', produs).val();

        qty  = parseFloat( qty );
        pret = parseFloat( pret );

        if( isNaN( qty ) || isNaN( pret ) ){
          return;
        }
        total += qty * pret;
    });
    return total;
}

$('.produs').on( 'blur keyup', 'input', getTotal );
$(document).ready( getTotal );

Pe ultima linie faci trigger când se încarcă pagina (poate ai și ceva elemente pre-filled, nu?). Penultima linie este unde umbli la events; ajustezi în funcție de necesități (dacă ai un număr relativ mic, să zicem… sub 20-30 rows) poți face o iterație la fiecare keyup, altfel doar la blur…

Functia imi este clara, nici o nelamurire acolo, dar mai departe nu prea ma prind cum ajung sa pun valoarea totalului general in campul respectiv. Si aici nu vorbesc de asignarea valorii, ci de preluarea ei. Ma induce in eroare:

$('.produs').on( 'blur keyup', 'input', getTotal );
$(document).ready( getTotal );

Ah! Pentru că am plecat cu o idee și am ajuns la altceva :smile:

În loc de return total; pune $('#valoare_comanda').val( total );

Am facut deja chestia asta si pentru ca valoarea ramane 0 indiferent de ce completez in input-uri am pus intrebarea cu preluarea valorii :slight_smile:

probabil pentru ca n-ai clasele respective pe inputuri.

var qty  = $('.cantitate', produs).val();
var pret = $('.pret_unitar', produs).val();

eu as pune ceva de genu js-get-quantity si js-get-price (prefixez cu js- ca sa n-am probleme mai tarziu. stiu ca clasele respective sunt folosite doar ca selectori, n-au treaba cu css-ul de pe pagina)

@alescx, clasele sunt la locul lor (vezi codul din primul post).

sorry, am observat dupa aia. incerc sa-mi dau seama acum de ce nu vrea s-o ia

repet raspunsul. pune clasele :wink:

<input class="short" type="text" class="cantitate" name="cantitate_23" value="" placeholder="Cantitate" /> -
1 Like

@Cosmin: ai de două ori atributul class :slight_smile:

1 Like

trebuia sa-l lasi. a doua oara ii sarea in ochi chestia asta :smiley:

1 Like

Shit! Asta era! :slight_smile: Multzam fain!

<input class="short" type="text" name="valoare_comanda" id="valoare_comanda" readonly="readonly" value="" />

Quick question: Ce se intampla daca dau un inspect si modific #valoare_comanda?

Did I just hack your app?

@dakull tind să cred că toată povestea asta are scop pur informativ :slight_smile: