Reputation: 573
I've walked into a strange problem. When trying to replace a dot on a number input, instead of replacing just that dot, it clears out the entire input.
$("[data-input-payment-id]").on("keyup", function(e) {
var test_value = $(this).val().replace(/\./g, "");
$(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">
How do I change it so it only removes the dots?
Upvotes: 16
Views: 2671
Reputation: 573
This isn't really a solution as I'd personally like to see it, but here is what I did to solve the problem at hand. I changed the JavaScript code to listen for keycode 46 (the .
) and I'm returning false on the paste event listener to disable pasting a value into the input.
$("[data-input-payment-id]").on("keypress", function(e) {
var key = e.charCode ? e.charCode : e.keyCode;
if (key == 46) {
return false;
}
});
$("[data-input-payment-id]").on("paste", function(e) {
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">
It works at least in Chrome and Edge.
Upvotes: 2
Reputation: 350137
I would:
keyup
event, listen to the input
event. This way you can also allow pasting.type=number
inputs will have an empty string as value as soon as the input becomes invalid (as a number). I would store that previous correct value in a data property of the input
elementvalidity.stepMismatch
you can know whether the current value is violating the step
property of the input
which by default is 1. With a step of 1, this means entering a number with a decimal separator will be considered a mismatch.$("[data-input-payment-id]").on("input", function (e) {
if (!this.validity.stepMismatch) {
$(this).data("lastValid", $(this).val());
};
$(this).val($(this).data("lastValid") || "");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number"data-input-payment-id="12">
Having said this, I personally am not in favour of blocking user input in this way: they might for a moment think their keyboard is broke. It is in my opinion better to allow the user to type anything and just indicate with a message next to the input that the input is not valid (until it is).
Upvotes: 2
Reputation: 8332
I think (guessing) it's because you use type="number"
. Then digits followed by a dot, e.g. 123.
, isn't a valid number, and val
returns blank.
You could try this instead:
$("[data-input-payment-id]").on("keyup", function(e) {
var test_value = this.value.replace(/[^\d,]/g, "");
$(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input data-input-payment-id="12">
This uses normal text type and filters out anything but digits in the replace.
Edit:
Changed the regex to match anything but numbers and commas.
Upvotes: 11
Reputation: 1111
Your Keypress example gave me this idea. If you can intercept the keypress event, it is possible to check any validation before adding the actual value. This example also does not require any conditional and is able to filter any non-digit value.
$("[data-input-payment-id]").on("keypress", function(e) {
if ((this.value + e.key).match(/\D/)) {
return false;
}
});
$("[data-input-payment-id]").on("paste", function(e) {
var pasteData = (e.originalEvent.clipboardData || window.clipboardData).getData('text');
pasteData = pasteData.replace(/\D/g, '');
this.value = this.value + pasteData;
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">
http://jsfiddle.net/xpvt214o/511118/
Upvotes: 2
Reputation: 370679
See MDN docs on input
s of type number
:
Value
A Number representing a number, or empty
If the input string cannot be converted to a proper number - such as if the string contains two dots - then accessing the .value
property will return the empty string.
The .value
(and val()
function) will still return strings, but those strings must represent valid numbers (or be the empty string). Rather than setting the element's value unconditionally, simply check to see if the value isn't the empty string first:
$("[data-input-payment-id]").on("keyup", function(e) {
const val = $(this).val();
if (val === '') return;
var test_value = $(this).val().replace(/\./g, "");
$(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-input-payment-id="12">
Or you might use a text input, and possibly a pattern
:
$("[data-input-payment-id]").on("keyup", function(e) {
const val = $(this).val();
var test_value = $(this).val().replace(/\./g, "");
$(this).val(test_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<input data-input-payment-id="12">
<input type="submit">
</form>
<form>
<input pattern="^\d+$" data-input-payment-id="12">
<input type="submit">
</form>
Upvotes: 1
Reputation: 308
$(this).val()
is returning an empty string if an input with type="number"
has more than one .
You can fix this, by only running the replacing the value if $(this).val()
does not return an empty string.
Upvotes: 0