Hello again,
So, let’s have a look at updating the form total.
We will need to do this any time the user inputs something into one of our table’s input fields (apart from the “Descripción” field).
$("#invoice-table").on("input", function(e) {
if(e.target.className !== "description"){
console.log("Yay");
}
});
We are using the oninput event to do this, examining this event to determine which field triggered it and reacting accordingly.
Note: so that we can reference the field by its class, I have changed the Descripción field’s name attribute to a class attribute.
In the updateTotal function we need to get every row in the table, extract the quantity and cost of the item and update the price:
function updateTotal(){
$("#invoice-table > tbody > tr.row").each(function(){
var quantity = Number($(this).find("input.cantidad").val()),
cost = Number($(this).find("input.coste").val());
$(this).find("p.precio").text(cost * quantity);
});
}
And we need to update the subtotal:
function updateTotal(){
var subtotal= 0;
$("#invoice-table > tbody > tr.row").each(function(){
var quantity = $(this).find("input.cantidad").val(),
cost = $(this).find("input.coste").val();
price = +cost * +quantity;
$(this).find("p.precio").text(price);
subtotal += price;
});
$(".subtotal").text(subtotal);
}
Note in the above, I’ve used a unary plus as a synonym for Number().
All that’s left now is the grand total, which is the subtotal plus IVA percent of the subtotal plus IRPF percent of the subtotal.
e.g.
quantity 2, coste 50
= price 100
= subtotal 100
+
iva 21% = 100 *0. 21
= 21
+
irpf 22% = 100 * 0.22
= 22
= 100 + 21 +22
I hope I got that right.
Anyways, here’s the implementation:
function updateTotal(){
var subtotal = 0,
iva = Number($(".iva").val()) / 100,
irpf = Number($(".irpf").val()) / 100,
totaliva,
totalirpf;
$("#invoice-table > tbody > tr.row").each(function(){
var quantity = $(this).find("input.cantidad").val(),
cost = $(this).find("input.coste").val();
price = +cost * +quantity;
$(this).find("p.precio").text(price);
subtotal += price;
});
totaliva = subtotal*iva;
totalirpf = subtotal*irpf;
$(".subtotal").text(subtotal);
$(".totaliva").text(totaliva);
$(".totalirpf").text(totalirpf);
$(".total").text(subtotal + totaliva + totalirpf);
}
That function is actually doing quite a lot of things and you should probably split it into further functions, but I’ll leave that to you 
The final thing to do is to make sure any decimals are rounded to two decimal places, otherwise you’ll have prices like “22.259999999999998” which would be silly.
This will only affect the totaliva, totalirpf and total fields.
You could write:
totaliva = Math.round((subtotal*iva) * 100) / 100;
totalirpf = Math.round((subtotal*irpf) * 100) / 100;
$(".total").text(Math.round((subtotal + totaliva + totalirpf) * 100) / 100);
but that’s ugly.
Let’s stick it in a function:
function roundToTwo(value) {
return(Math.round(value * 100) / 100);
}
...
totaliva = roundToTwo(subtotal*iva);
totalirpf = roundToTwo(subtotal*irpf);
$(".total").text(roundToTwo(subtotal + totaliva + totalirpf));
Hope that all makes sense.
Here’s the complete code:
<!doctype html>
<head>
<meta charset="utf-8">
<title>Invoice generator</title>
<base href="http://brunofelicio.com/staging/facturame/"/>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/style.css">
<style>#template{ display: none; }</style>
</head>
<body>
<div id="container">
<div id="page-container">
<form id="invoice" method="POST" action="invoice_html.php"><!-- Invoice form -->
<div id="main" role="main">
<div id="details">
<h2>Detalles</h2>
<table id="invoice-table">
<thead>
<tr>
<th>Opciones</th>
<th>Descripción</th>
<th>Cant.</th>
<th>Coste</th>
<th>Precio</th>
</tr>
</thead>
<tbody>
<tr class="row">
<td><a href="#" class="delete-row">Delete</a></td>
<td><input type="text" class="description" placeholder="Descripción del articulo" size="40" value="Some description"/></td>
<td><input class="cantidad" type="text" name="cost" placeholder="Cant." size="2" value="0"/></td>
<td><input class="coste" type="text" name="qty" placeholder="Coste" size="2" value="0"/></td>
<td><p class="precio">0</p></td>
</tr>
<tr>
<td><a href="#" class="add-row">Add row</a></td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="noborder" rowspan="4" colspan="3"></td>
<td></td>
<td class="subtotal">0</td>
</tr>
<tr>
<td>IVA <input class="iva" type="text" placeholder="IVA" value="21" size="2"/>%</td>
<td class="totaliva"></td>
</tr>
<tr>
<td>IRPF<input class="irpf" type="text" placeholder="IRPF" value="21" size="2"/>%</td>
<td class="totalirpf"></td>
</tr>
<tr>
<td><strong>TOTAL</strong></td>
<td class="total">0</td>
</tr>
</tfoot>
</table>
</div>
</div><!--! end of #main -->
</div> <!--! end of #page-container -->
</form>
</div> <!--! end of #container -->
<script src="js/jquery-1.10.2.min.js"></script>
<script>
var template = $("#invoice-table > tbody > tr:first").clone();
function roundToTwo(value) {
return(Math.round(value * 100) / 100);
}
function updateTotal(){
var subtotal = 0,
iva = Number($(".iva").val()) / 100,
irpf = Number($(".irpf").val()) / 100,
totaliva,
totalirpf;
$("#invoice-table > tbody > tr.row").each(function(){
var quantity = $(this).find("input.cantidad").val(),
cost = $(this).find("input.coste").val();
price = +cost * +quantity;
$(this).find("p.precio").text(price);
subtotal += price;
});
totaliva = roundToTwo(subtotal*iva);
totalirpf = roundToTwo(subtotal*irpf);
$(".subtotal").text(subtotal);
$(".totaliva").text(totaliva);
$(".totalirpf").text(totalirpf);
$(".total").text(roundToTwo(subtotal + totaliva + totalirpf));
}
$(".add-row").on("click", function(e) {
var newRow = template.clone();
$("#invoice-table > tbody > tr.row:last").after(newRow);
e.preventDefault();
});
$("#invoice-table").on("click",".delete-row", function(e) {
var tableRow = $(this).closest("tr");
if(tableRow.is(":first-child")){
alert("Don't be silly!");
} else {
tableRow.remove();
updateTotal();
}
e.preventDefault();
});
$("#invoice-table").on("input", function(e) {
if(e.target.className !== "description"){
updateTotal();
}
});
</script>
</body>
</html>