Reputation: 11925
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?
Upvotes: 12
Views: 21562
Reputation: 11925
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...
Upvotes: 1
Reputation: 37533
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);
}
}
Upvotes: 1
Reputation: 106332
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;
}
Upvotes: 0
Reputation: 6356
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.
Upvotes: 2
Reputation: 171764
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
}
}
Upvotes: 0