Reputation: 937
I have the code below which does restrict the input to only numbers and a select number of key combinations. But I also want to restrict the input to only accept one decimal point.
number: {
init: function (element) {
// Allows only numbers with decimals
$(element).on("keydown", function (event) {
// Allow: backspace, delete, tab, escape, and enter
if (event.keyCode === 46 || event.keyCode === 8 || event.keyCode === 9 || event.keyCode === 27 || event.keyCode === 13 ||
// Allow: Ctrl+A, Ctrl + C, Ctrl + V, Ctrl + X
((event.keyCode === 65 || event.keyCode === 67 || event.keyCode === 86 || event.keyCode === 88) && (event.ctrlKey === true || event.metaKey === true)) ||
// Allow: .
(event.keyCode === 190 || event.keyCode === 110) ||
// Allow: home, end, left, right
(event.keyCode >= 35 && event.keyCode <= 39)) {
// let it happen, don't do anything
return;
} else {
// Ensure that it is a number and stop the keypress
if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
event.preventDefault();
}
}
});
}
}
I tried to add '$(element).val().indexOf('.') !== -1'
like below but it does not do anything and I can still type in as many periods I want. How should I actually restrict it?
if (event.shiftKey || ($(element).val().indexOf('.') !== -1 && (event.keyCode === 190 || event.keyCode === 110)) || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
event.preventDefault();
}
Upvotes: 0
Views: 1642
Reputation: 10976
So I must say I don't really see the logic in allowing explicitly; instead you should exclude explicitly as by default everything is allowed. You buy a computer after it having passed all your criteria, you don't buy 10 computers, then throw away those that don't fit your criteria. So, no need to touch the Ctrl & other function keys, you're making it needlessly complicated.
If you look carefully at your extremely long if
clause, you will notice the following: (event.keyCode === 190
under which you stated // let it happen, don't do anything
. So periods will always be added regardless. Here are the gotchas with your current approach:
keydown
event, all keycodes produce the same value with Caps Lock on or not, because they're the same keys. So you cannot distinguish between period .
and semicolon ;
.keydown
event, keycodes for the same number on a numpad and on the keyboard are different, because they are different keys.As a result you are much better off using the keypress
event, which returns the character value. Here is a refactored and much more concise function, that achieves exactly the same:
$('#jquery').on("keypress", function (event) {
var k = event.keyCode || event.charCode;
if (k === 46 && this.value.match(/\./g) || (k < 48 && k !== 46 ) || k > 57) {
event.preventDefault();
}
});
Test it here: http://jsfiddle.net/kevinvanlierde/5ay3cory/6/
NOTE: Because Mozilla Firefox sucks at making the difference between keydown and keypress, it messes up and disables all control keys too.
Upvotes: 1
Reputation: 937
I fixed my own code and thought I'd share it here:
// Allows only numbers with decimals
$(element).on("keydown", function(event) {
// Allow: backspace, delete, tab, escape, and enter
if (event.keyCode === 46 || event.keyCode === 8 || event.keyCode === 9 || event.keyCode === 27 || event.keyCode === 13 ||
// Allow: Ctrl+A
(event.keyCode === 65 && (event.ctrlKey === true || event.metaKey === true)) ||
// Allow: .
(event.keyCode === 190 || event.keyCode === 110) ||
// Allow: home, end, left, right
(event.keyCode >= 35 && event.keyCode <= 39)) {
// let it happen, but check for excessive periods
if ((event.keyCode === 190 || event.keyCode === 110) && $(element).val().indexOf('.') !== -1) {
event.preventDefault();
}
return;
} else {
// Ensure that it is a number and stop the keypress
if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
event.preventDefault();
}
}
});
I added the following code where it allows certain keycodes:
if ((event.keyCode === 190 || event.keyCode === 110) && $(element).val().indexOf('.') !== -1) {
event.preventDefault();
}
Upvotes: 0
Reputation: 318
if ((yourString.match(new RegExp(".", "g")) || []).length > 1) {
// yourString contains more than one "."
}
Upvotes: 0