Sum numbers with JavaScript doesn't work properly "Intl.NumberFormat" - javascript

I have page with table of products and for each product there is a price.
When I change the qty it gets the total price...
But I have this problem:
When the numbers are lower then "1,000", the sum is ok.
ex:
prod 1: 200
prod 2: 200
prod 3: 500
total: 900
But when the numbers are greater then "1,000", the comma is the problem. I get a wrong answer.
ex:
prod 1: 200
prod 2: 1,200
prod 3: 300
total: 501
When I remove the "Intl.NumberFormat" from the total of each product, I get the right answer, but for some cases I get numbers like this: "1.000031545",
which I don't need. I only need the first 2 digit after the dot.
CODE: (simplefied)
<table>
<tr>
<td style="text-align: center;">
<label for="prod[<?php echo $prodid; ?>]"><input class='qty' style="font-size: 12px;" type="text" name="qty_<?php echo $prodid; ?>" placeholder="qty" minlength="1" maxlength="3" size="2"></label>
</td>
<td class='price'>
<?php echo $prodprice; ?>
</td>
<td width="40" class="sum">0</td>
</tr>
<tr>
<td colspan="3">
<span class="output"></span>
</td>
</table>
<script type="text/javascript">
function getTotal(){
var total = 0;
$('.sum').each(function(){
total += parseFloat(this.innerHTML);
});
$('#total').text(total);
givenNumber = total;
nfObject = new Intl.NumberFormat('en-US');
output = nfObject.format(givenNumber);
document.querySelector('.output').textContent = total;
}
getTotal();
$('.qty').keyup(function(){
var parent = $(this).parents('tr');
var price = $('.price', parent);
var sum = $('.sum', parent);
var value = parseInt(this.value) * parseFloat(price.get(0).innerHTML||0);
givenNum1 = value;
nfObj = new Intl.NumberFormat('en-US');
outpu = nfObj.format(givenNum1);
sum.text(outpu);
getTotal();
})
</script>

Referencing the MDN Web Docs
If parseFloat encounters a character other than a plus sign (+), minus
sign (- U+002D HYPHEN-MINUS), numeral (0–9), decimal point (.), or
exponent (e or E), it returns the value up to that character, ignoring
the invalid character and characters following it.
You can remove the comma by using replace() and then parse it afterwards to get the right value.
let str = "1,200"
let newStr = str.replace(/,/g,"");
console.log(`Without replace ${parseFloat(str)}`);
console.log(`With replace ${newStr}`);

parseFloat stops parsing at the first invalid character. , is not a valid character to parseFloat.
You can remove the ,:
total += parseFloat(this.textContent.replace(/,/g, ""));
Note that I also switched from innerHTML to textContent.
Also note that I used a regular expression with the g ("global") flag, since .replace(",", "") would only replace the first comma (so 1,200,300 would fail). Or in modern environments you can use replaceAll but it's relatively new (though easily polyfilled):
total += parseFloat(this.textContent.replaceAll(",", ""));
For this I'd just use the regular expression.

Related

How can I perform math on last x characters of string and update text box on the fly?

I have an app where a user scans or types in a starting barcode, and the ending barcode is automatically calculated based on a quantity value.
It works fine when the starting barcode is entirely numeric, it does the math and includes leading zeroes so the end code is the correct length.
My problem is that some small percentage of the barcodes are not entirely numeric.
The barcodes are 14 characters long. The last 5 characters will always be numeric and quantities will rarely exceed a few hundred and never go high enough that we spill into the 6th digit.
I'm not a javascript expert by any means, and just getting what I have now working strained my skills -- I'm hoping the community here can help me out :)
Here's the code I'm working with:
$(document).ready(function() {
//leading zero fill function for barcodes
function pad(num, size) {
var s = "00000000000000" + num;
return s.substr(s.length - size);
}
//Function to do BC math: starting number + quantity -1 (since it's inclusive) = end.
function updateCode() {
var quantity = $(this).closest('tr').find('.quantity').val();
var barstart = $(this).closest('tr').find('.barstart').val();
var end = pad(parseInt(barstart, 10) + parseInt(quantity - 1, 10), 14);
$(this).parent().next().find('.barend').val(end);
}
$(document).on("change, keyup", ".barstart", updateCode);
});
Edit Trying to insert the HTML again:
<script src="//code.jquery.com/jquery-1.7.2.min.js"></script>
<table id="formtable">
<tr>
<td><input class="quantity" size="6" id="qty_1" name="qtyid_1" value="123" type="text"></td>
<td><input class="barstart" size="15" maxlength="14" id="barstartid_1" name="barstart_1" value="" placeholder="Barcode Start" type="text"></td>
<td><input class="barend" size="15" maxlength="14" id="barendid_1" name="barend_1" value="" placeholder="Barcode End" type="text"></td>
</tr>
</table>
Here's a jsfiddle: https://jsfiddle.net/g1p2xh6y/1/
The users can live without it, but it'll save them some headaches (and help me make a good impression - this is a new gig) if I can get it working, so I greatly appreciate any help the community can offer :)
Thanks!
Many thanks to #admcfajn - I didn't know the slice() function existed, and that resolved it for me. I had to move the zero padding to the suffix, and remove it from the end value, but since it's pulling the prefix instead of doing math, that's no problem.
Here's the updated function:
function updateCode() {
var quantity = $(this).closest('tr').find('.quantity').val();
var barstart = $(this).closest('tr').find('.barstart').val();
var barprefix = barstart.slice(0,barstart.length-5);
var barendsuffix = pad(parseInt(barstart.slice(-5),10)+parseInt(quantity-1,10),5);
$(this).parent().next().find('.barend').val(barprefix+barendsuffix);
}

JavaScript validating input only contains integers on submit

I've been trying for a bit to find a good way to go about this. Here's the trick this is being developed for IE6, so HTML5 is not supported (which is what is making this a pain, and why the button is actually a span). I need to allow all input into the input element but on submit i need to verify that the input is an integer and if it contains alpha characters or decimals throw an error.
<table id="studentIdInputTable">
<tr><td colspan="3"><hr class="style-hr" /></td></tr>
<tr><td><span class="underline bold">Selection 1</span></td>
<td class="center"><span class="small-text">Employee ID</span></td>
</tr>
<tr><td>Please enter your Student ID to <span class="bold italic">start your registration process</span></td>
<td class="center"><input type="text" maxlength="11" id="tbNewStudentId" /></td>
<td> <span id="btnNewStudent" class="validation-button">Start</span></td></tr>
</table>
I have javascript native to the HTML page as below
function CheckNewStudentId(){
var newStudentID = $("tbNewStudentId").val();
newEmployeeID = parseInt(newEmployeeID, 10);
var isNum = /^\d+$/.test(IDnumber);
if (isNum == false) {
alert(IDnumber + " is not a valid student number. Please enter only numbers 0-9, containing no alphabetical characters.");
}
}
It would be easier if this was for a more updated browser platform. Any ideas how I can go about this?
Edit***
For reference to other users this was solved using this function
function validIdCheck(Input){
if(Number.isInteger(Input)==false){
alert("This is not a valid ID");
}
}
connected to this jQuery click function
$("#btnNewStudent").click(function(){
var newStuId = $("#tbNewStudentId").val();
newStuId=parseInt(newStuId);
validIdCheck(newStuId);
});
To check if a number is an integer try this. It returns a boolean.
Number.isInteger(yourNumber)
docs: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests
Using part of your code:
function validateStudentId(id) { return /^\d+$/.test(id) }
This will return true if it is a number or combination of numbers from 0 to 9.
If the id can not start with a 0, try this:
function validateStudentId(id) { return /^([1-9]|[1-9]\d+)$/ }
Quick explanation:
^ starts with
[1-9] digit between 1 and 9
| or
\d digit (0 to 9)
+ occurs at least once and up to unlimited times
$ ends with
Test it here

replace characters in price calculation JS

I'm creating a script for percentage calculation on my e-commerce, but I have a problem.
If i use use characters such as: ", . %" the price value says "NaN".
So I made this:
<input type="text" name="cost" onkeyup="disc()"> <br><br>
<input type="text" name="discount" id="prized" onkeyup="updateInput()">
<input type="text" name="price" value="">
<script>
function updateInput(){
var discount = document.getElementsByName("discount")[0].value;
var cost = document.getElementsByName("cost")[0].value;
document.getElementsByName("price")[0].value = cost - (cost * (discount / 100));
}
function disc(){
if($("#prized").val().length > 1) {
var discount = document.getElementsByName("discount")[0].value;
var cost = document.getElementsByName("cost")[0].value;
document.getElementsByName("price")[0].value = cost - (cost * (discount / 100));
}
}
</script>
How can I replace the characters when they are inserted on cost value or discount value?
I did some research, and I found an interesting function: .replace
I have no idea how to use it in my script.
Someone can help me reach my goal?
You should have to replace special characters , and & like this
var price = $(".price").val().replace(/,/g, "").replace("%", "")
This replace(/,/g, "") will replace multiple replace of comma ,
Ex. 1,00,000 be 100000
Why not validate your user input prior to calling your function? create a regex to only allow the characters you want. As it is your user can input any character they want in the input box. Probably a good idea to limit that.
I don't know whether this is the requirement, any way replace work like below,
var test = "90.56%";
test = test.replace(/[.%]/g, "");
//test will be "9056"

Javascript returning incorrecct results

Before I start, I would like to say that if this question has already been answered please direct me to the appropriate answer.
I am having an issue with my Java Script function not returning an expected value. I am trying to use it to validate text input for a number range, and, if the input is outside that range, return a custom error message.
here is the HTML for one of the fields within a the form which I am trying to validate:
<td><input name="bottomair" type="text" required id="bottomair"
size="3" onChange="bottomAirF()"></td>
<td class="noborder" id="bottomairerror"></td>
And here is the associated Javascript:
function bottomAirF() {
var x, text;
x = document.getElementById("bottomair");
if (isNaN(x) || x < 33 || x > 40) {
text = "Temp Out of Tolerance";
} else {
text = " ";
}
document.getElementById("bottomairerror").innerHTML = text;
}
What I am trying to accomplish is to have the function check to see if the entered number is between 33 and 40. If the number is not between these two numbers, the code should return the error message "Temp Out of Tolerance" but if the number is between 33 and 40 it should return nothing. As it stands right now, any number (or lack there of) returns the error message.
This code is modified from W3School's Comparison function.
I have tried everything that I can think of and it is still not working properly so any help would be greatly appreciated.
Although all the posted answers are technically correct, I believe this solution is neither maintenable nor scalable.
You have hard dependency on element ids which are static.
Imaging if, in future, you want to add more of these tds that perform such validation, are you going to keep track of newly added rows?
Although, technically you can but anthropologically its mentally draining and things like this deny to make use of the very purpose the computers and software is designed - Automation.
Something that lets you do creative tasks and have the mechanical stuff done by the computer.
For this philosophical reason, I believe this piece of code is a much better solution.
HTML - Get rid of Ids and pass this meaning current element (which is input in this case) as a parameter to the function.
<table>
<tr>
<td><input type="text" required size="3" onChange="bottomAirF(this)"></td>
<td class="noborder"></td>
</tr>
</table>
JS - use DOM accessors to find next td and update it's innerHTML
function bottomAirF(elem) {
var x, text;
x = +elem.value; // Prepended + sign will parse whatever follows to integer.
if (isNaN(x) || x < 33 || x > 40) {
text = "Temp Out of Tolerance";
} else {
text = " ";
}
elem.parentNode.nextElementSibling.innerHTML = text;
}
EDIT: For the updated requirements
To add new validations and conditions.
Let's say you have 3 textboxes which you need validation on. Each of these textboxes have different validation parameters.
First Should only accept values between 1 and 10
Second should only accept values between 11 and 33
Third should only accept values between 33 and 41
So the updated code would be, (the name of the function will be changed to something generic, like, validate)
Notice that there are two additional attributes on the input element viz val-min and val-max that specify the range.
<table>
<tr>
<td><input type="text" required val-min="1" val-max="10" size="3" onChange="validate(this)"></td>
<td class="noborder"></td>
</tr>
<tr>
<td><input type="text" required val-min="11" val-max="33" size="3" onChange="validate(this)"></td>
<td class="noborder"></td>
</tr>
<tr>
<td><input type="text" required val-min="33" val-max="40" size="3" onChange="validate(this)"></td>
<td class="noborder"></td>
</tr>
</table>
JS Code
function validate(elem) {
var x, text;
x = +elem.value; // Prepended + sign will parse whatever follows to integer.
var min = elem.getAttribute('val-min');
var max = elem.getAttribute('val-max')
if (isNaN(x) || x < min || x > max) {
text = "Temp Out of Tolerance";
} else {
text = " ";
}
elem.parentNode.nextElementSibling.innerHTML = text;
}
Working Fiddle
you are missing .value
x = document.getElementById("bottomair").value;
please instead this line:
document.getElementById("bottomair");
write this line:
document.getElementById("bottomair").value;
It should be like this
x = document.getElementById("bottomair").value;
if (isNaN(x) || parseInt(x,10) < 33 || parseInt(x) > 40) {
text = "Temp Out of Tolerance";
} else {
text = " ";
}
You've done very well all you needed was to add
value to document.getElementById("bottomair")
Here is the solution I've just added the .value
x = document.getElementById("bottomair").value;
Definitely Missing .value
$(document).ready(function () {
$("#btnCalc").click(
function () {
bottomAirF();
}
);
});
function bottomAirF() {
var x, text;
x = document.getElementById("bottomair").value;
if (isNaN(x) || x < 33 || x > 40) {
text = "Temp Out of Tolerance";
} else {
text = " ";
}
document.getElementById("bottomairerror").innerHTML = text;
}
See
Simple JSFiddle Example

Multiple order quanity x price and show decimal two places

How do I get the javascript and php to display two decimal places after calculation. Right now it works fine but no decimal places, just whole numbers
php********
<td> width="3"><input type="text" name="order_quan" /></td>
<td><input type="text" name="Price" /></td>
<td><font color="yellow"><span class=Price></span></td>
Java Script********
<script>
$('input[name=order_quan], input[name=Price]').keyup(function() {
var divParent = $(this).closest('div');
var order_quan = $('input[name=order_quan]', divParent).val()-0;
var Price = $('input[name=Price]', divParent).val()-0;
if (order_quan >= 0 && Price >= 0)
$('span.Price', divParent).text(order_quan*Price);
});
</script>
You can use .toFixed(2);
(order_quan * Price).toFixed(2);
Here's the basics
String((order_quan*Price * 100)>>0).replace(/(\d{2}$)/,'.$1');
//shift it 2 decimal places left, floor it, and add '.' before the last two digits

Categories