1

I'm currently trying to restrict users so they can only input letters or numbers in a textbox and if anything other than letters or numbers is typed in I want to remove the value.

So my regex looks like ^[a-zA-Z0-9]+$ and the whole jQuery functions looks as follows:

 $("#myInputField").keyup(function (e) {
    if (/^[a-zA-Z0-9]+$/.test(this.value)) {
        this.value = this.value.replace(/^[a-zA-Z0-9]+$/, '');
    }
});

but this seems to be doing the opposite. So if I type a number or letter in then it's replaced and it's allowing all the other characters. Can someone tell me where I'm going wrong please.

freedomn-m
  • 27,664
  • 8
  • 35
  • 57
Izzy
  • 6,740
  • 7
  • 40
  • 84

4 Answers4

3

Your regex is currently this:

^[a-zA-Z0-9]+$

Breaking that down, that matches the start of the string, then as many as possible alphanumeric characters, then the end of the string.

What you actually want to match is any non-alphanumeric characters, and you don't care where the start or end of the string is.

As such, the regex as suggested in the comments is correct:

[^a-zA-Z0-9]

This matches any non-alphanumeric characters.

You must change this in both the test and replacement lines. Furthermore, somebody can right-click and paste into the textbox, so this isn't foolproof (someone can also disable JavaScript).

Scott Stevens
  • 2,546
  • 1
  • 20
  • 29
  • Thanks for this, the paste issue can I not just do `$('#validate-serial').bind("paste", function (e) { e.preventDefault(); });` after the if condition? – Izzy Feb 08 '17 at 14:04
  • 1
    You can try to prevent a Paste, but I suggest you *don't*. Copy+Paste is integral to computers, just like the Back button (I've seen sites that break the Back button). You could check the input onChange or onBlur, but again *the user can disable JavaScript*, so you **must** check it server-side. – Scott Stevens Feb 08 '17 at 14:10
  • 1
    On the server side the input is checked to ensure it's always numbers/letters – Izzy Feb 08 '17 at 14:12
  • 1
    If you're checking server-side, then I wouldn't worry too much about client-side validation. Make it good enough to stop accidental errors, but anything else is extra effort. Your keyup function is probably good enough, I would also check `blur` for when the textbox is unfocused (this catches pastes etc.). – Scott Stevens Feb 08 '17 at 14:16
  • Thanks for the further information I really appreciate it – Izzy Feb 08 '17 at 14:18
0

If you change your regex in both locations to [^a-zA-Z0-9] it resolves the issue. Basically your regex is almost always true and even when it is false it acts true because something else negates it to be true. I have added an example with example code. I also use the console to prove it.

 $("#myInputField").keyup(function (e) {
   console.log(/[^a-zA-Z0-9]+$/.test(this.value));
    if (/[^a-zA-Z0-9]+$/.test(this.value)) {
        this.value = this.value.replace(/[^a-zA-Z0-9]+$/, '');
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="myInputField"/>

** At the time of this posting there is an answer. They have better wording. Mine just provides an example that I worked on.

Cayce K
  • 2,288
  • 1
  • 22
  • 35
0

As mentioned before, use /[^a-zA-Z0-9]+$/ to find any string that does not conform to only letters or numbers.

Note that the String.replace function returns the string with the replacement. The string called on String.replace is not adjusted.

$("#myInputField").keyup(function (e) {
   if (/[^a-zA-Z0-9]+$/.test(this.value)) {
       this.value = this.value.replace(/[^a-zA-Z0-9]/g, '');
   }
});

@Cayce K Thanks for pointing out that the other symbols should be removed :)

jervtub
  • 347
  • 1
  • 10
0

You can use the following regex at both places (in your condition as well as in replace statement)

[^\d\w]

This is negated set, which match any character which is not in set(i.e. anything other than alpha numeric).

Vijay Mishra
  • 350
  • 2
  • 14