How to check if number ends in .99 - javascript

I'm attempting to do some validation a price field. I would like to check if the price entered into the price field ends in .99
I've attempted find posts about this but I can't find examples for decimal numbers only whole numbers. I tried to check by doing price % 1 but it isnt consistent as the price increases by 10, 20 etc.
Is there a quick way to check if all numbers end in .99?
const price = 9.99
console.log(price % 1)

Floating point math is inherently imprecise. The actual mathematical expression price - 9 will get those extra 0s and a 2 too.
Best you could do is convert to a string with fixed precision (rounding off any extraneous precision; for a price in dollars, you'd only need two digits, but you might go to three or more to verify the price entered didn't end with nonsense fractions of a cent) and perform a string test, e.g.
price.toFixed(2).endsWith('.99')
which doesn't try to perform math on price at all, it just rounds off to two digits after the decimal place to produce a string, then checks if the string ends with .99.

You can try regular expression as well. See following code for example:
function testRegex() {
var re = /^[0-9]*[.](99)$/;
var val = document.getElementById("inputValue").value;
if(re.exec(val)) {
document.getElementById("result").innerText = "Found match!!!";
} else {
document.getElementById("result").innerText = "Found no match!!!";
}
}
<input type="text" id="inputValue" value="" onkeyup="testRegex()" />
<div id="result"></div>

You can perform that validation using the following regular expression:
/\.99$/
First, we try to match an explicit . by escaping it with a backlash. Then, the next two characters must be 99, and then the string end must occur for the successful match. We check that with $. For example,
prices = [0.99, 0.0099, 1.99, 2.99, 3.98, 4.01];
for (const price of prices) {
if (/\.99$/.test(price.toString())) {
console.log(`${price} ends with .99`);
}
}
will print:
0.99 ends with .99
1.99 ends with .99
2.99 ends with .99

Related

How to make regular expression only accept special formula?

I'm making html page for special formula using angularJS.
<input ng-model="expression" type="text" ng-blur="checkFormula()" />
function checkFormula() {
let regex;
if (scope.formulaType === "sum") {
regex = "need sum regular expression here"; // input only like as 1, 2, 5:6, 8,9
} else {
regex = "need arithmetic regular expression here"; // input only like as 3 + 4 + 6 - 9
}
if (!regex.test(scope.expression)) {
// show notification error
Notification.error("Please input expression correctly");
return;
}
// success case
if (scope.formulaType === "sum") {
let fields = expression.split(',');
let result = fields.reduce((acc, cur) => { return acc + Number(cur) }, 0);
// processing result
} else {
// need to get fields with + and - sign.
// TODO: need coding more...
let result = 0;
// processing result
}
}
So I want to make inputbox only accept my formula.
Formulas are two cases.
1,2,3:7,9
or
4-3+1+5
First case, means sum(1,2,3,4,5,6,7,9) and second case means (4-3+1+5).
But I don't know regular expression how to process it.
I searched google, but I didn't get result for my case.
So I want to need 2 regex match.
1,2,3:7,9
Fot this pattern, you can try this one:
^\d+(?::\d+)?(?:,\d+(?::\d+)?)*$
^\d+(?::\d+)?
matches string starts with a number(e.g. 1) or two numbers separated by a column (e.g. 1:2)
(?:,\d+(?::\d+)?)*$
repeats the previous pattern with a comma in front of it as many time as possible until meets the end of the string (e.g. ,2:3,4:5,6)
4-3+1+5
Fot this pattern, you can try this one:
^\d+(?:[+-]\d+)*$
Like the previous one, this is much simpler
^\d+
starts with a number(e.g. 12)
(?:[+-]\d+)*$
repeats the previous pattern with a - or + in front of it as many time as possible until meets the end of the string (e.g. +2-3+14)
Also, if you need at least one pair of numbers.
Such as 1,2 is allowed but just 1 is not. You can just change the * before $ to +:
^\d+(?::\d+)?(?:,\d+(?::\d+)?)+$
^\d+(?:[+-]\d+)+$
And if you allow white spaces in between them:
^\d+(?:\s*:\s*\d+)?(?:\s*,\s*\d+(?:\s*:\s*\d+)?)+$
^\d+(?:\s*[+-]\s*\d+)+$

Parsing toLocaleString and back to float loosing precision

This is what works as expected:
This parseFloat(newValue).toLocaleString("de-DE", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) will result in a String: "34.886,55"
This does not work as expected:
For parseFloat("34.886,55") I get a Number, but I lost everything after the comma: 34.886.
How can I fix this problem ?
I wrote this simple function for doing locale based parseFloat, to the best of my knowledge, the assumptions for this function are.
The decimal operator will come once.
So split it at the decimal("," in our case) to get two elements in an array.
Then remove the thousands separator("." in our case) for each of the elements in the array.
Then joinback the array with the decimal separator ("." in our case)
finally return the parseFloat value of this joined number!
var str = "34.886,55"
console.log("before: ", str);
str = localeParseFloat(str, ",", ".");
console.log("resulting floating value from the function: ", str);
function localeParseFloat(str, decimalChar, separatorChar){
var out = [];
str.split(",").map(function(x){
x = x.replace(".", "");
out.push(x);
})
out = out.join(".");
return parseFloat(out);
}
<script src="https://rawgit.com/eu81273/jsfiddle-console/master/console.js"></script>
Here's a brief example of the number parsing... Commas are not valid in numbers, only the full stop represents the decimal separator. If it is encountered, the string conversion stop, as you can see on the second log. Also check the third log, I've added a check for the value to be true if it's lower than 100, making it more obvious that you are not playing with thousand separator but really decimal separator.
console.log(parseFloat("34.886.55"));
console.log(parseFloat("34,886.55"));
console.log(parseFloat("34.886,55"), parseFloat("34.886,55") < 100);

Phone number regex - Merge three conditions

I need to create a regex function which will validate a phone number field based on certain conditions and show alerts for each of the three cases.
Practically I have this 3 regex functions which I want to combine in a single one.
/^3\d{9}$/; //If it starts with 3 and has another 9 numbers it's a cellphone
/^0\d{7,10}$/; //If it starts with 0 and has another 7-10 numbers it's a landline
/^(?:00|\+)/; //If it starts with 00 or a + sign, it's an international number
What I am trying to achieve, is to have a javascript function which will combine this three regex functions and show a certain message in case the number is not valid.
So for example if the number starts with 3 but it has less or more than 9 numbers after the 3, probably it's a wrong cellphone number so I want to warn the user about that. Same thing for the Landline. For the international numbers I simply want to make them aware that it might be an international number because it starts with double 00 or + sign.
My problem is that I don't know how to combine this three regex values in a single one, which will allow me to build a simple and clean javascript code.
I think this will work for you: /^(?:3\d{9}|0\d{7,10}|(?:00|\+)\d+)$/g
const testPhoneNumber = number => /^(?:3\d{9}|0\d{7,10}|(?:00|\+)\d+)$/.test(number)
const numbers = [123, "+48667065144", 3111222333, "001234567", "00123456879", 6473812354, 3475456389, 7483925821]
for (const number of numbers) {
console.log(`${number} is ${testPhoneNumber(number) ? "valid": "not valid"} phone number`)
}
match(/(^3\d{9}$)|(^0\d{7,10}$)|(^(?:00|\+))/)
this will capture the matched data in an array (size 4).
position 0 : the matched data
position 1 : matched data of the 1st regexp
....
function check(number) {
//var number = '3123456789';
//var number = '01234567';
//var number = '001';
var regexList = [
'^3\\d{9}$', //If it starts with 3 and has another 9 numbers it's a cellphone
'^0\\d{7,10}$', //If it starts with 0 and has another 7-10 numbers it's a landline
'^[0]{2}|[\+]' //If it starts with 00 or a + sign, it's an international number
];
for (var r in regexList)
if (number.match(new RegExp(regexList[r])))
break;
else
r = null;
switch (r) {
case "0":
alert('If it starts with 3 and has another 9 numbers it\'s a cellphone');
break;
case "1":
alert('If it starts with 0 and has another 7-10 numbers it\'s a landline');
break;
case "2":
alert('If it starts with 00 or a + sign, it\'s an international number');
break;
default:
alert('Invalid number');
}
}
<input type="text" id="numberToCheck" />
<input type="button" onclick="check(document.getElementById('numberToCheck').value)" />
As "elegant" as I can make it...
var input = '00372553253';
var matches = [];
// The following is technically one line!
[
{regex: /^3\d{9}$/, type: "cellphone"},
{regex: /^0\d{7,10}$/, type: "landline"},
{regex: /^(?:00|\+)/, type: "international"}
].forEach(
function(element) {
if (element.regex.test(input))
matches.push(element.type);
}
);
alert(matches);
The test case will actually match two regexes!

Javascript: Convert a string representation of money to Number

Lets say I have an amount in string format like this:
amount = '12,000.00'
I want to convert it into a Number (Javascript) or a float.
parseFloat(amount) // this gives me 12 as a result
Number(amount) // this gives me NaN as a result
Other solution I thought was this:
parseFloat(amount.replace(/[,]/g, ''))
This works fine. But the problem here is the Locale.
This would fail when the amount is € 12000,00.
Here ',' has altogether a different meaning.
I looked around for a good solution but couldn't. I am looking for a generalized solution.
This is not that easy, as you can't exactly know what's the delimiter for thousands and what for the decimal part
Consider "12.000.000" is it 12000.000 === 12000 or 12000000?
But if you would set the requirement that the last delimiter is always the decimal delimiter -
meaning if at least one delimiter is given, the last one has to be the decimal delimiter, *if the digits following, don't exceed a defined length.
Then you could try the following
Edit
(see the revs if you're interested in the old function)
I put in the ability to define the max length of digits after the last delimiter "," or "." up until it is treated as float, after that its returned as integer
var amounts = ["12000","12.000,00", "12,000.00", "12,000,01", "12.000.02", "12,000,001"];
formatMoney.maxDecLength = 3; //Set to Infinity o.s. to disable it
function formatMoney(a) {
var nums = a.split(/[,\.]/);
var ret = [nums.slice(0, nums.length - 1).join("")];
if (nums.length < 2) return +nums[0];
ret.push(nums[nums.length - 1]);
return +(ret.join(nums[nums.length - 1].length < formatMoney.maxDecLength ? "." : ""));
}
for ( var i=0,j;j=amounts[i];i++)
console.log (j + " -> " +formatMoney(j));
Gives the output:
"12000 -> 12000"
"12.000,00 -> 12000"
"12,000.00 -> 12000"
"12,000,01 -> 12000.01"
"12.000.02 -> 12000.02"
"12,000,001 -> 12000001" //as you can see after the last "," there are 3 digits and its treated as integer
Another JSBin
You can get the local decimal delimiter in this manner:
1.1.toLocaleString().substr(1,1)
Before parse float, you could make sure the string contains nothing but numbers, possibly a minus sign, and the local decimal delimiter.
The truth is, you'll never know the format. 12,345. Is that 12345, or another locale version if 12.345?
However, if you have consistent decimals, then you'd be able to use the lastIndexOf function on a comma and a period will reveal the decimal position and character.
var price = '12,345.67';
var lastPeriod = price.lastIndexOf('.');
var lastComma = price.lastIndexOf(',');
if (lastComma != -1 && lastComma > lastPeriod) {
decimalCharacter = ',';
} else {
decimalCharacter = '.';
}
console.log(decimalCharacter); //. or , based on how the price string looks - see below
If price is 12,345.67, decimalCharacter will be .. If it's 12.345,67, it'll be returned as ,.

Get the number and round to whole number

I'm getting the miles from Google Map API V3 and displaying it in a textbox based on the from and to addresses. I want to parse out the number and round it off to the nearest whole number.
Miles = "29.9 mi" // i want the result as 30
Miles = "9.3 mi" // 10
I tried Math.round but it's returning NAN.
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var miles = response.routes[0].legs[0].distance.text;
miles = Math.round(miles);
$('#TotalMiles').val(miles);
}
Did you look at the JavaScript API for round?
Syntax
Math.round(x)
Parameters
x A number.
Description
If the fractional portion of number is .5 or greater, the argument is
rounded to the next higher integer. If the fractional portion of
number is less than .5, the argument is rounded to the next lower
integer.
Because round is a static method of Math, you always use it as
Math.round(), rather than as a method of a Math object you created.
EDIT:
You need to convert the string into its parts to get the number
Miles = "29.9 mi"
var num = parseFloat(Miles);
Math.round(num);
and way to do it with a regular expression
Miles = "29 mi"
var rounded = Miles.replace(/(\d+(\.\d+)?)(\s?mi)/, function(match, number, x, units){ return Math.round(parseFloat(number)) + units });
console.log(rounded);
Try parseFloat + Math.ceil:
var number = "9.3 mi";
console.log(Math.ceil(parseFloat(number)));
you may need to split out the extra characters.
var str = "29.9 mi";
var number = str.split(" ");
var new_number = Math.round(parseFloat(number[0]));
This is a longwinded answer. In the end it would make more sense to tailor it to what you need exactly, but here I am just showing how to split on " " (space) and round the resulting string after parsing it as a float.
I would try KaeruCT's answer though. I don't think parseInt or parseFloat actually need the non numeric characters removed.
Try Math.round():
var number =29.9;
console.log(Math.round(number));

Categories

Resources