Reputation: 525
I am checking for valid input and successfully checked for blank inputs, but how do I check for valid lengths in decimal places using jquery?
if ($val === "")
This is fine for blank values, but what is the correct syntax that finds an input no greater than 2 decimal places?
This is the code so far and the browser is now reverting to the native browser pop-ups for warning on input.
$(document).ready(function() {
$("#submitCalculation").click(function() {
$(".checkVelocity").each(function() {
$val = $(this).val();
if ($val === "") {
if ($val.split(".")[1] || "").length > 2) {
$(this).popover({
placement: "left",
content: '<textarea class="popover-textarea"></textarea>',
template: '<div class="popover"><div class="arrow"></div>'+
'<div class="row"><div class="col-3 my-auto"><i class="fas fa-exclamation-triangle" id="invalid-input3">'+
'</i></div><div class="popover-content col-9">Enter the velocity of the car between 10 and 300 ms<sup>-1</sup>, kmh<sup>-1</sup> or mph.'+
'</div></div>'
});
$(this).popover('show');
}}
})
})
})
Originally it is working for blank or incorrect non-number inputs:
$(document).ready(function() {
$("#submitCalculation").click(function() {
$(".checkVelocity").each(function() {
$val = $(this).val();
if ($val === "") {
$(this).popover({
placement: "left",
content: '<textarea class="popover-textarea"></textarea>',
template: '<div class="popover"><div class="arrow"></div>'+
'<div class="row"><div class="col-3 my-auto"><i class="fas fa-exclamation-triangle" id="invalid-input3">'+
'</i></div><div class="popover-content col-9">Enter the velocity of the car between 10 and 300 ms<sup>-1</sup>, kmh<sup>-1</sup> or mph.'+
'</div></div>'
});
$(this).popover('show');
}
})
})
})
But it does not work for when decimal places exceed 2 for instance.
Upvotes: 0
Views: 124
Reputation: 1074395
You've said that trailing zeroes should be allowed, which the previous answers don't (they'll reject "2.000"
). (It wasn't clear early on that you wanted to do that, so far enough. :-) )
I think I'd lean toward a regular expression approach:
const rex = /^\s*(?:\d+|0)(?:\.\d{0,2}0*)?\s*$/;
const valid = rex.test($val);
Live Example:
const rex = /^\s*(?:\d+|0)(?:\.\d{0,2}0*)?\s*$/;
function test($val, expect) {
const valid = rex.test($val);
const validmsg = valid ? "valid" : "INVALID";
const success = !valid === !expect;
console.log(`${JSON.stringify($val)}: ${validmsg} ${success ? "OK" : "<=== ERROR"}`);
}
// Good ones
test("2", true);
test("2.1", true);
test("2.12", true);
test("2.120", true);
test("2.120000", true); // Trailing zeros okay
// Bad ones
test("", false);
test("2.123", false);
test("2.120001", false);
The regular expression /^\s*(?:\d+|0)(?:\.\d{0,2}0*)?\s*$/
says:
^
- start of string\s*
- allow zero or more whitespace chars (you may want to leave this out and trim the string first instead)(?:\d+|0)
- a non-capturing group defining an alternation (multiple alternatives) that will match either \d+
(one or more digits) or 0
(literally)(?:\.\d{0,2}0*)
- a non-capturing group defining
\.
- a literal .
for the decimal place\d{0,2}
- zero, one, or two digits0*
- any number of 0
characters?
- makes the entire non-capturing group in front of it optional, in case there's no decimal part at all\s*
- allow zero or more whitespace chars (you may want to leave this out and trim the string first instead)$
- end of stringUpvotes: 2
Reputation: 525
This has been solved by this code:
const isOpen = (val) => {
const num = parseFloat(val);
if (isNaN(num)) {
return true;
} else {
const decimals = num.toString().split('.')[1] || '';
if (decimals.length > 2) {
return true;
} else {
return false;
}
}
};
$(document).ready(function() {
$("#submitCalculation").click(function() {
$(".checkLength").each(function() {
const val = $(this).val();
if (isOpen(val)) {
$(this).popover({
html: true,
placement: "bottom",
content: '<textarea class="popover-textarea"></textarea>',
template: '<div class="popover"><div class="arrow"></div>' +
'<div class="row"><div class="col-3 my-auto"><i class="fas fa-exclamation-triangle" id="invalid-input7">' +
'</i></div><div class="popover-content col-9">Enter a value between 2 and 50 m with up to 2 decimal places.' +
'</div></div>'
});
$(this).popover("show");
$(this).click(function() {
$(this).popover("hide");
});
}
})
})
})
In short: The popover will only fire for empty strings, numbers that are too high, numbers that are too low or numbers that have too many decimal places.
Conversely, the popover will not fire for correct values, whole numbers, or decimal places that do not exceed the maximum value (2) or are decimal places with only zeroes in them.
Upvotes: 0
Reputation: 10765
To check for decimal places, do a split on period and get the length of the second element in the array. Since the question has been clarified to say that something like 2.000 or 2.210000000 should also be accepted, you could use a combination of .parseFloat()
and .toString()
with .length
to allow the passage of strings like 2.0000000 or 2.22000000:
if($val !== "" && $val.indexOf('.') > -1){
//We have decimal places, use combination of
//parseFloat toString length
//parseFloat will remove trailing zeroes.
const decimalLength = (parseFloat($val).toString().split('.')[1] || "").length;
//This doesn't work as it will block on trailing zeroes, ie. 2.000000 or 2.0100000
//const decimalLength = $val.split('.')[1].length;
if(decimalLength > 2) {
//Do something
}
}
Or you can go with a more lean approach suggested by T.J. Crowder:
if (($val.split(".")[1] || "").length > 2) { /* Disallow that many decimal places */ }
Upvotes: 3
Reputation: 1616
One more approach is to use regex pattern to do this validation:
var regex = /^\d+(\.\d{0,2})?$/g;
// returns true if valid the param has 0,1,2 decimal points, otherwise returns false
function validateDecimalPoint(param) {
console.log(regex.test(param));
return regex.test(param);
}
validateDecimalPoint('2.12');
Upvotes: 0