1

I have an input field:

    <input id="thing" type='number' placeholder='Up to 20 tickets' min='1' max='20' name='tickets'>

And despite the fact that I've listed min and max numbers, it still accepts typing random letters into the field, and such.

I'd like to only allow numbers 1 to 20 to appear in the field upon user input of any kind. How might I do that?

'input' DOM event? some HTML form magic?

Update Haaa, okay, so dynamically created form inputs don't function like normal inputs. The value fields aren't hooked up to user actions.

Costa Michailidis
  • 7,691
  • 15
  • 72
  • 124
  • See this stackoverflow answer: http://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input – Anthony Dekimpe May 18 '17 at 22:38
  • Possible duplicate of [HTML Text Input allow only Numeric input](http://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input) – Anthony Dekimpe May 18 '17 at 22:40
  • 1
    Which browser are you using? – Ry- May 18 '17 at 22:41
  • It's gotta work in all browsers. And those answers in the links that do limit input to certain number ranges (I've read most of them) don't allow for backspace or refreshing the page. They kind of break user expectations is really fundamental ways. I'm going to try to write a keyCode / preventDefault solution that allows TAB, F5, Backspace, delete, paste, copy... ugh... – Costa Michailidis May 18 '17 at 22:44

5 Answers5

1

Never trust user's input. Limiting values in html input is only for user's convenience. Even if you somehow limited user's ability to change input value directly, he could still press f12 (in Chrome), and manually change values to whatever he wants.

That being said, your code works just fine, and does what you want it to do- it limits user to input just numbers, between 1 and 20. Before doing anything with this data though, you have to validate it on the server, so server will make sure if it's really a number, and it's really between 1 and 20, because as I said- there's no way to prevent user from entering literally anything he wants into inputs.

Przemek K.
  • 75
  • 8
1

Using Chrome

document.querySelector( "input" ).addEventListener( "input", function( evt ) {
  var v = evt.target.value;
    if ( v ) {
      console.log( v ); // Only outputs numbers
    }
}, false );
<input type="number" value="1" min="1" max="20" name="foo" placeholder="bar">

Behaviour is as expected; nothing but numbers 1-20 are output.

Fred Gandt
  • 4,217
  • 2
  • 33
  • 41
0

You can use Plain Javascript.

<script>


function handleChange(input) {
    if ((input.value < 0) && ((input.value > 20))
       return false;
  }
</script>

HTMl code

<input type="number" onchange="handleChange(this);" />

Or you can use this

<input type="number" onKeyPress="if(this.value.length>20) return false;" />
Ananth A
  • 331
  • 2
  • 5
0

I ended up doing this:

var temp = ''
input.addEventListener('input', function (event) {
  if (this.value == '') return
  if (this.value < 1 || this.value > 20 || this.value.match(/\D/)) return this.value = temp
  temp = this.value
}, false)

The input event is the most broad. It captures copy pastes, and all other manner of changing field values.

The check for empty string is important, because if some one has typed 15, and changes their mind, and wants to type 20, they'll need to backspace twice, before typing the 2 and the 0. So, the state of empty is valid.

Anytime the function runs it stores the new value in a temp var, and we apply that immediately if we get input we don't like, because preventDefault() doesn't work with the input event.

Costa Michailidis
  • 7,691
  • 15
  • 72
  • 124
  • "because preventDefault() doesn't work with the input event" --- what is the "default event" for the "input"? What would you want to prevent for it? – zerkms May 18 '17 at 23:00
  • I want to prevent the character from being entered in the field. – Costa Michailidis May 18 '17 at 23:11
  • 1
    Yep, but `input` happens **after** the value changed. So you cannot prevent it since it's in the past. My point is that it's not "it does not work" but - "it makes no sense". – zerkms May 18 '17 at 23:27
  • 1
    Yeup, that's right. But you don't have access to the previous value either. And it's not just removing the last character because copy pastes happen, arrow keys get hit, and so on. Having a reliable previous value would be nice. – Costa Michailidis May 18 '17 at 23:29
  • True, I'm just being too pendantic and nitpicking, sorry :-) – zerkms May 18 '17 at 23:33
  • Hahaa, it's totally appropriate here, and with me in general. I make Dumb mistakes : ) – Costa Michailidis May 18 '17 at 23:34
0

My version, used for quantity inputs in a shop allowing only numbers and max 2 digits:

const qinputs = document.querySelectorAll('input.quantity-input');
const allowedkeys = ["Backspace", "Delete", "ArrowLeft", "ArrowRight"];

qinputs.forEach(qinput => {
 qinput.addEventListener('keydown', function handleClick(event) {
     pressedKey = event['key'];
     if (!allowedkeys.includes(pressedKey) && (isNaN(pressedKey) || (this.value.length > 1))) {
         event.preventDefault();
     }
 });
});
<input type="text" class="quantity-input" value="1">

There is just one problem with this: You cannot select and overwrite values. Only delete and write again. A possible solution would be to allow all entries and then have the script correct the value afterwards (onkeyup, maybe).

Ralf
  • 598
  • 1
  • 7
  • 17