This is a table for user to record Expenses and Amount. User can add table cell to record more items with the amount. After user key in the Amount, it will show 7% tax at beside and total amount at the top. But now i am facing 2 problems.
If user added 2 items, and input the 2 items' amount, then if they deleted the row, the total amount will not deduct after the row is deleted.
the tax will only added in first row. I want to do it in each row with 7% tax with each item's amount.
So can i know how to solve this 2 problems?
function validate(evt) {
var theEvent = evt || window.event;
var key = theEvent.keyCode || theEvent.which;
key = String.fromCharCode(key);
var regex = /[0-9]|\./;
if (!regex.test(key)) {
theEvent.returnValue = false;
if (theEvent.preventDefault) theEvent.preventDefault();
}
}
function force2decimals(event) {
var value = $(event).val();
var format_val = parseFloat(value).toFixed(2);
$(event).val(format_val);
}
//<----------------------2 Decimal force END-------------------->
// +
function mFunction() {
document.getElementById("rowrow").insertRow(-1).innerHTML =
'<tr><td></td><td><output id="gst">0.00</output></td><td><input type="text" name="Amount[]" id="columninput" class="input" oninput="myFunction(this.value)" placeholder="Amount" style="font-size:14px;" min="0" lang="en-150" onchange="force2decimals(this)" onkeypress="validate(event)" inputmode="numeric"></td></tr>';
}
// -
function remove() {
var x = document.getElementById("rowrow").rows.length;
if (x == 1) {} else {
document.getElementById("rowrow").deleteRow(-1);
};
}
function myFunction() {
const ele = document.querySelectorAll('input.input');
let sum = 0;
ele.forEach(input => {
sum += input.value ? parseFloat(input.value) : 0;
});
document.getElementById('result').textContent = sum.toFixed(2);
document.getElementById('gst').textContent = (sum * 0.07).toFixed(2);
}
.css-serial {
counter-reset: serial-number;
}
.css-serial td:first-child:before {
counter-increment: serial-number;
content: counter(serial-number);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<div id="container">
<div id="body">
<br>
<div class="row">
<div class="css-serial" style="overflow-x:auto;">
<table id="rowrow">
<tr>
<td id="number"></td>
<td><output id="gst">0.00</output></td>
<td><input type="text" name="Amount[]" class="input" oninput="myFunction(this.value)" id="columninput" placeholder="Amount" style="font-size:14px;" min="0" lang="en-150" onchange="force2decimals(this)" onkeypress='validate(event)' inputmode='numeric'
required></td>
Total Amount <output id="result"> 0.00 </output>
<input type="button" id="slipbutton1" onclick="mFunction();" name='add' value="+" />
<input type="button" id="slipbutton2" onclick="remove();" name='remove' value="-" /><br><br>
</table>
</div>
</div>
<br>
</div>
</div>
I have managed to make changes as per your need, also I have used jquery as you had added into your code.
I have calculated output in the remove() you can move it to a common function to avoid dirty code.
function remove() {
var x = document.getElementById("rowrow").rows.length;
if (x == 1) {} else {
var ele = document.querySelectorAll('input.input');
let sum = 0;
ele.forEach(input => {
sum += input.value ? parseFloat(input.value) : 0;
});
sum = sum - ele[ele.length - 1].value;
document.getElementById('result').textContent = sum.toFixed(2);
document.getElementById("rowrow").deleteRow(-1);
};
}
Changed GST id to class, as id should be unique.
Added this line of code to print GST into each row.
$(input).parents("tr").find(".gst").text((input.value * 0.07).toFixed(2));
you had added 2 class attributes to input in JS template, also merged them.
<tr>
<td></td>
<td><output class="gst">0.00</output></td>
<td>
<input
type="text"
name="Amount[]"
class="columninput input" // This line
oninput="myFunction(this.value)"
placeholder="Amount"
style="font-size:14px;"
min="0" lang="en-150"
onchange="force2decimals(this)"
onkeypress="validate(event)"
inputmode="numeric"
>
</td>
</tr>
function validate(evt) {
var theEvent = evt || window.event;
var key = theEvent.keyCode || theEvent.which;
key = String.fromCharCode(key);
var regex = /[0-9]|\./;
if (!regex.test(key)) {
theEvent.returnValue = false;
if (theEvent.preventDefault) theEvent.preventDefault();
}
}
function force2decimals(event) {
var value = $(event).val();
var format_val = parseFloat(value).toFixed(2);
$(event).val(format_val);
}
//<----------------------2 Decimal force END-------------------->
// +
function mFunction() {
document.getElementById("rowrow").insertRow(-1).innerHTML =
'<tr><td></td><td><output class="gst">0.00</output></td><td><input type="text" name="Amount[]" class="columninput input" oninput="myFunction(this.value)" placeholder="Amount" style="font-size:14px;" min="0" lang="en-150" onchange="force2decimals(this)" onkeypress="validate(event)" inputmode="numeric"></td></tr>';
}
// -
function remove() {
var x = document.getElementById("rowrow").rows.length;
if (x == 1) {} else {
var ele = document.querySelectorAll('input.input');
let sum = 0;
ele.forEach(input => {
sum += input.value ? parseFloat(input.value) : 0;
});
sum = sum - ele[ele.length - 1].value;
document.getElementById('result').textContent = sum.toFixed(2);
document.getElementById("rowrow").deleteRow(-1);
};
}
function myFunction() {
debugger
var ele = document.querySelectorAll('input.input');
let sum = 0;
ele.forEach(input => {
sum += input.value ? parseFloat(input.value) : 0;
$(input).parents("tr").find(".gst").text((input.value * 0.07).toFixed(2));
});
document.getElementById('result').textContent = sum.toFixed(2);
//document.getElementById('gst').textContent = (sum * 0.07).toFixed(2);
}
.css-serial {
counter-reset: serial-number;
}
.css-serial td:first-child:before {
counter-increment: serial-number;
content: counter(serial-number);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="body">
<br>
<div class="row">
<div class="css-serial" style="overflow-x:auto;">
<table id="rowrow">
<tr>
<td id="number"></td>
<td><output class="gst">0.00</output></td>
<td><input type="text" name="Amount[]" class="input" oninput="myFunction(this.value)" id="columninput" placeholder="Amount" style="font-size:14px;" min="0" lang="en-150" onchange="force2decimals(this)" onkeypress='validate(event)' inputmode='numeric'
required></td>
Total Amount <output id="result"> 0.00 </output>
<input type="button" id="slipbutton1" onclick="mFunction();" name='add' value="+" />
<input type="button" id="slipbutton2" onclick="remove();" name='remove' value="-" /><br><br>
</table>
</div>
</div>
<br>
</div>
</div>
Related
I Want to hide element if another div's length is greater than 0, otherwise show the div
i have this code but it is not working for me :(
<div id="myid">90.00</div>
<div class="myclass">99.00</div>
JS code
$(document).ready(function() {
if($('#myid').length > 2){
$('.myclass').hide();
}
});
First edit your question by your new detail;
Then set your condition inside your updateTotalFinal function
jQuery(document).ready(function() {
function updateTotalFinal(){
const subtotalValue = +jQuery('.wpforms-payment-total').text().replace(/^[^0-9,.]+/, "").match( /^[0-9,.]+/g, '');
let totalValue = subtotalValue;
const totalFinalElem = jQuery("#totalfinal");
jQuery("input.change-total:checked").each(function() {
const $this = jQuery(this);
if ($this.is("[data-method=add]")) {
totalValue = totalValue * $this.data("amount");
} else if ($this.is("[data-method=multiply]")) {
totalValue += subtotalValue * $this.data("amount");
}
});
totalFinalElem.text(`${totalValue.toFixed(2)}`);
// IF YOU WANT CHECK THAT ANY VALUE FOR totalfinal IS EXIST USE THIS
if($('#totalfinal').text().length ){
$('.wpforms-payment-total').hide();
}
// IF YOU WANT CHECK THAT totalfinal IS GREATHER THAN ZERO USE THIS
/* if(parseInt( $('#totalfinal').text()) > 0 ){
$('.wpforms-payment-total').hide();
} */
}
jQuery("input.change-total").on("change", function() {
updateTotalFinal();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wpforms-payment-total">
97
</div>
<tr>
<td>
<input type="checkbox" class="change-total" name="myBox2" size="12" data-amount="0.15" data-method="multiply" value="100" />
With Two Coat + 15%
</td>
<td>
<input type="checkbox" class="change-total" name="myBox3" size="12" id="myCheck" data-amount="0.9" data-method="add" />
With My Own Paint
</td>
</tr>
<br>
<b><span id="totalfinal"></span></b>
i have this code and want to hide
class "wpforms-payment-total" when "totalfinal" is calculated
<div class="wpforms-payment-total">
97
</div>
<tr>
<td>
<input type="checkbox" class="change-total" name="myBox2" size="12" data-amount="0.15" data-method="multiply" value="100" />
With Two Coat + 15%
</td>
<td>
<input type="checkbox" class="change-total" name="myBox3" size="12" id="myCheck" data-amount="0.9" data-method="add" />
With My Own Paint
</td>
</tr>
<br>
<b><span id="totalfinal"></span></b>
JS
jQuery(document).ready(function() {
function updateTotalFinal(){
const subtotalValue = +jQuery('.wpforms-payment-total').text().replace(/^[^0-9,.]+/, "").match( /^[0-9,.]+/g, '');
let totalValue = subtotalValue;
const totalFinalElem = jQuery("#totalfinal");
jQuery("input.change-total:checked").each(function() {
const $this = jQuery(this);
if ($this.is("[data-method=add]")) {
totalValue = totalValue * $this.data("amount");
} else if ($this.is("[data-method=multiply]")) {
totalValue += subtotalValue * $this.data("amount");
}
});
totalFinalElem.text(`$ ${totalValue}`);
}
jQuery("input.change-total").on("change", function() {
updateTotalFinal();
});
});
$(document).ready(function() {
if($('#totalfinal').text() > 0){
$('.myclass').hide();
}
});
Given this HTML code:
<body onload="assessSum()">
<input type="number" id="num0" min="0" max="10">
<input type="number" id="num1" min="0" max="10">
<button type="submit" id="sub">Submit</button>
</body>
What would be a function that would disable the submit button, if the sum of the 2 input fields is greater than a certain value?
My JavaScript/Jquery code doesn't seem to work:
function assessSum(){
var total = 0;
var maximum = 5;
var bt = document.getElementById('sub');
$.each($("input"),function(){
total += parseInt($(this).val()) || 0;
});
if(total > maximum){
bt.disabled = true;
}
else{
bt.disabled = false;
}
}
You need to run the function on change event of the inputs.
$(':input').on('change', assessSum);
function assessSum() {
var total = 0;
var maximum = 5;
var bt = document.getElementById('sub');
$("input").each((i, el) => {
total += (parseInt(el.value) || 0);
});
if (total > maximum) {
bt.disabled = true;
} else {
bt.disabled = false;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="number" id="num0" min="0" max="10">
<input type="number" id="num1" min="0" max="10">
<button type="submit" id="sub">Submit</button>
The disabling can also be done like this:
$('#sub').attr('disabled', (total > maximum));
I know that + is used for both addition and concatenation, it depends on what the variable type is. I have tried using Number() and parseFloat(), but I can't seem to get them to work. Here is my code:
var grandtotal;
$("#table tr").each(function () {
var row = $(this).closest('tr');
var totalprice = row.find('input[id^="TotalPrice"]').val();
grandtotal += totalprice;
});
$(".total_price").html(grandtotal);
This code gives me an output like this:
NaN1081083936354412531.5105
However, if I add Number() or parseFloat() to the totalprice line like this:
grandtotal += Number(totalprice);
OR
grandtotal += parseFloat(totalprice);
I get nothing returned.
Anybody have any idea what I need to change? Thank you.
EDIT: I have changed the controller code to this:
var grandtotal = 0;
$("#table tr").each(function () {
var row = $(this).closest('tr');
var totalprice = parseFloat(row.find('input[id^="TotalPrice"]').val());
grandtotal += totalprice;
});
$(".total_price").html(grandtotal);
Here is the HTML in question:
<td>
<div class="input-group"> <div class="input-group-addon">$ </div>
<input readonly="readonly" readonly id="TotalPrice{{ $loop->iteration }}" name="TotalPrice[]" placeholder="" class="form-control input-md" step="0.01" type="number" value="{{ $item->TotalPrice }}">
</div>
</td>
I am still getting a blank output.
Making grandtotal to 0 with parseFloat() will solve your problem. You are trying to add tr values to undefined variable.
// give grand total a value
var grandtotal = 0;
$(document).ready(function(){
$("#table tr").each(function () {
var row = $(this).closest('tr');
var totalprice = parseFloat(row.find('input[id^="TotalPrice"]').val());
grandtotal += totalprice;
});
$(".total_price").html(grandtotal);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="table">
<tr>
<td>
<input type="text" id="TotalPrice" value="1000.50"/>
</td>
</tr>
<tr>
<td>
<input type="text" id="TotalPrice" value="2000"/>
</td>
</tr>
<tr>
<td>
<input type="text" id="TotalPrice" value="10"/>
</td>
</tr>
</table>
<div class="total_price"></div>
Try checking isNaN:
// Inside each
if (totalprice && totalprice.length > 0 && !isNaN(totalprice)) {
grandtotal += parseFloat(totalprice);
}
function getFloat(val) {
if (val && val.length > 0 && !isNaN(val)) {
return parseFloat(val);
}
return null;
}
console.log("getFloat($('#inp1').val()): " + getFloat($('#inp1').val()));
console.log("getFloat($('#inp2').val()): " + getFloat($('#inp2').val()));
console.log("getFloat($('#inp3').val()): " + getFloat($('#inp3').val()));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="inp1" type="text" value="" />
<input id="inp2" type="text" value="literal" />
<input id="inp3" type="text" value="100" />
I need to solve some calculations and I'm using an .each() loop. I'm populating rows <tr> dynamically so I use .each() to loop through the table but I can't get different values when I have to sort them by vat value.
function callSum(id) {
var counter = 1;
var sum = document.getElementById("sum" + id).value;
var vat = document.getElementById("vat" + id).value;
$('.sumall').each(function() {
$('.vatall').each(function() {
if ($(this).val() == 0) { //if value of VAT is 0 sum it to vatTotalZero
document.getElementById("vatTotalZero").value = $(this, ".sumall").val; // don't know how to solve this
} else { //if value of VAT is > 0 sum it to vatTotal
document.getElementById("vatTotal").value = $(this, ".sumall").val; // don't know how to solve this
}
counter++;
});
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<tr>
<td class="col-sm-1">
<input type="text" name="sum[]" id="sum1" onfocus="callSum(1)" class="sumall form-control"/>
</td>
<td class="col-sm-1">
<input type="text" name="vat[]" id="vat1" class="vatall form-control "/>
</td>
</tr>
<br><br>
<label>All Sums without VAT (vat 0)</label>
<input type="text" name="vatTotalZero" id="vatTotalZero" class="form-control "/>
<br><br>
<label>All Sums with VAT (vat > 0)</label>
<input type="text" name="vatTotal" id="vatTotal" class="form-control "/>
Please see disrciptive comments in the source code.
function callSum(id) {
var counter = 1,
sum = document.getElementById("sum" + id).value,
vat = document.getElementById("vat" + id).value,
sumallVal;
$('.sumall').each(function () {
/* get the value */
sumallVal = $(this).val();
$('.vatall').each(function () {
if ($(this).val() == 0) { //if value of VAT is 0 sum it to vatTotalZero
//document.getElementById("vatTotalZero").value = $(this, ".sumall").val; // don't know how to solve this
/* set the value */
$("#vatTotalZero").val( sumallVal )
} else { //if value of VAT is > 0 sum it to vatTotal
//document.getElementById("vatTotal").value = $(this, ".sumall").val; // don't know how to solve this
/* set the value */
$("#vatTotal").val( sumallVal )
}
counter++;
});
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<tr>
<td class="col-sm-1">
<!-- <input type="text" name="sum[]" id="sum1" onfocus="callSum(1)" class="sumall form-control" /> -->
<input type="text" name="sum[]" id="sum1" onchange="callSum(1)" class="sumall form-control" />
</td>
<td class="col-sm-1">
<input type="text" name="vat[]" id="vat1" class="vatall form-control " />
</td>
</tr>
<br>
<br>
<label>All Sums without VAT (vat 0)</label>
<input type="text" name="vatTotalZero" id="vatTotalZero" class="form-control " />
<br>
<br>
<label>All Sums with VAT (vat > 0)</label>
<input type="text" name="vatTotal" id="vatTotal" class="form-control " />
Here we go with an enhanced version.
In this version I removed unused stuff, set an appropriate event handler and shortened the syntax slightly
function callSum(id) {
var sum = document.getElementById("sum" + id).value,
vat = document.getElementById("vat" + id).value,
sumallVal;
$('.sumall').each(function () {
/* get the value */
sumallVal = $(this).val();
$('.vatall').each(function () {
/* set the value */
$( $(this).val() == 0 ? "#vatTotalZero" : "#vatTotal" ).val( sumallVal )
});
});
}
$(document).ready(function() {
$('.sumall.form-control').on('input', function() {
// get number id directly from string id by deleting all non numbers
callSum( this.id.replace(/[^0-9]/gi, '') );
})
});
<tr>
<td class="col-sm-1">
<!-- <input type="text" name="sum[]" id="sum1" onfocus="callSum(1)" class="sumall form-control" /> -->
<input type="text" name="sum[]" id="sum1" class="sumall form-control" />
</td>
<td class="col-sm-1">
<input type="text" name="vat[]" id="vat1" class="vatall form-control " />
</td>
</tr>
<br>
<br>
<label>All Sums without VAT (vat 0)</label>
<input type="text" name="vatTotalZero" id="vatTotalZero" class="form-control " />
<br>
<br>
<label>All Sums with VAT (vat > 0)</label>
<input type="text" name="vatTotal" id="vatTotal" class="form-control " />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I have a table that dynamically calculates and create new row. Here is a snippet of the:
<table>
<tr class="purchase_schedule_table">
<td><input type="text" name="purchase_place" class="purchase_place_info" style="width: 90%;" ></td>
<td><input type="text" name="main_products_purch" style="width: 90%;" class="main_products_purch_info" ></td>
<td><input type="number" name="frequency" style="width: 90%;" class="frequency" ></td>
<td><input type="number" name="low" style="width: 90%;" class="product_low" ></td>
<td><input type="number" name="high" style="width: 90%;" class="product_high" ></td>
<td><input type="number" name="average" style="width: 90%;" class="product_average" disabled ></td>
<td>
<div class = "input-group" id="addrow">
<input type="number" name="product_total" style="width: 90%;" class="product_total" disabled>
<span class = "input-group-addon" style="width:1%; background-color:#786bae;border-color:#786bae;">
<a href="#">
<span style="color:#FFFFFF;font-size:9px;line-height: 1.5;border-radius:0 !important;" class="glyphicon glyphicon-plus addrow" aria-hidden="true"></span>
</a>
</span>
</div>
</td>
</tr>
</table>
Here is a snippet of jquery code to calculate the values:
//calculate purchase schedule monthly total
function calculatePurchaseScheduleMonthlyTotal(){
var total_sum = 0;
$('.product_total').each(function () {
var value = $(this).val();
total_sum = parseInt(total_sum) + parseInt(value);
});
$('.total_sum').val(total_sum);
};
//calculate purchase schedule
function calculatePurchaseSchedule(ObjRow) {
var low = 0;
var high = 0;
var average = 0;
var frequency = 0;
var total = 0;
var total_sum = 0;
frequency = ($(ObjRow).find('.frequency').val() == "") ? 0 : $(ObjRow).find('.frequency').val();
high = ($(ObjRow).find('.product_high').val() == "") ? 0 : $(ObjRow).find('.product_high').val();
low = ($(ObjRow).find('.product_low').val() == "") ? 0 : $(ObjRow).find('.product_low').val();
average = (parseInt(high) + parseInt(low)) / 2;
total = average * frequency;
$(ObjRow).find('.product_total').val(total);
$(ObjRow).find('.product_average').val(average);
calculatePurchaseScheduleMonthlyTotal();
};
Here is also a snippet of the code that is use to trigger the calculation:
$(document).on('focusout','input[type=number]',function () {
calculatePurchaseSchedule($(this).closest('tr'));
saveData();
});
Here is the code for adding a table row dynamically:
$('#addrow').click(function (e) {
e.preventDefault();
var purchase_schedule_row = '<tr class="purchase_schedule_table"><td> <input type="text" name="purchase_place" class="purchase_place" style="width: 90%;"></td><td><input type="text" name="main_products_purch" style="width: 90%;" class="main_products_purch"></td><td><input type="number" name="frequency" style="width: 90%;" class="frequency"></td><td><input type="number" name="low" style="width: 90%;" class="product_low"></td> <td><input type="number" name="high" style="width: 90%;" class="product_high"></td> <td><input type="number" name="average" style="width: 90%;" class="product_average" disabled></td><td> <div class = "input-group" id="addrow"> <input type="number" name="total" style="width: 90%;" class="product_total" disabled><span class = "input-group-addon" style="width:1%; background-color:#ec6d65;border-color:#ec6d65;"> <span style="color:#FFFFFF;font-size:9px;line-height: 1.5;border-radius:0 !important;" class="glyphicon glyphicon-minus deleterow" aria-hidden="true"></span></span></div></td></tr>';
$('#purchaseScheduleTable').append(purchase_schedule_row);
});
What I want to do is to store each table row td element value as a array of objects. I have tried doing so in the following code:
var purchase_place;
var main_products_purch;
var frequency;
var product_low;
var product_high;
var product_average;
var product_total;
var product_total_sum;
var purchase_schedule_table = [];
var purchase_schedule_data = {};
var count = 1;
$('.purchase_schedule_table').each(function(){
$(this).find('.product_total').each(function () {
product_total = $(this).find('.product_total').val();
console.log(product_total);
purchase_schedule_data.product_total = product_total;
});
purchase_schedule_table.push(purchase_schedule_data);
});
console.log(purchase_schedule_table);
For example, the end result should be like this:
[
{purchase_place: 'purchase_place', main_products_purch : 'main_products_purch', frequency:'frequency', product_average: 'product_averager'}
{purchase_place: 'purchase_place', main_products_purch : 'main_products_purch', frequency:'frequency', product_average: 'product_averager'}
]
What am I doing wrong? Thanks in advance.
Iterate through each tr with class purchase_schedule_table and then each td in it, make an object and push it in a an array like following.
var arr = [];
$('.purchase_schedule_table').each(function () {
var obj = {};
$(this).find('td').each(function () {
var input = $(this).find('input')[0];
obj[input.name] = input.value;
});
arr.push(obj);
})
console.log(arr)