4

I don't know if this is possible (it looks like it's not), but I'm trying to find a way to detect, inside the onKeyDown or onKeyPress event of an HTML input tag, what the resulting value will be.

It's important that I use these events. I can't just use onKeyUp, because by then the input will have already changed. I want to prevent it from happening in the first place. I've also tried appending the pressed key character to the end of the string, but that doesn't account for cases where you typed a character in the beginning of the string in the input field.

Any ideas? I've looked for a while and it doesn't seem possible but I figured I'd ask.

Carlos Rodriguez
  • 2,190
  • 2
  • 18
  • 29

2 Answers2

8

Here I have 2 versions, one with jQuery and other with JavaScript alone.

$("#inputJQuery").on("keydown", function(ev){
 console.log("jQuery value:", $(this).val()); // this is the value before the key is added
 console.log("jQuery selectionStart:", this.selectionStart); // the position where the character will be inserted
 console.log("jQuery selectionEnd:", this.selectionEnd); // if has a selection this value will be different than the previous
})

document.querySelector("#inputVanilla").onkeydown = function(ev){
 console.log("VANILLA value:", this.value); // this is the value before the key is added
 console.log("VANILLA selectionStart:", this.selectionStart); // the position where the character will be inserted
 console.log("VANILLA selectionEnd:", this.selectionEnd); // if has a selection this value will be different than the previous
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<input id="inputJQuery" type="text"/>
<input id="inputVanilla" type="text"/>
Manuel Sánchez
  • 174
  • 1
  • 7
  • I didn't mention this before because I didn't realize this was relevant, but my input is type "number". It looks like this only works for text input. Do you know of any way around that? If not I'll just have to switch to type text – Carlos Rodriguez Aug 24 '17 at 00:37
  • It's not possible for number-type inputs. https://stackoverflow.com/a/21959157/6605322 – Manuel Sánchez Aug 24 '17 at 00:43
2

Simply check for the length of the value on keydown. This also works for deleting characters.

You can also check against this in a conditional that returns false to prevent the user from typing in more than a certain number of characters. Note that you'll probably want to check this against the backspace and delete keys (keyCodes 8 and 46 respectively) so that you're able to delete keys once the maximum length is reached.

var input = document.getElementById('input');
input.onkeydown = function(e) {
  console.log(input.value.length);
  if (input.value.length == 10) {
    if (e.keyCode === 8 || e.keyCode === 46) {
      return true;
    } else {
      return false;
    }
  }
}
<input id="input">

Hope this helps! :)

Obsidian Age
  • 41,205
  • 10
  • 48
  • 71
  • Thanks for the reply, but it seems that checking for value.length simply returns the length of the input before the new character is applied. This doesn't help me determine where in the string the key is added. For example, say someone typed the number 100. They then add a 1 to the front (making the text box 1100. I need to know the new value before it is set to the input, so that I can prevent it. I'm not sure how that's possible with your answer. Thanks – Carlos Rodriguez Aug 24 '17 at 00:25
  • 1
    Oh, I see - my bad. You could always check on the `input.value` itself, like `if (input.value == 1100) { return false; }`, though this would only check after they actually type it. Having said that, you really shouldn't be preventing them from *typing* anything, rather validating the input once the form is submitted (or logic is handled). – Obsidian Age Aug 24 '17 at 00:41
  • Not sure I agree with that. If you set an inputs type to "number", chrome prevents any non numeric input from being entered altogether. I'm just trying to extend on that same thinking. Allowing negatives as long as they're in the right place, for example – Carlos Rodriguez Aug 24 '17 at 03:35
  • 1
    Oh yeah, you can certainly validate on the front-end. Though preventing actual input is rather unusual, and I'm not sure it's actually possible to prevent the inputs from being typed out preemptively. Personally I do things like check the `blur()` event, then add an inline error message if the input won't be accepted. Then the user knows they need to change it. Still, front-end validation is **never** enough, and you should **always** validate on the back-end as well (don't forget you can manipulate data after a form is submitted). – Obsidian Age Aug 24 '17 at 03:38
  • Yeah the back end is a REST Api, so I'm not assuming the requests are even coming from this page, or "a page" for that matter lol – Carlos Rodriguez Aug 24 '17 at 03:40