25

I want to restrict the user to only be able to change the contents of the box with the spinners provided with input type="number" in HTML5, and not be able to type anything into the box

<input type="number" min="0" value="0" step="5"/>

Can I do this?

(my intended audience will only be using Chrome, so the spinners not appearing on IE(9) and Firefox(13) is not an issue)

Ed Harrod
  • 3,423
  • 4
  • 32
  • 53
  • 1
    possible duplicate of [Is there a way to stop manual input in a type=number but still allow changes with the "up/down" buttons?](http://stackoverflow.com/questions/18290960/is-there-a-way-to-stop-manual-input-in-a-type-number-but-still-allow-changes-wit) – Léo Lam Apr 24 '14 at 08:49
  • 1
    ah yes, that is the same question, but Mr. Alien's answer is what I am looking for. – Ed Harrod Apr 24 '14 at 08:53
  • @LéoLam Out of interest, how did you find that? It doesn't mention spinners – Ed Harrod Apr 24 '14 at 08:54
  • There's already [an answer that is similar to Mr. Alien's answer](https://stackoverflow.com/a/18291025/1636285). The question says: "I would like to stop users from being able to type in the input, but still allow for changes using the *"up/down" arrows* that appear with type=number." I believe the "spinners" you're talking about are the "arrows". – Léo Lam Apr 24 '14 at 08:55
  • @LéoLam I wouldn't say they are similar personally! I understand the link, I was just curious where you saw it as I searched before I posted, was it under "Related"? – Ed Harrod Apr 24 '14 at 09:01
  • Yes, it was under "Related". The answer in this question is, admittedly, better that the one in the question that was linked (with the new edit). But still, it is not a reason to ask duplicate questions ;) – Léo Lam Apr 24 '14 at 09:07
  • I know, I wouldn't have asked if I'd found the original question! – Ed Harrod Apr 24 '14 at 09:09
  • No worries, I hope a moderator will "merge" the two questions instead of closing/deleting this one, as the answer in this question is better in my opinion – Léo Lam Apr 24 '14 at 09:10
  • another working tricks http://stackoverflow.com/questions/27740112/how-to-make-input-type-number-un-editable-but-still-functioning – superdb Jan 05 '15 at 05:44

3 Answers3

57

You can use Javascript onkeydown event here... Which will prevent the user to type anything, and still he will be able to use the arrow controls to increase and decrease the numbers.

<input type="number" min="0" value="0" step="5" onkeydown="return false" />

Demo

Note: Just don't depend on JavaScript and HTML, always have a server side validation to ensure that user didn't posted any malicious input. Javascript can be disabled and user can misuse by adding any text in the textbox, but there is no other way you can stop him, so keep a server side check as well.


As you commented that you will like to disable the text selection as well, so that users don't get confused, you can also use CSS positioning techniques here, as you said that intended users are of Chrome only, so there is not much of cross browser issue, so you can do something like this...

Demo 2

Wrap the input element with the span element, and just with CSS positioning technique and :after pseudo, we overlay a virtual element over the input.

Now I've kept the outline just for the demonstration purposes, you can remove them safely.

span {
    position: relative;
    outline: 1px solid #00f;
}

span:after {
    content: "";
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    position: absolute;
    outline: 1px solid red;
    width: 91%;
}
Mr. Alien
  • 153,751
  • 34
  • 298
  • 278
  • thanks, that's great, don't worry I have server-side validation too. It may be slightly misleading as the box can be selected with the cursor, but not changed, do you know of a way to disable selection without disabling the spinners? – Ed Harrod Apr 24 '14 at 08:47
  • 1
    @ECH: maybe you could add some CSS styling to make it look like it's disabled? Also, this didn't prevent me from copy/pasting something into it, nor having autocomplete (!) suggest something – Léo Lam Apr 24 '14 at 08:57
  • 1
    This is quite elegant. But for example if I zoom the page in the browser the arrows occupy less of the input field. Thus the 91% do not cover all the text part anymore. – Peter Leupold Oct 28 '16 at 19:45
  • Couldn't you still paste arbitrary values into the field? – Venryx May 08 '19 at 04:56
  • Hi, I don't know if you would see this but in React this didn't work for me. – İlker Mar 06 '21 at 09:31
3

Accepted answer uses onkeydown, which will disable the spinner as well; which is well documented here : https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event

You can use onkeypress which will prevent charCode keys. But MDN says keypress is on deprecation. Though it is well supported, you are advised against it. https://caniuse.com/#search=keypress

My solution is to have your own function to filter by keycodes and preventDefault on all other keyCodes. Note that updateValue is a custom function. To let the spinner do its work you can follow the inline method at the end.

myInputTag = document.getElementsByTagName('input')[0];

myInputTag.onkeydown = onlyUpDownKeys ;

function onlyUpDownKeys(e) {
(e.keyCode===38 || e.keyCode===40) ? updateValue(e): e.preventDefault(); 
}

This will work on all keyboard layouts. Explore compatibility for your users at https://caniuse.com/#search=.keycode

You may also fit this into the default inline Input tag definition in HTML like this :

'<input class="tableCell" type="number" min=0 onkeydown = "!(e.keyCode===38 || e.keyCode===40) && e.preventDefault();">';
bonney
  • 537
  • 4
  • 15
2

For ReactJs users, do this:

onKeyDown={(e) => {
                              e.preventDefault();
                            }}
AG_HIHI
  • 1,705
  • 5
  • 27
  • 69