HellaDev
HellaDev

Reputation: 408

Regex test to allow alphanumeric and hyphens keeps returning false

I am trying to disable input of certain values using jQuery and regex via typed or pasted input (anything that isn't alphanumeric or a hyphen should return false and e.preventDefault() is called to stop input). Every time I run this test it fails by returning false no matter what the input is and I can't figure out what I'm doing wrong here.

When I run the test in node console valid.test("hello-world") (or a variable equal to "hello-world") it comes back as true, and when I do valid.test("hello_world") it comes back as false, but when I do it using my code below it comes back as false every time no matter the input.

My code:

jQuery('#input').on('keydown paste', function(e) {
  var input = e.target.value;
  var isValid = /^[a-zA-Z\d-]+$/;
  var tester = isValid.test(input);

  if (tester === false) {
    e.preventDefault();
    console.log("Input allowed? " + tester);
  } else if (tester) {
      console.log("Input allowed? " + tester);
  }
});

In node console I get the following results:

"hello-world" = true
"hello_world" = false
"hello." > false
"goodness gracious" = false
"goodness-gracious" = true
"goodness123" = true
"goodness!!" = false

What am I missing here?

EDIT: I created a codepen to show the result I'm getting: https://codepen.io/anon/pen/JpdMgM

Upvotes: 0

Views: 232

Answers (3)

Oscar Cero Uno
Oscar Cero Uno

Reputation: 64

with both events you are getting the input value before it is present in the content.

For the "paste" event you could use something like

$("#textareaid").bind("paste", function(e){
    // access the clipboard using the api
    var pastedData = e.originalEvent.clipboardData.getData('text');
    alert(pastedData);
} );

see this for further reference.

With the "keydown", something like ctwheels's answer could work.

Upvotes: 0

ctwheels
ctwheels

Reputation: 22817

You need to separate the logic for keypress and paste as the e.preventDefault() is what's causing you issues. Using the same logic as seen in this answer, you can test against the pasted input.

let r = /^[a-zA-Z\d-]+$/

$('#input').bind({
  keydown: function(e) {
    return r.test(e.key)
  },
  paste: function(e) {
    if(!r.test(e.originalEvent.clipboardData.getData('text'))) {
      e.preventDefault()
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input id="input"/>

Upvotes: 2

Hassan Imam
Hassan Imam

Reputation: 22534

You need to escape the - inside the character class. So, your regex will be /^[a-zA-Z\d\-]+$/

var data = ["hello-world","hello_world","hello.","goodness gracious","goodness-gracious","goodness123","goodness!!"],
    result = data.map(word => /^[a-zA-Z\d\-]+$/.test(word));
console.log(result);

Upvotes: 2

Related Questions