I am making an invoice tool for a private project. I am also using bootstrap. Everything up til this point has been perfect and no matter what I try I can't seem to get the pieces to work together.
Summary: The page loads with 2 rows of line items. Each row has a jquery function that will change the subtotal when qty and rate are changed. I have a button which will add and remove lines as needed and the primary item select list will on mousedown ajax fetch the items available.ALL these work perfectly..at least individually.
The resource found in This stack question solved my earlier issue with getting the new lines to added / removed properly ... WIN! But, I created 2 new problems that I cant seem to shake by doing so.
Here is the page loaded html ( table is id=lineitem )
<div class="container-fluid">
<div class="row">
<table class="table table-hover table-bordered styled" id="lineitem">
<thead>
<tr>
<th class="text-center">#</th>
<th class="col-md-2">PRODUCT/SERVICE</th>
<th class="col-md-6">DESCRIPTION</th>
<th class="col-md-1 text-right">QTY</th>
<th class="col-md-1 text-right">RATE</th>
<th class="col-md-1 text-right">AMOUNT</th>
<th></th>
</tr>
</thead>
<tbody class="invoicemap">
<tr>
<td class="count vert-align text-center">1</td>
<td ><select name="itemID[]" class="itemID form-control"><option disabled selected>Product/Service</option></select></td>
<td ><input class="form-control" type="text" name="describe" value=""/></td>
<td ><input id="qty" class="qty form-control" type="text" name="qty" value="0"/></td>
<td ><input id="rate" class="rate form-control" type="text" name="rate" value="8.00"/></td>
<td ><input id="amount" class="amount form-control" type="text" name="amount" value="0.00"/></td>
<td class="vert-align text-center"><a href="#"><span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
<tr>
<td class="count vert-align text-center">2</td>
<td ><select name="itemID[]" class="itemID form-control"><option disabled selected>Product/Service</option></select></td>
<td ><input class="form-control" type="text" name="describe" value=""/></td>
<td ><input id="qty" class="qty form-control" type="text" name="qty" value="0"/></td>
<td ><input id="rate" class="rate form-control" type="text" name="rate" value="5.00"/></td>
<td ><input id="amount" class="amount form-control" type="text" name="amount" value="0.00"/></td>
<td class="vert-align text-center"><a href="#"><span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-sm-1 col-md-1">
<div class="form-group">
<button type="button" class="btn btn-sm btn-info" id="addVar">Add Line</button>
</div>
</div>
<div class="col-sm-8 col-md-8"></div>
<div class="col-sm-2 col-md-2">
<div class="text-muted text-right" style="font-size: 16px; padding-top: 4px; ">DISCOUNT</div>
</div>
<div class="col-sm-1 col-md-1">
<div class="form-group">
<input type="text" class="form-control" name="discount" id="discount" value="0.00">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-1 col-md-1"></div>
<div class="col-sm-8 col-md-8"></div>
<div class="col-sm-2 col-md-2">
<div class="text-muted text-right" style="font-size: 16px; padding-top: 4px; ">BALANCE DUE</div>
</div>
<div class="col-sm-1 col-md-1">
<div class="form-group">
<input type="text" class="balance form-control" name="balance" id="balance" value="0.00">
</div>
</div>
</div>
</div>
The included .js file
$(function() {
CalculateTotal();
// Adding the change events for the Price and
// quantity fields only..
// Changing the total should not affect anything
$('#qty , #rate, #discount').on('change', function() {
UpdateTotals(this);
});
});
function UpdateTotals(elem) {
// This will give the tr of the Element Which was changed
var $container = $(elem).parent().parent();
var quantity = $container.find('#qty').val();
var price = $container.find('#rate').val();
var subtotal = parseInt(quantity) * parseFloat(price);
$container.find('.amount').val(subtotal.toFixed(2));
CalculateTotal();
}
function CalculateTotal(){
// This will Itearate thru the subtotals and
// claculate the grandTotal and Quantity here
var lineTotals = $('.amount');
var discount = $('#discount').val();
var grandTotal = 0.0;
$.each(lineTotals, function(i){
grandTotal += parseFloat($(lineTotals[i]).val()) ;
});
var total = parseFloat(grandTotal-discount ).toFixed(2);
$('.balance').val(total);
$('#ibalance').text(total);
}
function itemList() {
//var id=$(this).val();
//var dataString = 'id='+ id;
$.ajax ({
type: "POST",
url: "api/api.get-list.php?type=item",
cache: false,
async: false,
success:function(data) {
result = data;
}
});
return result;
}
$("select.itemID").mousedown(function(){
var $this = $(this);
if (data) {
$(this).val(data);
} else {
itemList();
$(this).html(result);
}
});
$('form').on('click', '.removeVar', function(){
$(this).closest('tr').remove();
$('.count').each(function(i){
$(this).text(i + 1);
});
});
$('#addVar').on('click', function(){
var varCount = $('#lineitem tr').length;
$node = ['<tr>',
'<td class="count vert-align text-center">'+varCount+'</td>',
'<td><select name="itemID[]" class="itemID form-control">',
'<option disabled selected>Product/Service</option>',
'</select></td>',
'<td ><input class="itemdetail form-control" type="text" name="describe" value=""/></td>',
'<td ><input id="qty" class="qty form-control" type="text" name="qty" value="0"/></td>',
'<td ><input id="rate" class="rate form-control" type="text" name="rate" value="0.00"/></td>',
'<td ><input id="amount" class="amount form-control" type="text" name="amount" value="0.00"/></td>',
'<td class="vert-align text-center"><a class="removeVar"><span class="glyphicon glyphicon-trash"></span></a></td>',
'</tr>'].join('\n');
$('#lineitem > tbody:last').append($node);
});
$("#lineitem").on('change', ".itemID", function(){
var row = $(this).closest('tr');
var itemID = row.find(".itemID").val();
//alert(itemID);
$.ajax ({
type: "POST",
url: "api/api.items.php?mode=fetch&id="+itemID,
cache: false,
success: function(html) {
row.find(".itemdetail").html(html);
//alert(html);
}
});
});
to attempt to make this easier the last function was my desperate attempt to get the select.itemID on change to call an ajax function to fetch all the line item details and put them in the right places. (detail and cost )
When all of this is plugged in. I can select from the select list and get the results populated ( its glitchy though - basically it requires 2 attempts to actually appear to have selected the item ) nothing else comes from this action. I can change the qty and rate on the 2 lines from page load. All ajax calls are sending the right data.
What fails, adding a row and using the select does not work, nor does adding totals.
This is a mess I know but I really need some help figuring this out.