How can I check the new value of a text field on keypress?
Asked Answered
L

6

12

I have a single form field and I need to be able to detect when the field changes and execute some additional code using the new value of the field. I only want to execute the code if the key pushed actually changes the value of the text box. Here's the solution I came up with.

function onkeypress(e) {
  var value = this.value;
  // do something with 
}

function onkeyup(e) {
  if ( e.which == 8 || e.keyCode == 46 ) { // delete or backspace keys
    this.onkeypress(e);
  }
}

There's just one problem though. onkeypress is fired before the field's value is updated, so when I grab the value, I'm getting the previous value. I would use keyup exclusively if I knew a way to test whether the key changed the value or not, but some characters (like the arrow keys) have no effect on the field's value.

Any ideas?

Ludwick answered 19/1, 2010 at 20:28 Comment(0)
P
2

The way I do this is simply with a variable along the lines of prevValue. At the end of the key press function, store the value in that variable, and only execute the function again if the value doesn't equal that previous value.

Pythagorean answered 19/1, 2010 at 20:34 Comment(0)
D
7

this is easy, just use onkeyup instead of onkeypress

Deonnadeonne answered 3/3, 2013 at 23:38 Comment(1)
You should consider adding explanation as to why onkeyup would work instead of onkeypress.Unlade
P
2

The way I do this is simply with a variable along the lines of prevValue. At the end of the key press function, store the value in that variable, and only execute the function again if the value doesn't equal that previous value.

Pythagorean answered 19/1, 2010 at 20:34 Comment(0)
S
1

have another conditional:

if(e.keyCode > 31  && e.keyCode < 127) {
    value = this.value + e;
}

This would catch any low level ascii symbol entered by the keyboard outside of the special char range.

EDIT: (32 is space)

function onkeyup(e) {        
  if ( e.which == 8 || e.keyCode == 46 ) { // delete or backspace keys 
    switch(e.keyCode) {
      case 32:
      case 48..90:
      case 96..111:
      case 188:
      case 190..192: 
      case 219..222:
          value = this.value + e;
          break;
      default: 
          break;
    }       
    this.onkeypress(e);        
  }        
}
Skyjack answered 19/1, 2010 at 20:34 Comment(4)
Yah, that's what I was meaning :) Sorry for the vagueness. I should have been more specific that the conditional needed to be nested.Skyjack
Actually, I just realized that this won't work, because the key codes don't necessarily match up with ascii codes. See developer.mozilla.org/en/DOM/Event/UIEvent/KeyEventLudwick
Eh, it still works, you just have to adjust the numbers. Let me try an edit of the conditional.Skyjack
- _ | these characters are false positivesHiphuggers
L
1

Here's my final solution, which uses a prevValue variable but doesn't pollute the global namespace (window) or the dom element's properties.

(function() {
  var input = document.getElementById('input_box'),
      prevValue;

  input.onkeyup = function(e) {
    if ( this.value != prevValue ) {
      prevValue = this.value;
      // execute some more code here...
    }
  }
}());

Notice above that the onkeyup function serves as a closure around the prevValue variable. This prevents the namespace pollution so I don't have to create a global variable or attach a property to the input element itself. This is as elegant as I can get it. I actually wrote mine in jQuery but thought the answer itself should be pure JavaScript...

Ludwick answered 20/1, 2010 at 15:32 Comment(0)
D
0

It's kind of a hack, but you can put the previous value in a property of the textbox (called "expando attributes")

function onkeypress(e) {
  this.oldvalue = this.value;
}

function onkeyup(e) {
  if (this.value != this.oldvalue) {
    // do something
  }
}
Damarisdamarra answered 19/1, 2010 at 20:34 Comment(0)
A
0

You could store the old value and detect if it changed:

function keyUpHandle(e) {
  if (this.prevValue && this.prevValue != this.value) {
    // do something
  }
  this.prevValue = this.value;
}
Agrigento answered 19/1, 2010 at 20:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.