I have a table for a school card.The aim is to display the average per grading period.The data is from the database while the average result is from the javascript.When a user input in any of the input fields, the average along that column should dynamically changes or update it.Now in my current code,It generates an error e.text() is not a function.Basically the sum variable didn't catch a value from the parseInt.Anyone have an idea resolving this issue?
****** sample results******
Subject | Col1 |Col2 |Col3 |Col4
1 80 80 86 80 (80+80+86+80)/4 Note: not this way
2 86 85 86 81
3 80 87 85 86
Result 82 84 and so on..
It should be:
(80+86+80)/3 number of rows
view.blade.php
<tr>
<th colspan="3">Subjects</th>
<th colspan="2">First Grading</th>
<th colspan="2">Second Grading</th>
<th colspan="2">Third Grading</th>
<th colspan="2">Fourth Grading</th>
</tr>
</thead>
<tbody>
#foreach($update_card['AllGrade'] as $subject)
{!! Form::hidden('grade_id[]',$subject['grade_id']) !!}
<tr>
<td colspan="3">{!! $subject->subject !!}</td>
<td colspan="2"><input type="text" name="term_1[]" value="{!! $subject->term_1 !!}" class="form-control number-only"></td>
<td colspan="2"><input type="text" name="term_2[]" value="{!! $subject->term_2 !!}" class="form-control number-only"></td>
<td colspan="2"><input type="text" name="term_3[]" value="{!! $subject->term_3 !!}" class="form-control number-only"></td>
<td colspan="2"><input type="text" name="term_4[]" value="{!! $subject->term_4 !!}" class="form-control number-only"></td>
<td class="ave" value="0"></td>
</tr>
#endforeach
<tr id="average">
<td colspan="3">Average</td><td colspan="2">0</td> <td colspan="2">0</td> <td colspan="2">0</td> <td colspan="2">0</td>
</tr>
</tbody>
javascript here
$("input").on("keyup", function() {
$("tbody tr").each(function(index) {
var sum = 0; // The summation of all terms.
var card = 0; // Number of cells.
$(this).children('td').not(':first').each(function(i, e) {
card++;
sum+= parseInt(e.text().trim()); //this is the error
});
var avg = sum/card;
console.log(avg);
$("#average td:nth-of-type("+index+")").html(avg);
});
});
as I pointed you loop through tds and get text() while it has no text on it .. it
has an input so you need to get the input value not the td text
so you can try something like this
I create a functions for row_sum() to sum the row ,column_sum() to sum the column ,column_Average() to get column average by row numbers and row_Average() to get row average by td numbers.
$(document).ready(function(){
$("input").on("keyup", function() {
//row_sum(); // for sum row
//column_sum(); // for sum column
column_Average(); // for column average
row_Average(); // for row average
}).keyup(); // by adding .keyup() your code will run onload
});
function column_sum(){
var sum = []; // The summation of all terms.
$("tbody tr:not(#average)").each(function(index) {
var thisIt = $(this);
thisIt.find('td:not(.ave)').not(':first').each(function(i) {
var input_val = ($.trim($(this).find('input').val())) ? $(this).find('input').val().trim() : 0;
sum[i] ? sum[i] += parseInt(input_val) : sum.push(parseInt(input_val));
});
});
$('#average td:not(:first)').each(function(i){
$(this).text(sum[i]);
});
}
function row_sum(){
$("tbody tr:not(#average)").each(function(index) {
var thisIt = $(this);
var sum = 0; // The summation of all terms.
thisIt.find('td').not(':first').not(':last').each(function(i) {
var input_val = ($.trim($(this).find('input').val())) ? $(this).find('input').val().trim() : 0;
sum += parseInt(input_val);
});
thisIt.find('td.ave').text(sum);
});
}
function column_Average(){
var sum = []; // The summation of all terms.
var tr_num = $("tbody tr:not(#average)").length;
$("tbody tr:not(#average)").each(function(index) {
var thisIt = $(this);
thisIt.find('td:not(.ave)').not(':first').each(function(i) {
var input_val = ($.trim($(this).find('input').val())) ? $(this).find('input').val().trim() : 0;
sum[i] ? sum[i] += parseInt(input_val) : sum.push(parseInt(input_val));
});
});
$('#average td:not(:first)').each(function(i){
$(this).text(sum[i] / tr_num);
});
}
function row_Average(){
$("tbody tr:not(#average)").each(function(index) {
var thisIt = $(this);
var sum = 0; // The summation of all terms.
var code = 0; thisIt.find('td').not(':first').not(':last').each(function(i) {
var input_val = ($.trim($(this).find('input').val())) ? $(this).find('input').val().trim() : 0;
code++;
sum += parseInt(input_val);
});
thisIt.find('td.ave').text(sum / code);
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th colspan="3">Subjects</th>
<th colspan="2">First Grading</th>
<th colspan="2">Second Grading</th>
<th colspan="2">Third Grading</th>
<th colspan="2">Fourth Grading</th>
<th>Average</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="3">Subject</td>
<td colspan="2"><input type="text" name="term_1[]" value="12" class="form-control number-only"></td>
<td colspan="2"><input type="text" name="term_2[]" value="13" class="form-control number-only"></td>
<td colspan="2"><input type="text" name="term_3[]" value="14" class="form-control number-only"></td>
<td colspan="2"><input type="text" name="term_4[]" value="15" class="form-control number-only"></td>
<td class="ave" value="0"></td>
</tr>
<tr>
<td colspan="3">Subject</td>
<td colspan="2"><input type="text" name="term_1[]" value="120" class="form-control number-only"></td>
<td colspan="2"><input type="text" name="term_2[]" value="130" class="form-control number-only"></td>
<td colspan="2"><input type="text" name="term_3[]" value="140" class="form-control number-only"></td>
<td colspan="2"><input type="text" name="term_4[]" value="150" class="form-control number-only"></td>
<td class="ave" value="0"></td>
</tr>
<tr id="average">
<td colspan="3">Average</td><td colspan="2">0</td> <td colspan="2">0</td> <td colspan="2">0</td> <td colspan="2">0</td>
</tr>
</tbody>
</table>
Related
I am trying to calculate unit total and based on that final total using jQuery, I am able to update unit total every time qty or price is updated, but not able to update final total.
Here is the code:
<table id="tblUpdate" class="dataTable">
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
<th>Unit Total</th>
</tr>
</thead>
<tbody>
<cfset TotalPrice = 0>
<cfloop query="qItems">
<cfset vLineID = qItems.LineID>
<cfset vUnitTotal = qItems.Quantity * qItems.Price>
<cfset TotalPrice = TotalPrice + vUnitTotal>
<tr data-item-id="#qItems.ItemID#">
<td>#qItems.ItemDescription#</td>
<td><input type="text" name="Quantity_#qItems.LineID#" id="Quantity#vLineID#" class="Quantity" onchange="ChangePrice(#vLineID#,'Quantity');" value="#NumberFormat(qItems.Quantity, '9.99')#" </td>
<td><input type="text" name="Price_#qItems.LineID#" id="UnitPrice#vLineID#" class="Price" onchange="ChangePrice(#vLineID#,'UnitPrice');" value="#NumberFormat(qItems.Price, '9.99')#" </td>
<td id="UnitTotal#vLineID#" class="UnitTotal">#NumberFormat(vUnitTotal,'9.99')#</td>
</tr>
</cfloop>
</tbody>
<tfoot>
<td colspan="4"></td>
<td>Total:</td>
<td id="TotalPrice_Total">#NumberFormat(TotalPrice,'9.99')#</td>
</tfoot>
</table>
And here if the Jquery: The unit total is updating every time when Qty and Price is updated, however, RefreshTotals() function is not updating. Its getting me values but not adding them and calculating final total.
<script>
$(document).ready(function()
{
function ChangePrice(LineID,FieldChanged) {
var Quantity = document.getElementById("Quantity"+LineID);
var UnitPrice = document.getElementById("UnitPrice"+LineID);
var TotalPrice = 0;
var vQuantity = Quantity.value;
var vUnitPrice = UnitPrice.value;
if (FieldChanged == "Quantity" || FieldChanged == "UnitPrice") {
vCustomTotal = vQuantity * vUnitPrice;
$('#UnitTotal' + LineID).text(vCustomTotal.toFixed(2));
}
refreshTotals();
}
function refreshTotals() {
var vTotalPrice = 0;
$('.UnitTotal').each(function(index) {
var r = $("#tblUpdate.UnitTotal").text();
vTotalPrice = vTotalPrice + r;
});
$('#TotalPrice_Total').text(vTotalPrice.toFixed(2));
}
}
</script>
Consider the following example.
$(function() {
function formatCurrency(f) {
return "$" + parseFloat(f).toFixed(2);
}
function refreshTotals() {
var vTotalPrice = 0;
var r;
$(".UnitTotal").each(function(index, element) {
r = parseFloat($(element).text().trim().substring(1));
vTotalPrice += r;
});
$('#TotalPrice_Total').text(formatCurrency(vTotalPrice));
}
function changePrice(Row) {
var Quantity = parseInt($(".Quantity", Row).val());
var UnitPrice = parseFloat($(".Price", Row).val().substring(1));
var TotalPrice = Quantity * UnitPrice;
$(".UnitTotal", Row).html(formatCurrency(TotalPrice));
refreshTotals();
}
$(".Quantity, .Price").change(function() {
changePrice($(this).closest("tr"));
});
refreshTotals();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tblUpdate" class="dataTable">
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
<th>Unit Total</th>
</tr>
</thead>
<tbody>
<tr data-item-id="01">
<td>Item 01</td>
<td><input type="number" min="0" max="999" name="Quantity_01" id="Quantity01" class="Quantity" value="9" /></td>
<td><input type="text" name="Price_01" id="UnitPrice01" class="Price" value="$9.99" /> </td>
<td id="UnitTotal01" class="UnitTotal">$89.91</td>
</tr>
<tr data-item-id="02">
<td>Item 02</td>
<td><input type="number" min="0" max="999" name="Quantity_02" id="Quantity02" class="Quantity" value="6" /></td>
<td><input type="text" name="Price_02" id="UnitPrice02" class="Price" value="$8.88" /> </td>
<td id="UnitTotal01" class="UnitTotal">$53.28</td>
</tr>
<tr data-item-id="03">
<td>Item 03</td>
<td><input type="number" min="0" max="999" name="Quantity_03" id="Quantity03" class="Quantity" value="3" /></td>
<td><input type="text" name="Price_03" id="UnitPrice03" class="Price" value="$7.77" /> </td>
<td id="UnitTotal03" class="UnitTotal">$23.31</td>
</tr>
</tbody>
<tfoot>
<td colspan="2"></td>
<td>Total:</td>
<td id="TotalPrice_Total">$0.00</td>
</tfoot>
</table>
When there are changes to Quantity or Price, the total Unit Price is updated along with the Total. We can pass in the Row and then collect all the details needed from that Row. The value of an input is String so it is best to cast it into the proper Integer or Float as needed. This will ensure that Math operations are correct.
This is my Html code in my Invoice file:
<tr class="item-row">
<td>7.</td>
<td class="item-name">
<input type="text" name="i7_n" placeholder="Enter Item" required="required">
</td>
<td class="description">
<textarea name="i7_d" placeholder="Item Note" class="form-control"></textarea>
</td>
<td>
<input type="number" name="i7_q" step="1" min="0" class="qty">
</td>
<td>
<input type="number" name="i7_c" step="1" min="0" class="cost">
</td>
<td><span class="price">0.00</span></td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">Subtotal Rs.</td>
<td td class="total-value"><div id="subtotal">0.00</div></td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">CGST 2.5%</td>
<td class="total-value"><textarea id="cgst" placeholder="%">0.00</textarea></td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">SGST 2.5%</td>
<td class="total-value"><textarea id="sgst" placeholder="%">0.00</textarea></td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">Amount after GST </td>
<td class="total-value"><div id="total">0.00</div></td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">Amount Paid Rs.</td>
<td class="total-value"><textarea id="paid">0.00</textarea></td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line balance">Balance Due Rs.</td>
<td class="total-value balance"><div class="due">875.00</div></td>
</tr>
When i run my this following JS Code:-
//This Updates subtotal & total
function update_total() {
var total = 0;
$('.price').each(function(i){
price = $(this).html().replace("$","");
if (!isNaN(price)) total += Number(price);
});
total = roundNumber(total,2);
$('#subtotal').html(total);
// $('#total').html(total);
update_gst();
}
//this adds CGST & SGST in subtotal
function update_gst() {
var total = $("#subtotal").html().replace("$","") + $("#cgst").val().replace("$","") + $("#sgst").val().replace("$","");
total = roundNumber(total,2) ;
$('#total').html(total);
update_balance();
}
//this updates amount paid & outstanding at end
function update_balance() {
var due = $("#total").html().replace("$","") - $("#paid").val().replace("$","");
due = roundNumber(due,2);
$('.due').html(due);
}
//This updates item Qty * Item Price = Item Total
function update_price() {
var row = $(this).parents('.item-row');
var price = row.find('.cost').val().replace("$","") * row.find('.qty').val();
price = roundNumber(price,2);
isNaN(price) ? row.find('.price').html("N/A") : row.find('.price').html(price);
update_total();
}
This gives me my all balances Ok. My problem is I want to add 2 Taxes (CGST #2.5% & SGST #2.5%) [By using JS only] to Sub-Total to give Final Figures after taxes. . i think my code "update_gst()" has some issues.
Please Help me on how I can update my above JS code...
i want when i check checkbox in table get array values check (NAME, FIRST NAME, SALAIRENET) in example below it gives me just SALAIRENET and give NaN a name for the line check, please help me.
he is my table
<table class="table table-bordered" id="mytable">
<tr>
<th>Archive</th>
<th><input type="checkbox" id="check_all"></th>
<th>S.No.</th>
<th>matricule</th>
<th>nom & prenom</th>
<th>salaire net</th>
<th>nbre de jour </th>
<th>prime</th>
</tr>
#if($salaries->count())
#foreach($salaries as $key => $salarie)
<tr id="tr_{{$salarie->id}}">
<td>archive</td>
<td><input type="checkbox" class="checkbox" data-id="{{$salarie->id}}"></td>
<td>{{ ++$key }}</td>
<td>{{ $salarie->matricule }}</td>
<td class="name">{{ $salarie->nom }} {{ $salarie->prenom }}</td>
<td class="salaireValue">{{ $salarie->salairenet }}</td>
<td><input type="text" name="nbreJ" class="form-control" value="{{$data['nbr']}}"></td>
<td><input type="text" name="prime" class="form-control" value="0"></td>
</tr>
#endforeach
#endif
</table>
he is my code jquery:
<script type="text/javascript">
$(document).ready(function () {
$('#check_all').on('click', function(e) {
if($(this).is(':checked',true))
{
$(".checkbox").prop('checked', true);
} else {
$(".checkbox").prop('checked',false);
}
});
$('.checkbox').on('click',function(){
if($('.checkbox:checked').length == $('.checkbox').length){
$('#check_all').prop('checked',true);
}else{
$('#check_all').prop('checked',false);
}
});
//get value
$('.table').on('click', function() {
var allChecked = $('.checkbox:checked');
for (var i = 0; i < allChecked.length; i++) {
var currentHtml = $(allChecked[i]).parent().siblings('.salaireValue')[0];
var currentHtml1 = $(allChecked[i]).parent().siblings('.name')[0];
var result = parseInt($(currentHtml)[0].innerText);
var result1 = parseInt($(currentHtml1)[0].innerText);
console.log(result);
console.log(result1);
}
});
});
</script>
It might be helpful to create functions to break up the work. Also you can use parseInt() but it must receive a String that represents an Integer, so "1000" versus "One Thousand".
Consider the following:
$(function() {
function checkToggleAll(c, v) {
$(".checkbox", c).each(function(i, el) {
$(el).prop("checked", v);
});
}
function checkAll(c) {
if ($(".checkbox:checked", c).length == $(".checkbox", c).length) {
$("#check_all").prop("checked", true);
} else {
$("#check_all").prop("checked", false);
}
}
function gatherData(c) {
var rows = {}
$(".checkbox:checked", c).each(function(i, el) {
var row = $(el).parent().parent();
rows[row.attr("id")] = {
Name: $(".first-name", row).text().trim(),
SurName: $(".sur-name", row).text().trim(),
SalaireValue: parseInt($(".salaireValue", row).text().trim())
};
});
return rows;
}
$("#check_all").change(function() {
checkToggleAll($("tbody"), $(this).prop("checked"));
console.log(gatherData($(".table tbody")));
});
$("tbody .checkbox").on("change", function() {
checkAll($(".table tbody"));
console.log(gatherData($(".table tbody")));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-bordered" id="mytable">
<thead>
<tr>
<th>Archive</th>
<th><input type="checkbox" id="check_all"></th>
<th>S.No.</th>
<th>matricule</th>
<th>nom & prenom</th>
<th>salaire net</th>
<th>nbre de jour </th>
<th>prime</th>
</tr>
</thead>
<tbody>
<tr id="tr_1">
<td>archive</td>
<td><input type="checkbox" class="checkbox" data-id="1"></td>
<td>1</td>
<td>1001</td>
<td class="name">Simpson, Homer</td>
<td class="salaireValue">60000</td>
<td><input type="text" name="nbreJ" class="form-control" value="40"></td>
<td><input type="text" name="prime" class="form-control" value="0"></td>
</tr>
<tr id="tr_2">
<td>archive</td>
<td><input type="checkbox" class="checkbox" data-id="2"></td>
<td>2</td>
<td>1002</td>
<td class="name">Leonard, Lenny</td>
<td class="salaireValue">40000</td>
<td><input type="text" name="nbreJ" class="form-control" value="40"></td>
<td><input type="text" name="prime" class="form-control" value="0"></td>
</tr>
<tr id="tr_3">
<td>archive</td>
<td><input type="checkbox" class="checkbox" data-id="3"></td>
<td>3</td>
<td>1002</td>
<td class="name">Carlson, Carl</td>
<td class="salaireValue">55000</td>
<td><input type="text" name="nbreJ" class="form-control" value="40"></td>
<td><input type="text" name="prime" class="form-control" value="0"></td>
</tr>
</tbody>
</table>
I assume that the table content might get updated dynamically, so I am using .on() just in case. You can use .change() if needed.
Hope that helps.
A few changes in your for loop will make it:
for (var i = 0; i < allChecked.length; i++) {
var $tr = $(allChecked[i]).closest("tr");
var item = {
Name: $tr.find(".first-name").text(),
SurName: $tr.find(".sur-name").text(),
SalaireValue: $tr.find(".salaireValue").text()
};
console.log(item);
}
I've also separated the names into two spans in order to make it easy to select them.
$('#check_all').on('click', function(e) {
if($(this).is(':checked',true))
{
$(".checkbox").prop('checked', true);
} else {
$(".checkbox").prop('checked',false);
}
});
$('.checkbox').on('click',function(){
if($('.checkbox:checked').length == $('.checkbox').length){
$('#check_all').prop('checked',true);
}else{
$('#check_all').prop('checked',false);
}
});
//get value
$('.table').on('click', function() {
var allChecked = $('.checkbox:checked');
for (var i = 0; i < allChecked.length; i++) {
var $tr = $(allChecked[i]).closest("tr");
var item = {
Name: $tr.find(".first-name").text(),
SurName: $tr.find(".sur-name").text(),
SalaireValue: $tr.find(".salaireValue").text()
};
console.log(item);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-bordered" id="mytable">
<tr>
<th>Archive</th>
<th><input type="checkbox" id="check_all"></th>
<th>S.No.</th>
<th>matricule</th>
<th>nom & prenom</th>
<th>salaire net</th>
<th>nbre de jour </th>
<th>prime</th>
</tr>
<tr id="tr_1">
<td>archive</td>
<td><input type="checkbox" class="checkbox" data-id="1"></td>
<td>1</td>
<td>1</td>
<td class="name"><span class='first-name'>Name</span> <span class='sur-name'>Surname</span></td>
<td class="salaireValue">123</td>
<td><input type="text" name="nbreJ" class="form-control" value="1"></td>
<td><input type="text" name="prime" class="form-control" value="0"></td>
</tr>
<tr id="tr_2">
<td>archive</td>
<td><input type="checkbox" class="checkbox" data-id="2"></td>
<td>2</td>
<td>2</td>
<td class="name"><span class='first-name'>Name</span> <span class='sur-name'>Surname</span></td>
<td class="salaireValue">456</td>
<td><input type="text" name="nbreJ" class="form-control" value="1"></td>
<td><input type="text" name="prime" class="form-control" value="0"></td>
</tr>
</table>
I am trying to update my gridview by calculating a few things like TotalPrice and TotalPriceGST. The calculation part works fine. I want to update the fields of TotalPrice and TotalPriceGST when i leave the UnitPriceTxt textbox (On Focus Out). But when i do it with the following code it updates the first row and doesn't allow me to write the price in the later textboxes. Please Help!
<div>
<table cellspacing="0" cellpadding="4" id="ContentPlaceHolder1_gvQuotationItems" style="color:#333333;width:900px;border-collapse:collapse;float: left">
<tr style="color:White;background-color:#F07323;font-weight:bold;">
<th scope="col">Product Code</th>
<th scope="col">Description</th>
<th scope="col">Sap Pack</th>
<th scope="col">Quantity</th>
<th scope="col">UnitPrice</th>
<th scope="col">Total Price</th>
<th scope="col">Total Price with GST</th>
</tr>
<tr style="color:#333333;background-color:#F7F6F3;">
<td style="width:160px;">BCR123A-1EA</td>
<td style="width:250px;">23477, Reference ethanols (H, M, L) (for</td>
<td style="width:30px;">1</td>
<td style="width:60px;">12</td>
<td>
<input type="text" id="UnitPriceTxt" style="width:50px;" />
</td>
<td style="width:60px;"></td>
<td style="width:60px;">
<label id="TotalPriceGST"></label>
</td>
</tr>
<tr style="color:#284775;background-color:White;">
<td style="width:160px;">459-UP</td>
<td style="width:250px;">459 bubbler</td>
<td style="width:30px;">1</td>
<td style="width:60px;">123</td>
<td>
<input type="text" id="UnitPriceTxt" style="width:50px;" />
</td>
<td style="width:60px;"></td>
<td style="width:60px;">
<label id="TotalPriceGST"></label>
</td>
</tr>
<tr style="color:#333333;background-color:#F7F6F3;">
<td style="width:160px;">567-UP</td>
<td style="width:250px;">567 Unprepared Customer Bubbler Purchase</td>
<td style="width:30px;">1</td>
<td style="width:60px;">50</td>
<td>
<input type="text" id="UnitPriceTxt" style="width:50px;" />
</td>
<td style="width:60px;"></td>
<td style="width:60px;">
<label id="TotalPriceGST"></label>
</td>
</tr>
</table>
</div>
This is My Script:
$(function () {
$("#UnitPriceTxt").focusout(function () {
var TextBoxtxt = $('#<%=gvQuotationItems.ClientID %>').find('input:text[id$="UnitPriceTxt"]').val();
var TotalPriceLbl = $('#<%=gvQuotationItems.ClientID %>').find("#totalPrice");
var TotalPriceGSTLbl = $('#<%=gvQuotationItems.ClientID %>').find("#TotalPriceGST");
$("#<%=gvQuotationItems.ClientID %> tr").each(function () {
if (!this.rowIndex) return;
var Quantity = $(this).find("td:eq(3)").html();
var UnitPrce = $(this).find('input:text[id$="UnitPriceTxt"]').val();
var totalPrice = parseInt(Quantity) * parseInt(UnitPrce);
var GST = (parseInt(Quantity) * 17) / 100;
var TotalPriceGST;
TotalPriceGST = totalPrice + GST;
$(this).find("td:eq(5)").html('<label id="totalPrice" style="font-size:small" >' + totalPrice + ".Rs" + '</label>');
$(this).find("td:eq(6)").html('<label id="TotalPriceGST">' + TotalPriceGST + '</label>')
})
})
});
What you want is $('#UnitPriceTxt').blur(function(){...});
$.blur() is the "focus out" function you're looking for.
I have the following form, with several checkboxes. Each set of checkboxes works fine, but when you change an input in the other set of checkboxes, it no longer filters based on the first set (and vice versa).
I need the logic from each set to crossover, and not sure how to achieve that?
$(document).ready(function() {
$("#type :checkbox").click(function() {
$("td").parent().hide();
$("#type :checkbox:checked").each(function() {
$("." + $(this).val()).parent().show();
});
});
$("#fee :checkbox").click(function() {
$("td").parent().hide();
$("#fee :checkbox:checked").each(function() {
$("." + $(this).val()).parent().show();
});
});
});
var repayment = function() {
};
window.onload = function() {
document.repaymentcalc.homevalue.onchange = repayment;
document.repaymentcalc.loanamount.onchange = repayment;
document.repaymentcalc.numberpayments.onchange = function() {
$('#years').html(this.value + ' years');
};
makeSomething();
};
function makeSomething() {
$('tbody tr').each(function(idx, row) {
var $row = $(row);
var initialRateCell = $row.find('td')[2];
var repaymentCell = $row.find('td').last()
var rate = parseFloat($(initialRateCell).html());
var repaymentVal = computeRepayment(rate);
$(repaymentCell).html(repaymentVal.repayment);
});
}
$("#myForm :input").change(function() {
makeSomething();
});
function computeRepayment(rate) {
var x = parseInt(document.repaymentcalc.loanamount.value, 10);
var y = parseInt(rate * 100, 10) / 120000;
var z = parseInt(document.repaymentcalc.numberpayments.value, 10) * 12;
var h = parseInt(document.repaymentcalc.homevalue.value, 10);
var repayment = y * x * Math.pow((1 + y), z) / (Math.pow((1 + y), z) - 1);
var loantovalue = x / h * 100;
var year = z / 12;
return {
repayment: repayment.toFixed(2),
loantovalue: loantovalue,
year: year
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<section id="type">
<p id="Mortgage Type">Mortgage Type</p>
<input type="checkbox" name="type" value="t2" id="t2" />2yr Fixed
<br>
<input type="checkbox" name="type" value="t3" id="t3" />3yr Fixed
<br>
<input type="checkbox" name="type" value="t5" id="t5" />5yr Fixed
<br>
<input type="checkbox" name="type" value="t9" id="t9" />Tracker
<br>
<input type="checkbox" name="type" value="t1" id="t1" checked/>All
<br>
</section>
<section id="fee">
<p id="Fee">Fee</p>
<input type="checkbox" name="fee" value="f2" id="f2" />Fee
<br>
<input type="checkbox" name="fee" value="f3" id="f3" />No Fee
<br>
<input type="checkbox" name="fee" value="f1" id="f1" checked/>All
<br>
</section>
<form name="repaymentcalc" id="myForm" action="">
</br>
<p>
Home Value £
<input type="number" id="homevalue" value="250000" style="width: 75px">
</p>
<p>
Loan Amount £
<input type="number" id="loanamount" value="200000" style="width: 75px">
</p>
Term
<input type="range" id="numberpayments" value="25" min="1" max="40" style="width: 100px">
<div id="years" style="display:inline-block;">25 years</div>
<p>
<div id="ltv">Loan to Value: 80.0%</div>
</div>
</form>
<br>
<div id="mortgagediv">
<table id="mortgagetable">
<thead>
<tr class="productheader">
<th class="lender">Lender</th>
<th class="type">Type</th>
<th class="inititalrate">Initial Rate (%)</th>
<th class="svr">SVR (%)</th>
<th class="apr">Overall APR (%)</th>
<th class="fee">Fee (£)</th>
<th class="ltv">LTV (%)</th>
<th class="repayment">Monthly Repayment (£)</th>
</tr>
</thead>
<tbody>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t2">2yr Fixed</td>
<td class="tg-031e">1.64</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f3"></td>
<td class="tg-031e">70</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t3">3yr Fixed</td>
<td class="tg-031e">1.69</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f3"></td>
<td class="tg-031e">75</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t5">5yr Fixed</td>
<td class="tg-031e">1.79</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f3"></td>
<td class="tg-031e">80</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t9">Tracker</td>
<td class="tg-031e">1.64</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f3"></td>
<td class="tg-031e">70</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t2">2yr Fixed</td>
<td class="tg-031e">1.69</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f2">999</td>
<td class="tg-031e">75</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t3">3yr Fixed</td>
<td class="tg-031e">1.79</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f2">999</td>
<td class="tg-031e">80</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t5">5yr Fixed</td>
<td class="tg-031e">1.79</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f2">999</td>
<td class="tg-031e">80</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t9">Tracker</td>
<td class="tg-031e">1.79</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f2">999</td>
<td class="tg-031e">80</td>
<td class="tg-031e"></td>
</tr>
</tbody>
</table>
</div>
I combined the logic of the two sets into a single callback. It is neither elegant nor efficient, but works.
$(document).ready(function() {
$(":checkbox").click(function() {
$("td").parent().hide();
var selections = [];
$(":checkbox:checked").each(function() {
selections.push("."+$(this).val());
});
$(".product").each(function() {
showRow = true;
for(i=0; i<selections.length; i++){
if (!$(this).children(selections[i]).length){
showRow = false;
}
}
if (showRow) $(this).show();
});
});
});
Here is a demo of it.
You have the event handler on the myform area only
$("#myForm :input").change(function() {
makeSomething();
});
But sections fee and type are outside the form and their change events are never cauth. So, you will need to either move the sections type and fee inside the form myform so they are selected within $("#myForm :input") or add another event handler for the checkboxes.
$("#fee :checkbox").change(function() {
makeSomething();
});
$("#type :checkbox").change(function() {
makeSomething();
});
Check out this fiddle
https://jsfiddle.net/bocanegra_carlos/obcux0d8/
Basically, I think your function should go back to the drawing board when it comes to how you are reading the checkboxes. It can be massively simplified, or at least made more understandable by doing this:
// Store all active classes in this variable
var allActive = [];
// Run this function anytime something changes
function activateClasses(){
// Create a string that jquery can use to search for all the children
var activeClassesString = '.' + allActive.join(', .');
// Instead of looking through _all_ the td elements,
// only look through the parent and search in them.
$('tbody tr').each(function(){
var data = $(this);
// instead of hiding all before, just hide when it finds
// no children with the classes you want
if(allActive.length && !data.find(activeClassesString).length)
data.hide();
// otherwise, show
else
data.show();
});
}
// When your checkbox changes, add the value of it either to the
// array of classes you want to sort, or remove it from the array
$('input[type="checkbox"]').change(function(){
var value = $(this).val();
var index = allActive.indexOf(value);
var checked = $(this).is(':checked');
if(!checked && index > -1)
allActive = allActive.slice(index, 1);
else if(checked && index === -1)
allActive.push(value);
activateClasses();
});
$(document).ready(function() {
var allActive = [];
function activateClasses(){
var activeClassesString = '.' + allActive.join(', .');
$('tbody tr').each(function(){
var data = $(this);
if(allActive.length && !data.find(activeClassesString).length) data.hide();
else data.show();
});
}
$('input[type="checkbox"]').change(function(){
var value = $(this).val();
var index = allActive.indexOf(value);
var checked = $(this).is(':checked');
if(!checked && index > -1)
allActive = allActive.slice(index, 1);
else if(checked && index === -1)
allActive.push(value);
activateClasses();
});
});
var repayment = function() {
};
window.onload = function() {
document.repaymentcalc.homevalue.onchange = repayment;
document.repaymentcalc.loanamount.onchange = repayment;
document.repaymentcalc.numberpayments.onchange = function() {
$('#years').html(this.value + ' years');
};
makeSomething();
};
function makeSomething() {
$('tbody tr').each(function(idx, row) {
var $row = $(row);
var initialRateCell = $row.find('td')[2];
var repaymentCell = $row.find('td').last()
var rate = parseFloat($(initialRateCell).html());
var repaymentVal = computeRepayment(rate);
$(repaymentCell).html(repaymentVal.repayment);
});
}
$("#myForm :input").change(function() {
makeSomething();
});
function computeRepayment(rate) {
var x = parseInt(document.repaymentcalc.loanamount.value, 10);
var y = parseInt(rate * 100, 10) / 120000;
var z = parseInt(document.repaymentcalc.numberpayments.value, 10) * 12;
var h = parseInt(document.repaymentcalc.homevalue.value, 10);
var repayment = y * x * Math.pow((1 + y), z) / (Math.pow((1 + y), z) - 1);
var loantovalue = x / h * 100;
var year = z / 12;
return {
repayment: repayment.toFixed(2),
loantovalue: loantovalue,
year: year
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<section id="type">
<p id="Mortgage Type">Mortgage Type</p>
<input type="checkbox" name="type" value="t2" id="t2" />2yr Fixed
<br>
<input type="checkbox" name="type" value="t3" id="t3" />3yr Fixed
<br>
<input type="checkbox" name="type" value="t5" id="t5" />5yr Fixed
<br>
<input type="checkbox" name="type" value="t9" id="t9" />Tracker
<br>
<input type="checkbox" name="type" value="t1" id="t1" checked/>All
<br>
</section>
<section id="fee">
<p id="Fee">Fee</p>
<input type="checkbox" name="fee" value="f2" id="f2" />Fee
<br>
<input type="checkbox" name="fee" value="f3" id="f3" />No Fee
<br>
<input type="checkbox" name="fee" value="f1" id="f1" checked/>All
<br>
</section>
<form name="repaymentcalc" id="myForm" action="">
</br>
<p>
Home Value £
<input type="number" id="homevalue" value="250000" style="width: 75px">
</p>
<p>
Loan Amount £
<input type="number" id="loanamount" value="200000" style="width: 75px">
</p>
Term
<input type="range" id="numberpayments" value="25" min="1" max="40" style="width: 100px">
<div id="years" style="display:inline-block;">25 years</div>
<p>
<div id="ltv">Loan to Value: 80.0%</div>
</div>
</form>
<br>
<div id="mortgagediv">
<table id="mortgagetable">
<thead>
<tr class="productheader">
<th class="lender">Lender</th>
<th class="type">Type</th>
<th class="inititalrate">Initial Rate (%)</th>
<th class="svr">SVR (%)</th>
<th class="apr">Overall APR (%)</th>
<th class="fee">Fee (£)</th>
<th class="ltv">LTV (%)</th>
<th class="repayment">Monthly Repayment (£)</th>
</tr>
</thead>
<tbody>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t2">2yr Fixed</td>
<td class="tg-031e">1.64</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f3"></td>
<td class="tg-031e">70</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t3">3yr Fixed</td>
<td class="tg-031e">1.69</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f3"></td>
<td class="tg-031e">75</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t5">5yr Fixed</td>
<td class="tg-031e">1.79</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f3"></td>
<td class="tg-031e">80</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t9">Tracker</td>
<td class="tg-031e">1.64</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f3"></td>
<td class="tg-031e">70</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t2">2yr Fixed</td>
<td class="tg-031e">1.69</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f2">999</td>
<td class="tg-031e">75</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t3">3yr Fixed</td>
<td class="tg-031e">1.79</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f2">999</td>
<td class="tg-031e">80</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t5">5yr Fixed</td>
<td class="tg-031e">1.79</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f2">999</td>
<td class="tg-031e">80</td>
<td class="tg-031e"></td>
</tr>
<tr class="product">
<td class="tg-031e">Nationwide</td>
<td class="t1 t9">Tracker</td>
<td class="tg-031e">1.79</td>
<td class="tg-031e">3.99</td>
<td class="tg-031e">3.40</td>
<td class="f1 f2">999</td>
<td class="tg-031e">80</td>
<td class="tg-031e"></td>
</tr>
</tbody>
</table>
</div>
Make better use of variables as well, as your code is very heavy. For example, instead of letting jQuery compile a list of all the tds in your document every time, assign it to a global variable. If td should be added dynamically, only update this global variable when new ones are added. That means the jQuery object already exists and there is no time involved in recompiling it, speeding up your code. At the moment that makes little difference, but once your list becomes long enough you will feel some slowdown. I'm also very sure that classes are maybe not your best option here. Maybe data- attributes are better suited, so your tr looks like this:
<tr data-lender="nationwide" data-type="2-years-fixed" data-rate="1.64" data-svr="1.5" /* ... and so on ...*/ ></tr>
The reason you'd want to do that is because this is much more legible than your arbitrary classes - you will get lost in the arbitrary classes you used as they are in no way obvious. Which is more obvious: 'show me a lender with tg-031e f1 f2' or 'Show me a lender with 2-years-fixed type'? (I know its not correct, they aren't saying the same thing, but that's only because I am already getting lost in the technical terms.) Think of the developer that might come after you, and the headache you will be creating. Don't be afraid to use a couple more characters if it makes things more obvious to read, as it will save you a boatload of time in the long run.