javascript event handler assignment funky functioning.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Plater
    Recognized Expert Expert
    • Apr 2007
    • 7872

    javascript event handler assignment funky functioning.

    Well, I'm stuck asking you all, because I cannot find a piece of code that works in multiple browsers.

    I have the following code that works in google chrome and ie:
    [code=javascript]
    //Add a keypress watcher to disallow spaces, slashes, alphabetic characters, etc
    document.getEle mentById("tbSit eCodeOrSerialNu mber").onkeypre ss=function(){r eturn OnlyNumbers(eve nt);};
    [/code]

    FF complains that the function is not defined. Looking up I see that FF likes
    the function definition to take a parameter in for this setup, aka: function(e)
    [code=javascript]
    document.getEle mentById("tbSit eCodeOrSerialNu mber").onkeypre ss=function(e){ return OnlyNumbers(eve nt);};
    [/code]
    But then it complains that "event" is not valid. Ok I think, how about using function (event)
    [code=javascript]
    document.getEle mentById("tbSit eCodeOrSerialNu mber").onkeypre ss=function(eve nt){return OnlyNumbers(eve nt);};
    [/code]
    Hurray it works in FF and google chrome, but then IE eats it.
    EDIT: No, it blocks EVERY keypress (backspace, ctrl+v, etc) in FF, but googlechrome is fine.
    IE complains inside the OnlyNumbers function that a null is being passed in as the parameter.

    Does anyone have a solid piece of code for attaching the onkeypress handler at runtime like that?
  • acoder
    Recognized Expert MVP
    • Nov 2006
    • 16032

    #2
    [code=javascript]document.getEle mentById("tbSit eCodeOrSerialNu mber").onkeypre ss=OnlyNumbers;[/code]
    is all you need. The event will be passed for you in Firefox/Opera, etc.

    Comment

    • Plater
      Recognized Expert Expert
      • Apr 2007
      • 7872

      #3
      .onkeypress only allows parameterless functions, but I need to pass in the event object as well, which was why I was doing the function wrapping.

      Comment

      • acoder
        Recognized Expert MVP
        • Nov 2006
        • 16032

        #4
        The event will be passed without specifying it:
        [code=javascript]function OnlyNumbers(e) {
        e = e || window.event;
        ...[/code]

        Comment

        • Plater
          Recognized Expert Expert
          • Apr 2007
          • 7872

          #5
          Ok I see what you did there. But it still doesn't work with IE. It doesn't get the value passed in, still says its null.

          I am thinking of taking it a different way anyway, since it seems it blocks all other keyboard keys as well in FF (no backspace, no delete, not ctrl+v, etc)
          But I am not sure what way to go.

          Comment

          • acoder
            Recognized Expert MVP
            • Nov 2006
            • 16032

            #6
            It should work in IE because window.event is global.

            You could try using parseInt/isNaN, but blocking keys onkeypress is more useful when specifying what to block, not what to allow.

            Comment

            • Plater
              Recognized Expert Expert
              • Apr 2007
              • 7872

              #7
              window.event is global, but is never defined (according to alert() boxes)

              I am now using this:
              [code=javascript]
              //Add a keypress watcher to disallow spaces, slashes, alphabetic characters, etc
              if(window.event ) // IE
              {
              document.getEle mentById("tbSit eCodeOrSerialNu mber").onkeypre ss=function(){r eturn OnlyNumbers(eve nt);};
              }
              else // ???Netscape/Firefox/Opera
              {
              document.getEle mentById("tbSit eCodeOrSerialNu mber").onkeypre ss=OnlyNumbers;
              }
              [/code]

              And with some work arounds for FF, I have it allowing arrow keys, delete key, and backspace, as well as numbers.
              [code=javascript]
              function OnlyNumbers(e)
              {
              var keynum;
              var keychar;
              var numcheck1;

              if(window.event ) // IE
              {
              keynum = e.keyCode;
              }
              else if(e.which) // Netscape/Firefox/Opera
              {
              keynum = e.which;
              }
              if (keynum==null)
              {//FF has the arrow keys and the delete key show up as null/undefined
              return true;
              }
              keychar = String.fromChar Code(keynum);
              numcheck1 = /(\d|\x08)/;
              var bv1= numcheck1.test( keychar);
              return (bv1 );
              }
              [/code]

              If there is a better way to do this, I am all ears. googlechrome and IE both had no problems allowing arrow keys/delete/backspace/home/end/numbers to be typed with only the /\d/ check.

              Comment

              • acoder
                Recognized Expert MVP
                • Nov 2006
                • 16032

                #8
                window.event is never defined because you're not using it. You're using "e". To solve it, add this line to the beginning of the function:
                [code=javascript]e = e || window.event;[/code]

                As for the second problem, that's a bit more complex. Either allow only allowable characters, or block all prohibited characters, or get the target of the event and check if the whole value is a number or not.

                Comment

                • Plater
                  Recognized Expert Expert
                  • Apr 2007
                  • 7872

                  #9
                  Well the problem I had was that FF treats special keys as the same keycode. Such as ctrl+c is the same keycode(or e.which) as "c" and "C".
                  So if I disallow alpha characters, which i need to do, then it also blocks those. Unless I check for special keys also being pressed.

                  Here is what I currently am going with.
                  [code=javascript]
                  function OnlyNumbers(e)
                  {
                  var keynum;
                  var keychar;
                  var numcheck1;

                  if(window.event ) // IE
                  {
                  keynum = e.keyCode;
                  }
                  else if(e.which) // Netscape/Firefox/Opera
                  {
                  keynum = e.which;
                  }
                  if ((keynum==null) || (e.altKey) || (e.ctrlKey))
                  {
                  return true;
                  }

                  keychar = String.fromChar Code(keynum);
                  numcheck1 = /(\d|\x08)/;
                  var bv1= numcheck1.test( keychar);
                  return bv1;
                  }
                  [/code]

                  That seems to be doing an ok-enough job. It doesn't stop people from pasting in text that is not numbers, but I can clean that up at a later point.
                  All I wanted was that only numbers could be displayed in the textbox. It got complicated really quick haha.

                  Comment

                  • mrhoo
                    Contributor
                    • Jun 2006
                    • 428

                    #10
                    firefox and IE return control character codes from keyup and keydown.

                    IE returns keyCodes from all key events, firefox returns keyCode for keyup and down, and charCode from keypress events.

                    The easiest way to validate keyboard input while its being typed is to look at the element's value onkeypress and replace anything that doesn't fit:
                    (Might as well use the same method to check pasted input onchange):

                    element.onkeypr ess=element.onc hange=function( ){
                    this.value=this .value.replace(/\D+/,'')
                    }

                    Comment

                    • acoder
                      Recognized Expert MVP
                      • Nov 2006
                      • 16032

                      #11
                      Of course, \D matches non-integers. I knew I was missing something simple. Thanks, mrhoo.

                      Comment

                      • Plater
                        Recognized Expert Expert
                        • Apr 2007
                        • 7872

                        #12
                        Originally posted by mrhoo
                        element.onkeypr ess=element.onc hange=function( ){
                        this.value=this .value.replace(/\D+/,'')
                        }
                        The idea is nice, and it *does* technically work I suppose, except that until you press a 2nd key, or leave, there is still any single non valid character that was typed in the box.

                        Comment

                        • mrhoo
                          Contributor
                          • Jun 2006
                          • 428

                          #13
                          this version will prevent the input from showing the nondigits at all-
                          except in opera, which needs the onkeyup.


                          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
                          <html lang="en">

                          <head>
                          <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                          <title>key events</title>
                          <!--
                          This code is for testing purposes only
                          -->
                          <style type="text/css">
                          body{font-size:125%;margi n:1ex 1em}
                          form *{font-size:1em; font-weight:bold}
                          </style>

                          <script type="text/javascript">
                          Code:
                          onload=function(){
                          	var who=document.getElementById('digitstext');
                          	who.onkeydown=function(e){
                          		e=window.event || e;
                          		var c=e.keyCode || 0;
                          		if(c<48 || c>57)return false;
                          		return c;
                          	}
                          	who.onchange= function(){
                          		this.value=this.value.replace(/\D+/,'');
                          	}
                          	if(window.opera){
                          		who.onkeyup=who.onchange;
                          	}	
                          	who.focus();
                          }
                          </script>
                          </head>

                          <body style="">
                          <div >

                          <form action='' onsubmit="retur n false" style="font-size:150%;width :100%">
                          <fieldset>

                          <legend>Key Events</legend>
                          <p>
                          <label>Only digits accepted<input id="digitstext " type="text" size="10" maxLength="10" value=""></label>
                          </p>
                          </fieldset>
                          </form>

                          </div>
                          </body>
                          </html>

                          I would just use the replace value onkeyup and onchange, and let the bad data show for an instant-

                          Code:
                          onload=function(){
                          	var who=document.getElementById('digitstext');
                          	who.onkeyup= who.onchange= function(){
                          		this.value=this.value.replace(/\D+/,'');
                          	}
                          	who.focus();
                          }

                          Comment

                          Working...