Link to home
Start Free TrialLog in
Avatar of gbateson
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(Event.KEYPRESS)
document.onkeypress=myKeyPress

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>
Avatar of knightEknight
knightEknight
Flag of United States of America image

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.
Avatar of gbateson
gbateson

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).
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(Event.KEYDOWN)
document.onkeydown=myKeyEventHandler

} else if (document.all) { // explorer
document.onkeypress=myKeyEventHandler
} // 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>
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(Event.KEYPRESS)
document.onkeypress=myKeyPress

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
Avatar of knightEknight
knightEknight
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.indexOf('Mac') >= 0) document.captureEvents(Event.KEYPRESS)
and removed the line which calls e.target.onchange()

knightEknight was very helpful in helping me find this solution. Thank you.