-1

I'm trying to prevent user from entering anything except numbers and letters, but my code doesn't even allow them itself. What could be the reason? Here's my code snippet:

$(document).ready(function(){
    $("#txtuname").keypress(function(e){ 
        var validExp = /^[0-9a-z]+$/gi;
        var val = $(this).val();
        if(val.match(validExp))
        {
            $("#errmsg").html("");
            return true;
        }
        else
        {
            $("#errmsg").html("Number and letters Only"); 
            return false;
        }
    });
});


<input type="text" name="txtuname" id="txtuname" />
<span id="errmsg"></span>

JSFiddle

Sachin
  • 1,646
  • 3
  • 22
  • 59

6 Answers6

1

You can use keyup not keypress

$(document).ready(function(){
 $("#txtuname").keyup(function(e){ 
  var validExp = /^[0-9a-z]+$/gi;
  var val = $(this).val();
  if(val.match(validExp))
  {
   $("#errmsg").html("");
   return true;
  }
  else
  {
   $("#errmsg").html("Number and letters Only"); 
   return false;
  }
 });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 

<input type="text" name="txtuname" id="txtuname" />
<span id="errmsg"></span>
Ying Yi
  • 784
  • 4
  • 16
  • The forbidden characters still show up in the input box despite the warning. So you will want to use `keydown`, instead of `keyup` – davidhu Sep 10 '16 at 03:30
  • Your solution is buggy as well whether you do use keyup or keydown; doesn't really matter. – Sachin Sep 10 '16 at 04:32
1

You can substitute input event for keypress event; adjust RegExp to /[0-9a-z]/i, use .split() with parameter "", Array.prototype.every(), RegExp.prototype.test() to check each character of input value at if condition; if each character is a digit or a letter condition is true, else false replace invalid characters of value using .replace() with RegExp /[^0-9a-z]/ig

$(document).ready(function() {
      var validExp = /[0-9a-z]/i;
      $("#txtuname").on("input", function(e) {
        var val = this.value;
        var check = val.split("").every(function(value) {
          return validExp.test(value)
        });
        if (check) {
          $("#errmsg").html("");
          return check;
        } else {
          this.value = val.replace(/[^0-9a-z]/ig, "");
          $("#errmsg").html("Number and letters Only");
          return false;
        }
      });
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<input type="text" name="txtuname" id="txtuname" />
<span id="errmsg"></span>
guest271314
  • 1
  • 15
  • 104
  • 177
  • 1
    You may want to highlight actual answer (`keyup`) as well as mention `paste` as suggested in http://stackoverflow.com/a/35592412/477420 – Alexei Levenkov Sep 10 '16 at 03:35
  • 1
    @AlexeiLevenkov See updated post. `input` event handles paste of characters at `` element – guest271314 Sep 10 '16 at 03:39
  • @AlexeiLevenkov Re-read Question. Must have missed that characters should be removed from input. Added call to `.replace()` to replace characters which are not a-z0-9 – guest271314 Sep 10 '16 at 03:57
1
$(document).ready(function () {

        $("#txtuname").keypress(function (e) {

            var validExp = /^[0-9a-z]+$/gi;

            if (validExp.test(e.key)) {
                $("#errmsg").html("");
                return true;
            }
            else {
                $("#errmsg").html("Number and letters Only");

                return false;
            }
        });
    });
0

This is because keypress events are fired before the new character is added to the value of the element (so the first keypress event is fired before the first character is added, while the value is still empty). You should use keyup instead, which is fired after the character has been added reference.

Here is the code

html

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 

<input type="text" name="txtuname" id="txtuname" />
<span id="errmsg"></span>

js

$(document).ready(function(){
    $("#txtuname").keyup(function(e){ 
        var validExp = /^[0-9a-z]+$/gi;
        var val = $(this).val();
        if(val.match(validExp))
        {
            $("#errmsg").html("");
            return true;
        }
        else
        {
            $("#errmsg").html("Number and letters Only"); 
            return false;
        }
    });
});
Community
  • 1
  • 1
Dhaval
  • 389
  • 1
  • 10
0

You issue is you are not getting the value of the key that is being pressed. If you set the val variable like so, it will work as expected.

var val = String.fromCharCode(e.keyCode)

This gets the ASCII code of the key pressed, and then converting to the letter or number it represents. Then you can check against your regex.

davidhu
  • 9,523
  • 6
  • 32
  • 53
0

$(document).ready(function(){
    $("#txtuname").keyup(function(e){ 
        var validExp = /^[0-9a-z]+$/gi;
        var val = $(this).val();
        if(validExp.test(val))
        {
            $("#errmsg").html("");
            return true;
        }
        else
        {
            // fix the value of input field here 
            $(this).val("");
            $("#errmsg").html("Number and letters Only"); 
            return false;
        }
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="txtuname" id="txtuname" />
<span id="errmsg"></span>
  1. You need to use keyup so that the character is "added" already to the value if you're going to use this given technique.

  2. Since String.prototype.match actually returns an array of the match, it won't work in the way you want it to. Not to mention that it is much more expensive than RegEx.prototype.test.

Bonus

You can use the technique of finding carret position in an input field shown in Get cursor position (in characters) within a text Input field

To actually fix the input field on keyup.

Community
  • 1
  • 1
Ahmed Masud
  • 21,655
  • 3
  • 33
  • 58