#14703 closed defect (fixed)
onInput and "normalization" in TextBoxMixin handleEvent
Reported by: | mm | Owned by: | Douglas Hays |
---|---|---|---|
Priority: | undecided | Milestone: | 1.8 |
Component: | Dijit - Form | Version: | 1.7.1 |
Keywords: | Cc: | ||
Blocked By: | Blocking: |
Description
I’m trying to implement onInput handler and I have found this logic quite confusing
For numbers onInput is caled twice (for keyydown and keypress) For CTRL+V also called twice (keypress and paste)
Tested in FF
I dont find this simplification.
Please can someone review ?
postCreate: function(){
setting the value here is needed since value="" in the template causes "undefined" and setting in the DOM (instead of the JS object) helps with form reset actions this.textbox.setAttribute("value", this.textbox.value); DOM and JS values should be the same
this.inherited(arguments);
normalize input events to reduce spurious event processing onkeydown: do not forward modifier keys set charOrCode to numeric keycode onkeypress: do not forward numeric charOrCode keys (already sent through onkeydown) onpaste & oncut: set charOrCode to 229 (IME) oninput: if primary event not already processed, set charOrCode to 229 (IME), else do not forward var handleEvent = function(e){
var charCode = e.charOrCode e.keyCode 229; if(e.type == "keydown"){
switch(charCode){ ignore "state" keys
case keys.SHIFT: case keys.ALT: case keys.CTRL: case keys.META: case keys.CAPS_LOCK:
return;
default:
if(charCode >= 65 && charCode <= 90){ return; } keydown for A-Z can be processed with keypress
}
} if(e.type == "keypress" && typeof charCode != "string"){ return; } if(e.type == "input"){
if(this.skipInputEvent){ duplicate event
this.skipInputEvent = false; return;
}
}else{
this.skipInputEvent = true;
} create fake event to set charOrCode and to know if preventDefault() was called var faux = lang.mixin({}, e, {
charOrCode: charCode, wasConsumed: false, preventDefault: function(){
faux.wasConsumed = true; e.preventDefault();
}, stopPropagation: function(){ e.stopPropagation(); }
}); give web page author a chance to consume the event if(this.onInput(faux) === false){
event.stop(faux); return false means stop
} if(faux.wasConsumed){ return; } if preventDefault was called setTimeout(lang.hitch(this, "_onInput", faux), 0); widget notification after key has posted
}; array.forEach([ "onkeydown", "onkeypress", "onpaste", "oncut", "oninput" ], function(event){
this.connect(this.textbox, event, handleEvent);
}, this);
},
Attachments (1)
Change History (21)
comment:1 Changed 9 years ago by
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 Changed 9 years ago by
Milestone: | tbd → 1.8 |
---|---|
Resolution: | invalid |
Status: | closed → reopened |
The keydown event still deals with enhanced keyboard scan codes and not ascii codes like keypress does. Hoever, there are some optimizations that could be made to eliminate keypress events for combinations like ctrl+A that cannot be stopped in keypress, and also to eliminate keydown events for printable keys that are outside the a-z0-9 range.
comment:3 Changed 9 years ago by
mm, please review the patch. ctrl+A will come thru keydown and not keypress to prevent the browser from seeing it first. Normal printable keys that relocate on different keyboards should not have keydown events with their random scan codes and will be seen only in keypress. numpad specific scan codes will be ignored unless modified with ctrl/alt/meta.
This is working as-designed. The API doc says the event is of type keydown | keypress | cut | paste | input. Some keys are best handled by keydown (ESC) and others by keypress (alpha-numberic). onInput is a general purpose handler to let the user know that something has happened.