I'm writing some jQuery which intercepts the value entered in an input field and determines whether to allow or to prevent the typed value.
I need to get the next value, i.e., what the value will be were I to permit the key-press, and I need to know this value at a point before it is displayed, so I'm using the keypress
event.
My question is: inside the keypress
event, how can I tell what the resultant value would be were I to permit the key-press? What is the 'potential value'?
If I write out the key-press event object to the console and inspect the properties, I can see that currentTarget.value
shows this 'potential value'. However, if I use this property inside the keypress
event then it returns only the value prior to the context key-press.
For example, if the user types "a" into an empty text box bound to the following jQuery
$(":input").on("keypress", function(e) {
console.log(e);
console.log(e.currentTarget.value);
});
Digging down through the first console output (e
) shows that currentTarget.value
= "a".
But the second console output (e.currentTarget.value
) will show "".
If the user was then to type "b" into that same text box then:
Manually inspectng e
and locating currentTarget.value
displays "ab"; Dumping e.currentTarget.value
from inside the event displays "a".
Can anyone explain how I can get this 'potential value' while inside the keypress
event?
Not the prettiest of solutions (you can see the would be result just before it's reverted), but to save the trouble of discerning between arrow/control and input keys etc, you could store the original value in keypress
and revert to that in keyup
if needed (also storing the selection positions for complete reversion)
$(":input").keypress(function(e) {
$(this).data('orgValue', {value: this.value, pos: this.selectionStart, selend:this.selectionEnd});
}).keyup(function(e){
var val = this.value;
if(!somevalidation(val)){
var org =$(this).data('orgValue');
this.value = org.value;
this.selectionStart = org.pos;
this.selectionEnd = org.selend;
}
});
Example fiddle
Edit
Did some testing, but jquery makes predicting the outcome relatively easy. Not only does it fill the key property, it also fills other properties on its event on which the type of key can be checked. While testing charCode seems to be 0 for 'non input' keys. The straight forward would be:
$(":input").keypress(function(e) {
if(!e.charCode)return; //is 0 for non input
var cur = this.value; //current value
var val = cur.substring(0,this.selectionStart)
+ e.key
+ cur.substring(this.selectionEnd);
return cur=== val //unchanged
|| somevalidation(val);
});
But that would not include deletes/backspaces, to handle those as well:
$(":input").keypress(function(e) {
var key,start = this.selectionStart ,end = this.selectionEnd;
if(e.charCode)
key = e.key;
else{
if(e.keyCode===8 || e.keyCode===46){
key = '';
if(end===start){
if(e.keyCode===8)
start--;
else
end++;
}
}
else
return true; //charCode is 0 for non input 46 = delete 8 = backspace
}
var cur = this.value; //current value
var val = cur.substring(0, start) + key + cur.substring(end);
return cur=== val //unchanged
|| somevalidation(val);
});
While testing this seemed to behave as expected. An other way might be have a hidden input field, send the keys there and examine its results, but the above should do the trick.