I would like to calculate and populate the grand total automatically before submiting the form. The grand total will base on my 5 input fields.
<input type="number" name="inspection_fee">
<input type="number" name="storage_fee">
<input type="number" name="local_fee">
<input type="number" name="cert_fee">
<input type="number" name="others_fee">
<input type="number" name="total_fee">
I know how to do it the php way like it would put variables after I submit it then calculate it totally like this.
<?php
$inspection_fee = $paymentSettings->inspection_fee;
$storage_fee = $paymentSettings->storage_fee;
$cert_fee = $paymentSettings->cert_fee;
$local_fee = $paymentSettings->local_fee;
$others_fee = $paymentSettings->others_fee;
$total_fee = $inspection_fee + $storage_fee + $cert_fee + $local_fee + $others_fee;
?>
But how would I populate the total before submiting it using javascript? Like if I change the inspection fee the total fee will auto adjust depends on the total value.
Looking for help.
Thanks in advance.
Set the total input field to read-only
Create a function to add up all the inputs and set the value in total_fee (good opportunity to use Array.prototype.reduce)
Bind your function to the inputs input event
const inputs = ['inspection_fee', 'storage_fee', 'local_fee', 'cert_fee', 'others_fee']
const total = document.querySelector('input[name="total_fee"]')
const sumTotal = () => {
total.value = inputs.reduce((sum, input) =>
sum += parseInt(document.querySelector(`input[name="${input}"]`).value || 0, 10), 0)
}
inputs.forEach(input => {
document.querySelector(`input[name="${input}"]`).addEventListener('input', sumTotal, false)
})
<input type="number" name="inspection_fee">
<input type="number" name="storage_fee">
<input type="number" name="local_fee">
<input type="number" name="cert_fee">
<input type="number" name="others_fee">
<input type="number" name="total_fee" readonly>
Attach onblur event to all input fields to call a JavaScript function. I have changed the "name" attribute to "id" attribute to be used in the JS function.
<input type="number" id="inspection_fee" onblur="calculateTotalFee();">
<input type="number" id="storage_fee" onblur="calculateTotalFee();">
<input type="number" id="local_fee" onblur="calculateTotalFee();">
<input type="number" id="cert_fee" onblur="calculateTotalFee();">
<input type="number" id="others_fee" onblur="calculateTotalFee();">
<br/>
<input type="number" id="total_fee">
<script type="text/javascript">
function calculateTotalFee(){
var totalFee = 0;
var inspectionFee = document.getElementById("inspection_fee").value.trim() === "" ? 0 :
document.getElementById("inspection_fee").value.trim();
var storageFee = document.getElementById("storage_fee").value.trim() === "" ? 0 :
document.getElementById("storage_fee").value.trim();
var localFee = document.getElementById("local_fee").value.trim() === "" ? 0 :
document.getElementById("local_fee").value.trim();
var certFee = document.getElementById("cert_fee").value.trim() === "" ? 0 :
document.getElementById("cert_fee").value.trim();
var othersFee = document.getElementById("others_fee").value.trim() === "" ? 0 :
document.getElementById("others_fee").value.trim();
totalFee = parseInt(inspectionFee) + parseInt(storageFee) +
parseInt(storageFee) + parseInt(localFee) + parseInt(certFee) + parseInt(othersFee);
document.getElementById("total_fee").value = totalFee;
}
</script>
Related
I'm trying to make a simple inventory systems. But I'm having problem with my oninput event.
I want to make TOTAL GOODS to be "Please input number in GOODS IN " whenever every non number value inserted into GOODS IN. But it seems I can't make it so.
/*MAKE EVERY TABLE CLICKABLE AND SHOW ROW DATA IN INPUT TEXT*/
var tbGoods = document.getElementById('tbGoods');
for (var i = 0; i < tbGoods.rows.length; i++) {
tbGoods.rows[i].onclick = function() {
document.getElementById("idTxt").value = this.cells[1].innerHTML;
document.getElementById("gdTxt").value = this.cells[2].innerHTML;
document.getElementById("qtyTXT").value = this.cells[3].innerHTML;
var qty = parseInt(document.getElementById('qtyTXT').value);
var x = parseInt(document.getElementById('gdin').value);
var result = qty - x;
document.getElementById('totalgd').value = result;
};
}
/*MAKE EVERY NUMBER I PUT IN GOODS IN, TO BE CALCULATED WITHOUT SUBMIT BUTTON (ONINPUT)*/
function testmin() {
var qty = parseInt(document.getElementById('qtyTXT').value);
var x = parseInt(document.getElementById('gdin').value);
var result = qty - x;
if (document.getElementById('gdin').value === '') {
document.getElementById('totalgd').value = '0';
} else if (document.getElementById('qtyTXT').value === '') {
document.getElementById('totalgd').value = '0';
} else if (Number.isNaN(document.getElementById('gdin').value)) {
document.getElementById('totalgd').value = 'Please Input Number in Goods In';
} else {
document.getElementById('totalgd').value = result;
}
}
<form method="post">
<label>ID</label>
<input type="text" name="id" id="idTxt" disabled>
<label>GOODS</label>
<input type="text" name="goods" id="gdTxt" disabled>
<label>AVAILABLE QTY</label>
<input type="text" name="qty" id="qtyTXT" disabled>
<label>GOODS IN</label>
<input type="text" name="gdin" id="gdin" oninput="testmin()">
<br>
<br>
<label>Total Goods</label>
<input type="text" name="totalgd" id="totalgd" value="0" disabled>
<br>
<input type="submit" name="submit" value="submit">
</form>
You don't need to code that manually. You can simply set the input type as "number" and your browser will not allow any non-numeric characters to be entered into the field.
Demo (run the snippet and try typing in the box):
<input type="number" id="gdin" name="gdin"/>
Reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number
Just add type = "number" in the input label for TOTAL GOODS. It should prevent user from entering any alphabet. Except "e"
<input type="number" name="totalgd" id="totalgd" value="0" disabled>
As pointed out, if you want to show an alert or something when an input of alphabet is there in TOTAL GOODS, you can just add
<input type="text" name="totalgd" id="totalgd" value="0" oninput = "checkFunction()" disabled>
and in the function you can check the input for :
function checkFunction() {
let totalGoodsIn = document.getElementById("totalgd").value;
let regExp = /[a-zA-Z]/g;
if(regExp.test(totalGoodsIn))
{
//logic if alphabet is present in TOTAL GOODS
}
else
{
//logic if alphabet is not present in TOTAL GOODS
}
}
if you want GOODS IN to be numeric just change the type of the label accordingly
function validateNumberField() {
var value = $("#numberField").val();
var pattern = /^\d+$/;
var isValid = pattern.test(value);
if(!isValid){
document.getElementById('totalgd').value = 'Please Input Number in Goods In';
}
}
<p>Please enter number :</p>
<input type="number" id="numberField" name="numberField"
oninput="validateNumberField()" />
I want to calculate result for each row, I used javascript that add multiple rows, and I want calculation on every row.
function sub() {
var txtFirstNumberValue = document.getElementById('AB[]').value;
var txtSecondNumberValue = document.getElementById('RAB').value;
var resultMul = parseInt(txtFirstNumberValue) * parseInt(txtSecondNumberValue);
var textthired = document.getElementById('RQP').value;
var result = parseInt(textthired) + parseInt(resultMul);
if (!isNaN(result)) {
document.getElementById('TA[]').value = result;
}
}
<input type="number" name="AB[]" onkeyup="sub();" id="AB[]" min="5" max="1000" required>
<input type="text" name="TA[]" id="TA[]" readonly>
<input type="text" name="RQP" value="1500" readonly onkeyup="sub();" id="RQP">
<input type="text" name="RAB" value="50" readonly onkeyup="sub();" id="RAB">
First of all last two fields are readonly so keyup function will not work.
Second you add value only when there is any entry in the field by checking entered value as greater than 0
i have multiple input number fields with the same class, and i have to sum them but when I try with my javascript i get always NaN result
var arrNumber = new Array(); //contain the number of specific input field
var totale;
$(".input-n-pro").bind('keyup mouseup', function () {
totale = 0;
$('.input-n-pro').each(function(){
var this_num = $(this).val();
totale = parseInt(this_num)+parseInt(totale);
})
console.log("totale="+totale);
});
The html of input is this, generated by php, one for every row of a table
<input type="number" name="<?php echo $data["name"];?>" min="0" max="500" placeholder="0" class="form-control input-xs input-n-pro" style="display: inline">
I don't know it won't work, it work with only js withous jquery but i have to get the id of every field to do that and i want to do that for everyone with the same class because they are dinamic fields
P.S. The other part of my work, is to get every name of those fields and store them so i can have an array in js where i have the name of input and his number value, but i don't know how to do because they are dinamic
You probably parsing something that is not an integer. Then the parseInt won't work and returns NaN. If you sum a NaN, then it stays a NaN, example:
// working testcase:
const testArray = ['2', '3', '4'];
let total = 0;
for (value of testArray) {
total += parseInt(value);
}
// returns 9
console.log(total);
// your testcase:
const testArray2 = ['2', '3', 'notANumber'];
let total2 = 0;
for (value of testArray2) {
total2 += parseInt(value);
}
// returns NaN since we are adding 2 + 3 + NaN = NaN
console.log(total2);
So the solution is to 'negate' the NaN by treating it as 0:
// solution:
const myArray = ['2', '3', 'notANumber', '4'];
let total = 0;
for (value of myArray) {
// treat NaN, undefined or any falsey values as 0.
total += parseInt(value) || 0;
}
// returns 9
console.log(total);
To integrate this concept in your code, you'll get something like:
let total = 0;
$('.input-n-pro').each(() => {
let valueInString = $(this).val();
let actualValue = parseInt(valueInString) || 0;
total += actualValue;
});
if one of inputs value is empty then parseInt returns NAN. So you can better do a check using IsNan function. if input is empty than assign 0. For example;
var x= parseInt($('#abc').val()); if (isNaN(x)) x = 0;
Part 1 and 2 of your question
The reason you get NaN is most probably that if any of the inputs has no value, asking for that value returns an empty string (form fields always return strings) "". parseInt("") returns NaN.
Using vanilla ECMAScript 6, the solution is a one-liner with the help of Array.prototype.reduce:
const sum = [...document.querySelectorAll('.input-n-pro')].reduce((acc, val) => acc += Number(val.value) || 0, 0);
For your second question, just use Array.prototype.map. Also a one-liner.
const theArr = [...document.querySelectorAll('.input-n-pro')].map(x => {return { name: x.name, value: parseInt(x.value) || 0 }});
Note: The Array spread operator [...document.querySelectorAll('.input-n-pro')] makes an array from the NodeList document.querySelectorAll returns, so you can use Array methods on the list (like reduce and map).
Example:
calc.addEventListener('click', () => {
const sum = [...document.querySelectorAll('.input-n-pro')].reduce((acc, val) => acc += Number(val.value) || 0, 0);
console.log(sum);
})
getArr.addEventListener('click', () => {
const theArr = [...document.querySelectorAll('.input-n-pro')].map(x => {return { name: x.name, value: parseInt(x.value) || 0 }});
console.log(theArr);
})
<input type="number" value="5" class="input-n-pro" name="a" />
<input type="number" value="3" class="input-n-pro" name="b" />
<!-- lets insert one input that contains no number -->
<input type="text" value="foo" class="input-n-pro" name="m" />
<input type="number" value="2" class="input-n-pro" name="c" />
<input type="number" value="11" class="input-n-pro" name="d" />
<input type="number" class="input-n-pro" name="e" />
<br />
<button id="calc" type="button">Calculate Sum</button>
<button id="getArr" type="button">Get Array of name-value pairs</button>
bind() has been deprecated => use on
arrNumber = [], //contain the number of specific input field
totale = 0;
doTotale(); // first round
$(".input-n-pro").on('keyup mouseup change', doTotale);
function doTotale()
{
totale = 0;
arrNumber.length = 0;
$('.input-n-pro').each(function()
{
let
name = $(this).attr('name'),
val = parseInt($(this).val(),10) || 0;
arrNumber.push( {name, val });
totale += val;
})
console.clear();
console.log("totale =",totale);
console.log("arrNumber =", JSON.stringify(arrNumber) );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
AA : <input type="number" name="AA" value="5" class="input-n-pro" /> <br>
BB : <input type="number" name="BB" value="3" class="input-n-pro" /> <br>
CC : <input type="text" name="CC" value="foo" class="input-n-pro" /> <br> <!-- lets insert one input that contains no number -->
DD : <input type="number" name="DD" value="2" class="input-n-pro" /> <br>
EE : <input type="number" name="EE" value="11" class="input-n-pro" /> <br>
FF : <input type="number" name="FF" class="input-n-pro" />
I want to sum up some prices and put them in All price input, but the function doesn't sum the numbers, it puts the numbers next to each other. Is there any code that changes the string to the number?
<html>
<label class="fa">ext modeling price</label>
<input type="number" class="form-control" onchange="allPrc();" id="model-
ext-price" placeholder= "0" ></input>
<br>
<label class="fa">int modeling price</label>
<input type="number" class="form-control" onchange="allPrc();" id="model-
int-price" placeholder= "0" ></input>
<hr class="hrline">
<label class="fa"> ext renderign price</label>
<input type="number" class="form-control" onchange="allPrc();" id="render-
ext-price" placeholder= "0" ></input>
<br>
<label class="fa">int rendering price </label>
<input type="number" class="form-control" onchange="allPrc();" id="render-
int-price" placeholder= "0" y></input>
<hr class="hrline">
<label class="fa">pproduction price </label>
<input type="number" class="form-control" onchange="allPrc();"
id="pproduction-price" placeholder= "0" y></input>
<hr class="hrline">
<label class="fa"> All price </label>
<input type="number" class="form-control" id="All-price" placeholder= "0"
readonly></input>
</html>
<script>
document.getElementById ('model-ext-price').onchange = function() {allPrc();};
document.getElementById ('model-int-price').onchange = function() {allPrc();};
document.getElementById ('render-ext-price').onchange = function() {allPrc();};
document.getElementById ('render-int-price').onchange = function() {allPrc();};
document.getElementById ('pproduction-price').onchange = function() {allPrc();};
var allPrc = function () {
var Totalextmdl = document.getElementById ('model-ext-price').value,
Totalintmdl = document.getElementById ('model-int-price').value,
Totalextrndr = document.getElementById ('render-ext-price').value,
Totalintrndr = document.getElementById ('render-int-price').value,
Totalpp = document.getElementById ('pproduction-price').value,
TotalPrc = 0;
document.getElementById('All-price').value = TotalPrc;
var TotalPrc = Totalextmdl + Totalintmdl + Totalextrndr + Totalintrndr +
Totalpp;
document.getElementById('All-price').value = (TotalPrc>0 &&
TotalPrc!=='NaN')?TotalPrc:0;
};
</script>
element.value returns a string. You want numbers. One easy way to convert your field values is to use a unary + when you first fetch them, like this:
var Totalextmdl = +document.getElementById('model-ext-price').value,
Totalintmdl = +document.getElementById('model-int-price').value,
Totalextrndr = +document.getElementById('render-ext-price').value,
Totalintrndr = +document.getElementById('render-int-price').value,
Totalpp = +document.getElementById('pproduction-price').value,
TotalPrc = 0;
It is possible that in var TotalPrc = Totalextmdl + Totalintmdl + Totalextrndr + Totalintrndr + Totalpp; statement, Totalextmdl, Totalintmdl, Totalextrndr, Totalpp values are read as string.
You can convert their value into number by putting + symbol in front of those variables:
var TotalPrc = (+Totalextmdl) + (+Totalintmdl) + (+Totalextrndr) + (+Totalintrndr) + (+Totalpp);
I think you're looking for parseInt or parseFloat (depending if you have whole numbers or not)
ex: parseInt(document.getElementById ('model-ext-price').value) or parseFloat(document.getElementById ('model-ext-price').value)
This ensures you're getting back a number and not a string. Might want to write other logic to do something if parseInt (or parseFloat) fails.
https://www.w3schools.com/jsref/jsref_parseint.asp
https://www.w3schools.com/jsref/jsref_parsefloat.asp
Convert your string values to numbers:
var allPrc = function () {
var ids =['model-ext-price','model-int-price',
'render-ext-price', 'render-int-price', 'pproduction-price'];
var TotalPrice = 0;
ids.forEach(funciton(id) {
totalPrice+=Number(document.getElementById(id).value;
});
return TotalPrice;
}
document.getElementById('All-price').value = allPrc;
I have a form with list of input fields to be filled in.The values entered will be validated against the min and max criteria.If the entered value doesn't fall into the criteria , users need to be triggered to enter the reason followed by entering the after weight.
<c:forEach var="Item" items="${listBean.nameList}" varStatus="status">
<input type="number" class="required" name="nameList<c:out value='[${status.index}]'/>.initialWeight" onchange="checkOnChange(this,'<c:out value="${Item.personId}"/>','<c:out value="${Item.minWeight}"/>','<c:out value="${Item.maxWeight}"/>')">
<input type="number" class="required" name="nameList<c:out value='[${status.index}]'/>.finalWeight" onchange="checkOnChange(this,'<c:out value="${Item.personId}"/>','<c:out value="${Item.minWeight}"/>','<c:out value="${Item.maxWeight}"/>')">
<input type="text" class="formtext" name="nameList<c:out value='[${status.index}]'/>.Reason" value="" maxlength="255" size="25">
</c:forEach>
So once the initalWeight is entered , onchange event will be triggered to check whether the value is with in the min and max value.If it doesn't fall in to the criteria ,users will be alerted to enter reason and the screen focus should be on the reason field.
function checkOnChange(name, id, min, max)
{
var check = true;
var originalValue = '';
var minimum = eval(min);
var maximum = eval(max);
var nameVal = eval(name.value);
if (nameVal > maxVal)
{
alert(id + ' Enter the reason before proceeding');
return false;
}
if (itemVal < minVal)
{
alert(id + ' Enter the reason before proceeding');
return false;
}
}
JSFiddle link : http://jsfiddle.net/jegadeesb/ehehjxbp/
Is there a better way to achieve this .Kindly share your suggestions.
Thanks for your valuable suggestions and time
Add the reason field an ID and the set focus on it using the focus method
<c:forEach var="Item" items="${listBean.nameList}" varStatus="status">
<input type="number" class="required" name="nameList<c:out value='[${status.index}]'/>.initialWeight" onchange="checkOnChange(this,'<c:out value="${Item.personId}"/>','<c:out value="${Item.minWeight}"/>','<c:out value="${Item.maxWeight}"/>')">
<input type="number" class="required" name="nameList<c:out value='[${status.index}]'/>.finalWeight" onchange="checkOnChange(this,'<c:out value="${Item.personId}"/>','<c:out value="${Item.minWeight}"/>','<c:out value="${Item.maxWeight}"/>')">
<input type="text" class="formtext" name="nameList<c:out value='[${status.index}]'/>.Reason" id="reason" value="" maxlength="255" size="25">
</c:forEach>
function checkOnChange(name, id, min, max)
{
var check = true;
var originalValue = '';
var minimum = eval(min);
var maximum = eval(max);
var nameVal = eval(name.value);
if (nameVal > maxVal)
{
alert(id + ' Enter the reason before proceeding');
document.getElementById("reason").focus();
return false;
}
if (itemVal < minVal)
{
alert(id + ' Enter the reason before proceeding');
document.getElementById("reason").focus();
return false;
}
}