gbateson
asked on
onkeypress disables onChange
how can I get Navigator 4+ to recognize onChange events for form elements, when I also need an event handler for onKeyPress events in the document. The code below works fine on Explorer, but when used with Netscape 4+, it detects Shift-Ctrl-A, D and S, but does not detect the onChange events for the text boxes in a form. What changes do I need to make to get Netscape to process the Shift-Ctrl keys AND the onChange events?
many thanks in advance for your suggestions and comments.
<HTML><HEAD><TITLE>key press test</TITLE>
<SCRIPT LANGUAGE="JavaScript1.2">< !--
/* set up the onKeyPress event handler
to intercept keyboard shortcuts */
if (document.layers) document.captureEvents(Eve nt.KEYPRES S)
document.onkeypress=myKeyP ress
function myKeyPress(e){
if (document.layers && e.which){ // netscape
var m = e.modifiers
var alt = (m & Event.ALT_MASK)
var ctrl = (m & Event.CONTROL_MASK)
var shift = (m & Event.SHIFT_MASK)
var ascii = e.which
} else if (document.all){ // explorer
var alt = event.altKey
var ctrl = event.ctrlKey
var shift = event.shiftKey
var ascii = event.keyCode
} // end if
if (ctrl && shift && !alt) {
if (ascii==1) alert('ctrl-shift-A')
else if (ascii==4) alert('ctrl-shift-D')
else if (ascii==19) alert('ctrl-shift-S')
} // end if
} // end function
//--></SCRIPT>
</HEAD>
<BODY><FORM>
Text item 1:
<INPUT type=text name=item1 length=20 maxlength=20
onChange='alert("changed item 1")'><BR>
Text item 2:
<INPUT type=text name=item2 length=20 maxlength=20
onChange='alert("changed item 2")'><BR>
</FORM></BODY></HTML>
many thanks in advance for your suggestions and comments.
<HTML><HEAD><TITLE>key press test</TITLE>
<SCRIPT LANGUAGE="JavaScript1.2"><
/* set up the onKeyPress event handler
to intercept keyboard shortcuts */
if (document.layers) document.captureEvents(Eve
document.onkeypress=myKeyP
function myKeyPress(e){
if (document.layers && e.which){ // netscape
var m = e.modifiers
var alt = (m & Event.ALT_MASK)
var ctrl = (m & Event.CONTROL_MASK)
var shift = (m & Event.SHIFT_MASK)
var ascii = e.which
} else if (document.all){ // explorer
var alt = event.altKey
var ctrl = event.ctrlKey
var shift = event.shiftKey
var ascii = event.keyCode
} // end if
if (ctrl && shift && !alt) {
if (ascii==1) alert('ctrl-shift-A')
else if (ascii==4) alert('ctrl-shift-D')
else if (ascii==19) alert('ctrl-shift-S')
} // end if
} // end function
//--></SCRIPT>
</HEAD>
<BODY><FORM>
Text item 1:
<INPUT type=text name=item1 length=20 maxlength=20
onChange='alert("changed item 1")'><BR>
Text item 2:
<INPUT type=text name=item2 length=20 maxlength=20
onChange='alert("changed item 2")'><BR>
</FORM></BODY></HTML>
To me it appears to work correctly. The onChange event in Netscape is not fired until the form element looses focus. If you need to know when a key is pressed in the text field, set up another handler for the keyDown event.
ASKER
Thanks for your quick response knightEknight. On further invesitgation, prompted by your comment, I also found the problem does not occur using NN 4.5 (Mac). However, I definitely have the problem using NN 4.04 (Win) and results I have recieved from WWW forms seem to indicate it probably occurs on NN4.5 (Win) and NN4.7 (Win) aswell. Perhaps this is a NN (Win) thing? Can you (or anyone else listening in) confirm that?
Point taken -- I am using NN 4.08, and I have noticed that there are some bugs in later versions (4.7) that do not occur in my version, and the other way around as well. Perhaps it has something to do with that. In any event, a keyDown handler solution will probably work in all 4+ versions (if I understand the problem correctly).
ASKER
Thanks again for your input, knightEknight. onkeydown should work for NN 4+, but according to IE documentation at:
http://msdn.microsoft.com/workshop/author/dhtml/reference/events/onkeydown.asp
onkeydown is only recognized by IE 5+ and I can confirm that the most recent MS browser for Mac, namely IE 4.5 (Mac) does not recognize onkeydown. Consequently. I have changed the code to trap onkeypress for IE and onkeydown for NN. Unfortunately, I cannot test these changes on NN 4.04 (Win) until Monday morning. I'll let you know how things go and in the meantime, have a peaceful weekend. By the way, the modified code looks like this:
<HTML><HEAD><TITLE>key event test</TITLE>
<SCRIPT LANGUAGE="JavaScript1.2">< !--
if (document.layers){ // netscape
document.captureEvents(Eve nt.KEYDOWN )
document.onkeydown=myKeyEv entHandler
} else if (document.all) { // explorer
document.onkeypress=myKeyE ventHandle r
} // end if
function myKeyEventHandler(e){
/* same as myKeyPress
in the original question */
} // end function
//--></SCRIPT>
</HEAD>
<BODY><FORM>
<!-- as in the original questino -->
</FORM></BODY></HTML>
http://msdn.microsoft.com/workshop/author/dhtml/reference/events/onkeydown.asp
onkeydown is only recognized by IE 5+ and I can confirm that the most recent MS browser for Mac, namely IE 4.5 (Mac) does not recognize onkeydown. Consequently. I have changed the code to trap onkeypress for IE and onkeydown for NN. Unfortunately, I cannot test these changes on NN 4.04 (Win) until Monday morning. I'll let you know how things go and in the meantime, have a peaceful weekend. By the way, the modified code looks like this:
<HTML><HEAD><TITLE>key event test</TITLE>
<SCRIPT LANGUAGE="JavaScript1.2"><
if (document.layers){ // netscape
document.captureEvents(Eve
document.onkeydown=myKeyEv
} else if (document.all) { // explorer
document.onkeypress=myKeyE
} // end if
function myKeyEventHandler(e){
/* same as myKeyPress
in the original question */
} // end function
//--></SCRIPT>
</HEAD>
<BODY><FORM>
<!-- as in the original questino -->
</FORM></BODY></HTML>
ASKER
Well, unfortunately onkeydown was no more effective on NN 4.04 (Win) than onkeypress. However, trying to move forward, I found this warning in "The Javascript Bible" (p449):
"In Navigator 4, if you have both onChange= and any keyboard event handlers defined for the same text field tag, the onChange= event handlers are ignored. This is not true for Internet Explorer, where all events fire."
This doesn't seem to be true if the keyboard event handlers are defined at the document level. In this case, NN 4.x behave inconsistently. As reported above, NN 4.04 (Win) definitely ignores the onChange and NN 4.5 (Win) and 4.7 (Win) probably do. On the other hand, NN 4.6 (Win) and 4.6 (Mac) recognize the onChange. Consequently, it seems the only way to account for these inconsistencies is to either i) check whether the NN version number is one of the versions that ignores onChange when onkeypress/down/up is defined, or ii) make sure onkeypress/down/up always fires the onChange event handler if there is one. Either option means firing the onChange event handler every time a key is pressed in NN, not only when the element losses focus. I chose option ii), because the resulting code looks cleaner. Here's the code I have settled upon. Thank you for your help, I am happy to give you 100 points.
<HTML><HEAD><TITLE>key press test</TITLE>
<SCRIPT LANGUAGE="JavaScript1.2">< !--
/* set up the onKeyPress event handler
to intercept keyboard shortcuts */
if (document.layers) document.captureEvents(Eve nt.KEYPRES S)
document.onkeypress=myKeyP ress
function myKeyPress(e){
if (document.layers && e.which){ // netscape
var m = e.modifiers
var alt = (m & Event.ALT_MASK)
var ctrl = (m & Event.CONTROL_MASK)
var shift = (m & Event.SHIFT_MASK)
var ascii = e.which
} else if (document.all){ // explorer
var alt = event.altKey
var ctrl = event.ctrlKey
var shift = event.shiftKey
var ascii = event.keyCode
} // end if
if (ctrl && shift && !alt) {
if (ascii==1) alert('onkeypress event (ctrl-shift-A)')
else if (ascii==4) alert('onkeypress event (ctrl-shift-D)')
else if (ascii==19) alert('onkeypress event (ctrl-shift-S)')
} else if (document.layers && e.target.onchange){ // netscape
e.target.onchange()
} // end if
} // end function
//--></SCRIPT>
</HEAD>
<BODY><FORM>
Text item 1:
<INPUT type=text name=item1 length=20 maxlength=20
onChange='alert("onChange event (item 1)")'><BR>
Text item 2:
<INPUT type=text name=item2 length=20 maxlength=20'><BR>
</FORM>
</BODY></HTML>
"In Navigator 4, if you have both onChange= and any keyboard event handlers defined for the same text field tag, the onChange= event handlers are ignored. This is not true for Internet Explorer, where all events fire."
This doesn't seem to be true if the keyboard event handlers are defined at the document level. In this case, NN 4.x behave inconsistently. As reported above, NN 4.04 (Win) definitely ignores the onChange and NN 4.5 (Win) and 4.7 (Win) probably do. On the other hand, NN 4.6 (Win) and 4.6 (Mac) recognize the onChange. Consequently, it seems the only way to account for these inconsistencies is to either i) check whether the NN version number is one of the versions that ignores onChange when onkeypress/down/up is defined, or ii) make sure onkeypress/down/up always fires the onChange event handler if there is one. Either option means firing the onChange event handler every time a key is pressed in NN, not only when the element losses focus. I chose option ii), because the resulting code looks cleaner. Here's the code I have settled upon. Thank you for your help, I am happy to give you 100 points.
<HTML><HEAD><TITLE>key press test</TITLE>
<SCRIPT LANGUAGE="JavaScript1.2"><
/* set up the onKeyPress event handler
to intercept keyboard shortcuts */
if (document.layers) document.captureEvents(Eve
document.onkeypress=myKeyP
function myKeyPress(e){
if (document.layers && e.which){ // netscape
var m = e.modifiers
var alt = (m & Event.ALT_MASK)
var ctrl = (m & Event.CONTROL_MASK)
var shift = (m & Event.SHIFT_MASK)
var ascii = e.which
} else if (document.all){ // explorer
var alt = event.altKey
var ctrl = event.ctrlKey
var shift = event.shiftKey
var ascii = event.keyCode
} // end if
if (ctrl && shift && !alt) {
if (ascii==1) alert('onkeypress event (ctrl-shift-A)')
else if (ascii==4) alert('onkeypress event (ctrl-shift-D)')
else if (ascii==19) alert('onkeypress event (ctrl-shift-S)')
} else if (document.layers && e.target.onchange){ // netscape
e.target.onchange()
} // end if
} // end function
//--></SCRIPT>
</HEAD>
<BODY><FORM>
Text item 1:
<INPUT type=text name=item1 length=20 maxlength=20
onChange='alert("onChange event (item 1)")'><BR>
Text item 2:
<INPUT type=text name=item2 length=20 maxlength=20'><BR>
</FORM>
</BODY></HTML>
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Actually, I later changed the code again so that it won't try and capture keypress events in NN 4.x (Mac) as this seems to be where the inconsistencies are. To do this, I changed the line to:
if (document.layers && navigator.appVersion.index Of('Mac') >= 0) document.captureEvents(Eve nt.KEYPRES S)
and removed the line which calls e.target.onchange()
knightEknight was very helpful in helping me find this solution. Thank you.
if (document.layers && navigator.appVersion.index
and removed the line which calls e.target.onchange()
knightEknight was very helpful in helping me find this solution. Thank you.