16

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">

JSFIDDLE

How do I change it so it only removes the dots?

13
  • 6
    works fine in firefox and chrome and edge - and you can't be using internet explorer, because then you wouldn't be using jsfiddle Commented Jul 30, 2018 at 9:49
  • though, in firefox, if you press and hold . then you get what you describe Commented Jul 30, 2018 at 9:52
  • 2
    @JaromandaX seems to break if you type 2 dots in a row Commented Jul 30, 2018 at 9:52
  • 6
    @JaromandaX im testing this in chrome and it does NOT work for me Commented Jul 30, 2018 at 9:53
  • 2
    Looks like if you use an invalid number in type = number, this.value will return a blank string - maybe connected: stackoverflow.com/questions/18677323/… - instead of removing the dots, why not just prevent them from typing the dots Commented Jul 30, 2018 at 10:03

6 Answers 6

11

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Problem here is that it doesnt take the comma into account
What do you mean by that? Any comma is removed. Isn't that what you were trying to do?
No, im trying to remove dots, not commas
2

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">

  • Allows pasting data with filtering
  • No specific conditionals
  • Can be modified for custom validation

http://jsfiddle.net/xpvt214o/511118/

Comments

2

I would:

  • Instead of the keyup event, listen to the input event. This way you can also allow pasting.
  • Keep a record of the previous correct value, so that you can roll back to it. This is necessary because 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 element
  • With the use of the property validity.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.
  • As a trailing decimal separator will not (yet) yield a fractional number, it will pass the above validation. So echo the value back into the input when all is OK: this will eliminate any trailing decimal separator that might have been keyed in.

$("[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).

4 Comments

Nitpick: this solution does not allow a user to clear the input, because the empty string is not a valid number. You might want to allow that explicitly, or mention it in the answer.
I further updated this answer after I realised that fractional numbers should not be accepted.
I can see why you did this, but I would like to remark (as you already sort of do in your answer) that this does not work at all when the step is not 1. For example, with a step of 10 a user will never be able to input a multiple of 10 with a single keystroke. Similar issue occurs with a step of 0.1. Since the question focuses on integers, this should work just fine.
@Justastudent, indeed step must be 1, which is the default and is what OP has.
2

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.

5 Comments

@Alnitak its not a nice solution, but not every solution is a nice solution.
By all means strip the '.' from pasted data, but disabling standard operations is bad, especially for accessibility users.
You might also want to listen for - (minus) key and + (plus) key because those are also allowed in the number field and can result in the same issue. Also, note that the keycodes for the Numpad versions of those keys are different.
Also, e can be typed in when the input is of number type.
I have modified your solution to work with paste and without conditionals and also prevent any extra characters such as e + or -.
1

See MDN docs on inputs 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>

1 Comment

the original issue happens if you type 123.. - so, try that in your code ... once you have the .. in there you can type 123..1.2.3.4.5.6 if you want :p
0

$(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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.