hello friends
i have a jquery function who calculate a total of form field in real time (live), the value of field is data from DB table .. it work fine i have add php loop to show all data in table but the jquery function calculate only the first line.
i would like to calculate all. he is the form

<form name="panierform" method="post" action="">
      <table width="80%" border="2">
        <?php do { ?>
          <tr>
            <td><label for="article"></label>
              <input type="text" name="article" id="article" value="<?php echo $row_Recordset1['article']; ?>">
            </td>
            <td><label for="prix"></label>
            <input name="prix" type="text" id="prix" value="<?php echo $row_Recordset1['prix']; ?>"></td>
            <td><label for="quantity"></label>
            <input name="quantity" type="number" id="quantity" value="1"></td>
            <td>
              <label for="ptotal"></label>
            <input type="text" name="ptotal" id="ptotal" value=""></td>
          </tr>
          <?php } while ($row_Recordset1 = mysql_fetch_assoc($Recordset1)); ?>
      </table>

for exemple if i have i have 5 data in my table the php loop will show 5 data but the ptotal field value is from jquery function it get only the first and all other are empty.
here the jquery code :

  <script type="text/javascript">
 function calculatePtotal()
    {
        var value = parseFloat($('#prix').val());
        var quantity = parseFloat($("#quantity").val());
        var shipping = parseFloat($("#shipping").val());
        var ptotal = (value * quantity);
        $("#ptotal").val(parseFloat(ptotal).toFixed(2));
    }
    $("#quantity, #shipping").change(function() {
        calculatePtotal();
    });
    calculatePtotal();
</script>

Recommended Answers

All 31 Replies

Member Avatar for iamthwee

Couldn't you do a running total?

are you storing the current value outside of the function?

if not you should be passing the current value to the function everytime you call it

With multiple rows in the table, you must use classes, not ids to identify the various DOM elements. Ids must be unique within a given DOM.

With the ids converted to classes, calculatePtotal() will be something like this :

function calculatePtotal() {
    $("tr", "#myTable").each(function(i, row) {
        $row = $(row);
        var value = parseFloat($('.prix', $row).val());
        var quantity = parseFloat($(".quantity", $row).val());
        var shipping = parseFloat($(".shipping", $row).val());
        var ptotal = (value * quantity);
        $(".ptotal", $row).val(parseFloat(ptotal).toFixed(2));
    });
}

That will recalculate all rows within the table.

i converted to class but the fonction work only if the first value of quantity change. and all ptotal get the first row total and not them real total.

<script type="text/javascript">
 function calculatePtotal()
    {
         $("tr", "#panierform").each(function(calculateptotal, row) {
        $row = $(row);
        var value = parseFloat($('.prix').val());
        var quantity = parseFloat($(".quantity").val());
        var shipping = parseFloat($(".shipping").val());
        var ptotal = (value * quantity);
        $(".ptotal").val(parseFloat(ptotal).toFixed(2));
    });
    }
    $(".quantity, .shipping").change(function() {
        calculatePtotal();
    });
    calculatePtotal();
</script>

That behaviour is more or less what I would expect from your code. You haven't done what I said to do. Look more carefully at my answer!

nothing happen with this code all ptotal is empty

 <script type="text/javascript">
 function calculatePtotal()
    {
        $("tr", "#myTable").each(function(i, row) {
        $row = $(row);
        var value = parseFloat($('.prix', $row).val());
        var quantity = parseFloat($(".quantity", $row).val());
        var shipping = parseFloat($(".shipping", $row).val());
        var ptotal = (value * quantity);
        $(".ptotal", $row).val(parseFloat(ptotal).toFixed(2));
    });
}
    $(".quantity, .shipping").change(function() {
        calculatePtotal();
    });
    calculatePtotal();
</script>


<form name="panierform" id="panierform" method="post" action="">
      <table width="80%" border="2" id="mytable">
        <tr>
          <th scope="col">Product</th>
          <th scope="col">Price</th>
          <th scope="col">Qty</th>
          <th scope="col">Product Total</th>
        </tr>
        <?php do { ?>
          <tr>
            <td><label for="article"></label>
              <input type="text" name="article" id="article" class="article" value="<?php echo $row_Recordset1['article']; ?>">
            </td>
            <td><label for="prix"></label>
            <input name="prix" type="text" id="prix" class="prix" value="<?php echo $row_Recordset1['prix']; ?>"></td>
            <td><label for="quantity"></label>
            <input name="quantity" type="number" id="quantity" class="quantity" value="1"></td>
            <td>
              <label for="ptotal"></label>
            <input type="text" name="ptotal" id="ptotal" class="ptotal" value=""></td>
          </tr>
          <?php } while ($row_Recordset1 = mysql_fetch_assoc($Recordset1)); ?>
      </table>

The function you have works as we would expect. What exactly did you want, or think would happen?

http://jsfiddle.net/pixelsoul/EeY2f/

The PHP isn't relevant here, by the way. No real point in including it in your mark up.

no i don't understund why it don't work for me it is same thing the php code loop just show all content of table ... :( i must launch the website as soon possible. :( i want it work like work here http://jsfiddle.net/pixelsoul/EeY2f/

Make sure that your id on the table is the same as it is in the function Airshow provided. He has myTable and your table has id mytable all lower case.

Thanks Pixelsoul, I was about to suggest a fiddle.

And yes, changing mytable to myTable should fix it.

Whoops, posted in error - deleted.

hey it work thank you, table id should be width.
i i have 5 ptotal how can calculate the total of ptota
totalofptotal= ptotal+ptotal???? 5 time???
sometime maybe i will have more than 5 in table

Inside calculatePtotal() :

  • declare var totalofptotal = 0; before the .each loop.
  • accumulate totalofptotal inside the loop
  • display the accumulated totalofptotal after the loop.

This will handle any number of rows.

i don't understund when you say accumulate, and i tried this cod but din't work

function calculatePtotal() {
    var totalofptotal= 0;
    $("tr", "#myTable").each(function (i, row) {
        $row = $(row);
        var value = parseFloat($('.prix', $row).val());
        var quantity = parseFloat($(".quantity", $row).val());
        var shipping = parseFloat($(".shipping", $row).val());
        var ptotal = (value * quantity);
        $(".ptotal", $row).val(parseFloat(ptotal).toFixed(2));
    });

    var totalofptotal = ( ptotal + ptotal );
        $(".totalofptotal", $row).val(parseFloat(totalofptotal).toFixed(2));
}

calculatePtotal();

$(".quantity, .shipping").change(function () {
    calculatePtotal();
});
Member Avatar for iamthwee

To do a running total you always do:

total = 0;

//some loop
total = total + something

explain cleary please :)
it same want get total of same var but diferent value

It's important in an application like this to ensure that the total is the sum of the displayed, values. Consequently, you must accumulate (ie. add up) the rounded ptotals. As .toFixed() returns a string, you have to convert back to a number. This can be performed in a single expression, eg. parseFloat(ptotal.toFixed(2)).

Try :

    ...
    var totalofptotal += parseFloat(ptotal.toFixed(2));
});
$(".totalofptotal", $row).val(totalofptotal.toFixed(2));
...

Note that the second .toFixed(2) is theoretically not necessary, but it's safer to round again as javascript is prone to minor arithmetic errors. Otherwise you could end up displaying something like 10.0000000000001.

Sorry, the totalofptotal field will be unique, therefore it can have an id, not a class, and the jQuery selector doesn't need the $row context :

 $("#totalofptotal").val(totalofptotal.toFixed(2));

it don't work and line 9 have a problem but i can't undestund where.

   <script type="text/javascript">
function calculatePtotal() {
    $("tr", "#myTable").each(function (i, row) {
        $row = $(row);
        var value = parseFloat($('.prix', $row).val());
        var quantity = parseFloat($(".quantity", $row).val());
        var shipping = parseFloat($(".shipping", $row).val());
        var ptotal = (value * quantity);
        var totalofptotal += parseFloat( ptotal.toFixed(2));
        $(".ptotal", $row).val(parseFloat(ptotal).toFixed(2));
    });
$("#totalofptotal", $row).val(totalofptotal.toFixed(2));
}

calculatePtotal();

$(".quantity, .shipping").change(function () {
    calculatePtotal();
});
</script>

The problem you are having is probably due to the jQuery selector $("tr", "#myTable"), which selects all table rows inluding the header row, not just those to which the calculation applies.

This has the effect of generating NaN (not a number) in the accumulator expression, which messes up the total.

Try giving each of the relevant rows class="calc" and select them with $("tr.calc", "#myTable").

Also, fix the line which displays totalofptotal. See my "Sorry ..." post above.

i feel loose in desert, this what i tried to do

<form name="panierform" id="panierform" method="post" action="">
      <table id="myTable" width="80%" border="2">
        <tr>
          <th scope="col">Product</th>
          <th scope="col">Price</th>
          <th scope="col">Qty</th>
          <th scope="col">Product Total</th>
        </tr>
        <?php do { ?>
          <tr>
            <td><label for="article"></label>
              <input type="text" name="article" id="article" class="article" value="<?php echo $row_Recordset1['article']; ?>">
            </td>
            <td><label for="prix"></label>
            <input name="prix" type="text" id="prix" class="prix" class="calc" value="<?php echo $row_Recordset1['prix']; ?>"></td>
            <td><label for="quantity"></label>
            <input name="quantity" type="number" id="quantity" class="quantity" class="calc" value="1"></td>
            <td>
              <label for="ptotal"></label>
            <input type="text" name="ptotal" id="ptotal" class="ptotal" class="calc" value=""></td>
          </tr>
          <?php } while ($row_Recordset1 = mysql_fetch_assoc($Recordset1)); ?>
          <tr>
          <td>
              <label for="totalofptotal"></label>
            <input type="text" name="totalofptotal" id="totalofptotal" class="totalofptotal" value=""></td>
          </tr>

            <script type="text/javascript">
function calculatePtotal() {
    $("tr .calc", "#myTable").each(function (i, row) {
        $row = $(row);
        var value = parseFloat($('.prix', $row).val());
        var quantity = parseFloat($(".quantity", $row).val());
        var shipping = parseFloat($(".shipping", $row).val());
        var ptotal = (value * quantity);
        $("#totalofptotal").val(totalofptotal.toFixed(2));
        $(".ptotal", $row).val(parseFloat(ptotal).toFixed(2));
    });
$("#totalofptotal", $row).val(totalofptotal.toFixed(2));
}

calculatePtotal();

$(".quantity, .shipping").change(function () {
    calculatePtotal();
});
</script>

Here's the whole thing :

HTML

<form name="panierform" id="panierform" method="post" action="">
      <table id="myTable" width="80%" border="2">
        <tr>
          <th scope="col">Product</th>
          <th scope="col">Price</th>
          <th scope="col">Qty</th>
          <th scope="col">Product Total</th>
        </tr>
        <?php do { ?>
          <tr class="calc"><!-- class="calc" makes these table rows selectable separately from the header row -->
            <td><label for="article"></label>
              <input type="text" name="article" id="article" class="article" value="<?php echo $row_Recordset1['article']; ?>">
            </td>
            <td><label for="prix"></label>
            <input name="prix" type="text" id="prix" class="prix" value="<?php echo $row_Recordset1['prix']; ?>"></td>
            <td><label for="quantity"></label>
            <input name="quantity" type="number" id="quantity" class="quantity" value="1"></td>
            <td>
              <label for="ptotal"></label>
            <input type="text" name="ptotal" id="ptotal" class="ptotal" value=""></td>
          </tr>
          <?php } while ($row_Recordset1 = mysql_fetch_assoc($Recordset1)); ?>
          <tr>
          <td>
              <label for="totalofptotal"></label>
            <input type="text" name="totalofptotal" id="totalofptotal" value=""></td>
          </tr>

Javascript

function calculatePtotal() {
    var totalofptotal = 0;//initialise the accumulator
    $("tr.calc", "#myTable").each(function (i, row) {
        $row = $(row);
        var value = parseFloat($('.prix', $row).val());
        var quantity = parseFloat($(".quantity", $row).val());
        var shipping = parseFloat($(".shipping", $row).val());
        var ptotal = (value * quantity)toFixed(2);//calculate row total
        $(".ptotal", $row).val(ptotal);//display row total
        totalofptotal += parseFloat(ptotal);//accumulate the row totals to make a grand total
    });
    $("#totalofptotal").val(totalofptotal.toFixed(2));//display the grand total
}

calculatePtotal();
$(".quantity, .shipping").change(function () {
    calculatePtotal();
});

i copied whole thing but nothing happe ptotal is empty and total of ptotal is empty to

Then debug it!

I missed a . in line 8 above. It should read ...

var ptotal = (value * quantity).toFixed(2);//calculate row total

yest it was . and some HTML thank you for all

it work but i have add some line here but only one work but the 2 others i'm sure it will be easy to fix ;) just the line 19 and 20 comment

  <script type="text/javascript">
function calculatePtotal() {
    var totalofptotal = 0;//initialise the accumulator
    var shippingtotal = 0;//initialise the accumulator
    var wholeqtty = 0;//initialise the accumulator
    var grandtotal = 0;
    $("tr.calc", "#myTable", "#panierform").each(function (i, row) {
        $row = $(row);
        var value = parseFloat($('.prix', $row).val());
        var quantity = parseFloat($(".quantity", $row).val());
        var shipping = parseFloat($(".shipping", $row).val());
        var ptotal = (value * quantity).toFixed(2);//calculate row total
        $(".ptotal", $row).val(ptotal);//display row total
        totalofptotal += parseFloat(ptotal);//accumulate the row totals to make a grand total
        wholeqtty += parseInt(quantity);
        grandtotal = parseFloat(totalofptotal + shippingtotal);
        shippingtotal = parseFloat(shipping * wholeqtty);
    });
    $("#grandtotal").val(totalofptotal.toFixed(2));//grand total show only the totalofptotal value
    $("#shippingtotal").val(shippingtotal.toFixed(2));// shipping total show NaN
    $("#wholeqtty").val(wholeqtty.toFixed(0)); wholeqtty work ;)
    $("#totalofptotal").val(totalofptotal.toFixed(2));//display the product total
}

calculatePtotal();
$(".quantity, .shipping").change(function () {
    calculatePtotal();
});

Where is your element that has the class of .shipping? I'm not seeing one.

here is in html

<label for="shipping">SHIPPING</label>
      <select name="Shipping" class="shipping" id="shipping"> Shipping
        <option  value="0" selected="selected">Shipping</option>
           <option value="0">0.00</option>
           <option value="9.80">9.85</option>
           <option value="19.60">19.80</option>
         </select>
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.