0

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

HellaDev
  • 408
  • 2
  • 8
  • 24
  • 1
    The `e.preventDefault()` is causing the problem. https://codepen.io/anon/pen/Jpdpvm –  Jan 31 '18 at 17:28
  • 1
    You can see here https://codepen.io/anon/pen/bLdLQB the input is empty. –  Jan 31 '18 at 17:35

3 Answers3

2

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);
Hassan Imam
  • 21,956
  • 5
  • 41
  • 51
  • 1
    This seems to be working nicely in node console but when I run it through my jquery it no longer works. I updated my codepen in my main post to use your regex example but it still seems to be returning false every time once it goes through my jquery. – HellaDev Jan 31 '18 at 17:29
  • 1
    Comment e.preventDefault and try again. – Hassan Imam Jan 31 '18 at 17:39
  • 2
    The hyphen has nothing to do with this not working. The hyphen is interpreted literally. Also, this doesn't solve the issue since the issue isn't the regex but instead the events being combined with `e.preventDefault` – ctwheels Jan 31 '18 at 17:47
2

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"/>
ctwheels
  • 21,901
  • 9
  • 42
  • 77
  • Thank you ctwheels, that was the solution. I never suspected the preventDefault() as the culprit here! – HellaDev Jan 31 '18 at 17:58
0

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.

  • I was just making changes to my answer. It's funny you had the exact same idea as me! – ctwheels Jan 31 '18 at 17:45
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Jay Blanchard Feb 01 '18 at 14:30