Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

this is easy, just use onkeyup instead of onkeypress

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);        
  }        
}

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...

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
  }
}

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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top