2

    document.getElementById('my').onkeypress = function(event) {
      this.value = this.value.toUpperCase()
    }
    <input id='my' type="text">

Can someone explain to me what the this variable points to in the code above? Does it point to the input html element I grabbed from the document.getElementById('my)? Or does it point to the window object in the browser? Also what is the event parameter passed into the anonymous function?

For some reason when I run this code the value of each character is uppercased except the last char. So for example when I enter: a. The character a is not uppercased immediately it is only uppercased when I enter another letter. For example: Ab. Now b is not uppercased until I enter another letter after b: ABc. And this continues on. Can someone please explain why this happen?

James
  • 20,957
  • 5
  • 26
  • 41

2 Answers2

1

Can someone explain to me what the this variable points to in the code above? Does it point to the input html element I grabbed from the document.getElementById('my)? Or does it point to the window object in the browser? Also what is the 'event' parameter passed into the anonymous function?

  • this refers to the input element
  • it's not an anonymous function, it's the declaration of the onkeypress function
  • event is a parameter of the above function more info

The unexpected(?) behaviour is because the code is executed before the input field is updated, so only the previous value gets uppercased. To avoid it, you can use onkeyup event which fires after you release a key.

See it here:

document.getElementById('my').onkeypress = function(event) {
  this.value = this.value.toUpperCase()
}

document.getElementById('my2').onkeyup = function(event) {
  this.value = this.value.toUpperCase()
}

document.getElementById('my3').oninput = function(event) {
  this.value = this.value.toUpperCase()
}
<input id='my' type="text" placeholder="onkeypress">
<input id='my2' type="text" placeholder="onkeyup">
<input id='my3' type="text" placeholder="oninput">

Thanks to @www139 for bringing up oninput in the comments as it is indeed the best solution for modern browsers Please note it's HTML5-only and you can't get info like the key code, identifier, etc...

Shomz
  • 37,421
  • 4
  • 57
  • 85
  • Yep, on key up seems like the answer :) http://stackoverflow.com/questions/3063434/how-can-i-get-jquery-val-after-keypress-event – DougieHauser Nov 21 '15 at 21:09
  • 2
    @DougieHauser, what about that, a duplicate? OP asked for explanation, not a jQuery solution. – Shomz Nov 21 '15 at 21:10
  • Hi, it knows which key is pressed since the onKeyDown event, that's not the thing. The thing is that it gives you an opportunity to do something **before** the input happens, **on purpose**. Sometimes you want something else in the field to show up, sometimes you don't want anything or only a specific keys to respond, etc. – Shomz Nov 21 '15 at 21:20
  • @Shomz, I discovered that if you use `window.setTimeout` with the function connected to onkeypress, it will behave just like the oninput solution! – www139 Nov 21 '15 at 21:42
  • Yes, that will launch an async event and put it in a queue, but is considered a hack and generally should be avoided (see this: http://ejohn.org/blog/how-javascript-timers-work/). The purest way to get everything working perfecly, even on the older browsers, is to combine onkeydown and onkeyup (one for modifying the text while being pressed, and the other after being released) by assigning them the same function. – Shomz Nov 21 '15 at 22:05
1

Here is a simple definition of the key events references from w3c.

Tip: The order of events related to the onkeypress event:

onkeydown onkeypress onkeyup Note: The onkeypress event is not fired for all keys (e.g. ALT, CTRL, SHIFT, ESC) in all browsers. To detect only whether the user has pressed a key, use onkeydown instead, because it works for all keys.

This explains the oninput event; http://help.dottoro.com/ljhxklln.php

The oninput event has support of all the major browsers including IE 9 and later.

oninput better suits your needs than the "second-best" onkeyup because onkeyup only fires when the key is released. When you type, the new value is entered as soon as it is pressed, however it seems to add the new value to the box after the function fires. I will continue to experiment because I have another idea of how to do this but oninput seems like the best key event for this at the moment.

document.getElementById('my').oninput = function(event) {
  this.value = this.value.toUpperCase()
}
<input id='my' type="text">

UPDATE

You can still actually use the onkeypress event but you need to use a timeout to wait for the new value to be inserted into the text box before executing the function.

Here is another code snippet....

document.getElementById('my').onkeypress = function(event) {
  var elem = this;
  window.setTimeout(function() {
    elem.value = elem.value.toUpperCase()
  }, 0);
}
<input id='my' type="text">
www139
  • 4,960
  • 3
  • 31
  • 56