9

How to restrict the input field to enter only numbers/digits int and float both. Sometimes we need to allow both integer as well as float value for fields like amount, so in that case the validation is required. There are no of solutions available but they are of large size code. So need a short but effective code.

<p> Input box that accepts only valid int and float values.</p>
<input class="number-only" type=text />
vinayakj
  • 5,591
  • 3
  • 28
  • 48
  • 1
    The hybrid (HTML5/Javascript) solutions have the advantage that some mobile devices present a soft keyboard optimised for entering numbers. – MZB Jun 21 '15 at 16:33

6 Answers6

19

No need for the long code for number input restriction just try this code.

It also accepts valid int & float both values.

Javascript Approach

onload =function(){ 
  var ele = document.querySelectorAll('.number-only')[0];
  ele.onkeypress = function(e) {
     if(isNaN(this.value+""+String.fromCharCode(e.charCode)))
        return false;
  }
  ele.onpaste = function(e){
     e.preventDefault();
  }
}
<p> Input box that accepts only valid int and float values.</p>
<input class="number-only" type=text />

jQuery Approach

$(function(){

  $('.number-only').keypress(function(e) {
 if(isNaN(this.value+""+String.fromCharCode(e.charCode))) return false;
  })
  .on("cut copy paste",function(e){
 e.preventDefault();
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p> Input box that accepts only valid int and float values.</p>
<input class="number-only" type=text />

UPDATE

The above answers are for most common use case - validating input as a number.

But as per comments, some wants to allow few special cases like negative numbers & showing the invalid keystrokes to user before removing it, so below is the code snippet for such special use cases.

$(function(){
      
  $('.number-only').keyup(function(e) {
        if(this.value!='-')
          while(isNaN(this.value))
            this.value = this.value.split('').reverse().join('').replace(/[\D]/i,'')
                                   .split('').reverse().join('');
    })
    .on("cut copy paste",function(e){
     e.preventDefault();
    });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p> Input box that accepts only valid int and float values.</p>
<input class="number-only" type=text />
vinayakj
  • 5,591
  • 3
  • 28
  • 48
  • 1
    I didn't realize that isNaN checks for decimals as well. Upvoted for elegance. :) Do you know if this works with on screen keyboards or keyboard assistants that type on behalf of the user ? – Kraang Prime Jun 14 '15 at 22:55
  • @SanuelJackson thanks. Yes this works with onscreen keyboards, you can try OS's on-Screen keyboard, as its same event is captured. And by with keyboard assistants you mean the autofill feature of browsers then no for that you need some extra code. `.change(function(e) { if(isNaN(this.value)) this.value=""; })` – vinayakj Jun 15 '15 at 16:38
  • OP may not care, but this only works with non-negative numbers. It won't accept -1. – Guy Schalnat Jun 15 '15 at 23:41
  • @GuySchalnat I would care ofcourse.. why not.. but the above code is for most common case and for some special cases like allowing-negative numbers also you can add one more condition and rest of the code can stay as is. – vinayakj Jun 16 '15 at 14:51
  • @GuySchalnat Updated the answer to address the concerns about special cases - negative nos & - showing invalid keystrokes. – vinayakj Jun 20 '15 at 14:31
  • Thanks @vinayakj. Yes, better. You can't type in -.5 yet, and the delete key doesn't work, but this is getting closer to a good solution. – Guy Schalnat Jun 21 '15 at 01:15
  • As it is, you can enter ".5" and "-.5" if you type the number first and then add the rest; I don't know whether that is desired behaviour. – m69's been on strike for years Jun 21 '15 at 03:45
  • @GuySchalnat yes you cant type -.5,but more appropriate entry would be -0.5 & that is allowed but still if you want you can again add code to accommodate that `if(this.value!='-' || this.value!='-.' || this.value!='.')`, but I really think thats not necessary as you can always type `0.5`, `-0.5`, `-5` – vinayakj Jun 21 '15 at 07:37
  • Also the delete key seems to be working, can you please explain how it was not working. BTW I didnt downvote your answer,someone did, so I am upvoting it as it discuss different use cases fairly. – vinayakj Jun 21 '15 at 07:48
  • Ok, I must have been hitting the wrong key. Delete works. Thanks for the upvote. I figure that our job is to give the original poster as well as anyone who reads this afterwards the best possible answer, and since you have the accepted answer, I might as well help out by being your QA person. I'd prefer you to update that third answer with your fix, as most people won't read the comments, but that is up to you. Thanks for making your answer better. – Guy Schalnat Jun 22 '15 at 02:03
  • @GuySchalnat All credit goes to you for the updated third answer, it is the outcome of your QA only, – vinayakj Jun 22 '15 at 15:10
  • Spaces still allowed :( – DanDuh Sep 03 '15 at 08:40
  • @vinayakj Old android mobiles are generating charCode 229 for all key events for any characters. Do you have any idea how to handle this ? – Venkatesh K Jul 31 '17 at 12:28
  • @VenkateshK I dont have idea about the key events in android mobiles. Cant help you in that. – vinayakj Jul 31 '17 at 16:09
12

One-liner solution #1:

Use <input type="number"> with the step attribute.

<input type="number" step="0.0001"> // The user can enter up to 4 decimal places.

<input type="number" step="any"> // Not supported in all browsers, but permits numbers of any decimal precision.

You can also use the min and/or max attributes to set the minimum value and/or the maximum value.


One-liner solution #2:

Use a regular text input element with a RegExp pattern attribute.

<input type="text" pattern="^-?([0-9]*\.?[0-9]+|[0-9]+\.?[0-9]*)$">

This RegExp accepts numbers beginning with a dot ( . ) and/or a negative sign ( - ).

clickbait
  • 2,818
  • 1
  • 25
  • 61
  • 3
    Just a footnote on this answer. This input type is only valid in HTML5, [current html5 tag support](http://www.quirksmode.org/html5/inputs/) – Kraang Prime Jun 14 '15 at 23:00
  • 2
    Few things that matter here: 1. Thats HTML5 feature 2. Look & feel is different per browser 3. on the go validation not available 4. for validation that is too on submit you have to have form tag enclosing this. 5. Error messages are not same across all browsers – vinayakj Jun 15 '15 at 16:14
4

First things first. I prefer showing the invalid keystrokes rather than preventing them. User Experience Stack Exchange seems to agree at the moment (see this question).

That said, not everyone agrees, so let's see what we can do.

Second. This doesn't replace a validation step. There are certain valid keystroke combinations that are not valid numbers, but need to be permitted in order to enter valid numbers. For example, the user could type a decimal mark (full stop or comma, depending on the language they are using), and then leave the text box, and you don't have a valid number. The following strings are all starts of numbers, but not yet valid:

  • .
  • -.
  • ,
  • -,

The first two are the start of .5 or -.5, while the last two are the same in the various languages that use a comma instead of a full stop for the decimal mark.

This brings us to the (already rejected)

<input type="number" step="any">

Of course, you will have to include a JavaScript script to fix non-modern browsers, but those are available. In theory, these should also work correctly when the user works in a language that uses the comma instead of the full stop for the decimal mark. Even better, since users usually use only one browser, and since they will be used to how input number works in that browser, and since they will spend most of their time on other websites than yours, they may get confused if your website does not behave the same way they are used to.

But maybe you still want to make your own solution. If all else fails, I would go with a regular expression (yes, I know, I now have two problems). I don't believe in allowing spaces, so I limit it to a negative sign, digits, and one decimal mark (whichever they are using). For example:

$('.rational-number').on('keypress', function(e)
{
  if (e.charCode >= 32 && e.charCode < 127 && 
      !/^-?\d*[.,]?\d*$/.test(this.value + '' + String.fromCharCode(e.charCode)))
  {
    return false;
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type-"text" class="rational-number">

This ALMOST works. The only problem I now have is, it assumes any character you type goes at the end of the string. This is fine except for the '-' for negative numbers, which is only allowed at the beginning. So you can type -5.4, but if you type 5.4 and then hit the home key or left arrow back to the beginning, it won't let you make it negative.

It also won't deal with pasting. Paste is a complicated topic. I don't agree with rejecting all paste operations. I feel the best option here is to just let the user paste and let the validator pick up any invalid numbers.

Community
  • 1
  • 1
Guy Schalnat
  • 1,697
  • 15
  • 26
3

You can add a pattern attribute to the input field. If the input value doesn't match the pattern, you can style the input field and/or show an error message by using the css selector :invalid:

.error-msg {
  display: none; /* Hide by default */
}
.number-only:invalid {
  background: pink;
}
.number-only:invalid + .error-msg {
  display: inline;
}
<input type='tel' class='number-only' pattern='[+\-]?\d*\.?\d+' />

<span class='error-msg'>Please enter a valid integer or float value.</span>

Some notes:

  • type='tel' makes mobile browsers open a number keyboard, but of course you can also set the type to text.
  • Browser support for the pattern input attribute: http://caniuse.com/#feat=input-pattern
  • Browser support for the :invalid css selector: http://caniuse.com/#feat=form-validation
  • The pattern regex doesn't support exponential notation, e.g. 1.23e4.
  • The pattern regex doesn't allow spaces – they are not valid in int and float notation, but allowing them might improve user experience.
Matias Kinnunen
  • 7,828
  • 3
  • 35
  • 46
  • 1
    If application is for modern browsers only with HTML5 support then this would work, but this code is for modern browsers with no restriction on invalid key entry, though totally dependent on UX wanted, so for other browsers need to have native validation script. Upvote for detailed explaination – vinayakj Jun 21 '15 at 14:02
1

Call one jquery function in onkeypress of the textbox. In that function use the respective ascii code to restrict input.

sivaprakash
  • 167
  • 1
  • 4
  • 13
  • yes.. then I have to go on comparing the ASCII code for each invalid key and code becomes bigger, but need is for minimal code with near all use cases coverage – vinayakj Jun 21 '15 at 07:43
  • function isNumberKey(evt) { var charCode = (evt.which) ? evt.which : event.keyCode; if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57)) { return false; } else { return true; } } call this method in textbox onkeypress – sivaprakash Jun 21 '15 at 13:58
  • see first comment there it explains its limitation. http://stackoverflow.com/questions/891696/jquery-what-is-the-best-way-to-restrict-number-only-input-for-textboxes-all#answer-13084976 – vinayakj Jun 21 '15 at 14:08
-5

User can not enter Decimal value in js. Try using this code :

if(document.getElementById(id).value.indexOf('.') != -1){
    print "do not Enter decimal nuber";
}
Michaël Azevedo
  • 3,874
  • 7
  • 31
  • 45