-2

I am trying to only allow ASCII characters for my input fields. The test Fiddle seems to not know what to do with a TAB character:

https://jsfiddle.net/jp2code/5enmojb2/77/

Yes, 77 iterations, so far. Feel free to look at all I have tried.

$().ready(function() {
  $('input').bind('paste', function(e) {
    var text = $(this).val();
    var txt2 = text.replace(/[^\x00-\x19]/g, ' ');
    $(this).val(txt2);
  });
});

ASCII Chart from Wikipedia used to determine that I do not want ASCII characters 0x00 to 0x19, hence the regular expression used above.

This last version has no errors, but it copies what is in the input box above into the input box below, including the TAB that I want to be replaced with a blank space.

How do I replace any occcurance of ASCII characters 0x00 to 0x19 with a single space?

Liam
  • 25,247
  • 27
  • 110
  • 174
jp2code
  • 25,449
  • 37
  • 148
  • 261
  • If you do `console.log(text)` you'll notice that the event triggers *before* the paste contents have been applied to the field. See [jQuery bind to Paste Event, how to get the content of the paste](https://stackoverflow.com/questions/11605415/jquery-bind-to-paste-event-how-to-get-the-content-of-the-paste) – Guy Incognito Jan 12 '21 at 16:52
  • @GuyIncognito - I can already get the contents from the paste. I just can't replace special characters like the TAB – jp2code Jan 12 '21 at 16:53
  • 1
    Just FYI `bind()` is very outdated and has been deprecated. Convert it to `on()` instead – Rory McCrossan Jan 12 '21 at 16:53
  • Well you're not getting the contents in the jsfiddle version you've shown. – Guy Incognito Jan 12 '21 at 16:54
  • @GuyIncognito, when I paste into the fiddle show, I get exactly what is in the text shown above it – jp2code Jan 12 '21 at 16:55
  • Yes. Initially `$(this).val()` is empty, you apply the regex to an empty string which does nothing, and then set the field value to an empty string in the last line. Then the event ends and the browser completes the paste operation by applying the clipboard contents to the field. – Guy Incognito Jan 12 '21 at 16:57
  • @GuyIncognito, the javascript is for the `paste` event. Copy the text from the input field in the top and paste it into the blank field on the bottom. When the `paste` happens, the javascript should trigger. – jp2code Jan 12 '21 at 17:00
  • Christ on a bike. Yes, it *does* trigger, *but it doesn't do anything*. The script triggers *before* the field gets the new value so you can't use `$(this).val()` to get the paste contents. If you don't believe me try https://jsfiddle.net/robs7g4y/ and you'll see that `$(this).val()` is *not* the text that you're trying to paste into the field, it's whatever value the field had *before* you try to paste something to it. – Guy Incognito Jan 12 '21 at 17:02
  • @GuyIncognito, lol - sorry. I'm not good at javascript. I think I understand what you are saying now. Is there a way to fix it? I've tried other versions using a timeout (see https://jsfiddle.net/jp2code/5enmojb2/55/), but it still didn't work – jp2code Jan 12 '21 at 17:14
  • 1
    Read the duplicate linked in the first comment: replace `$(this).val()` with `e.originalEvent.clipboardData.getData('text')`, fix the regex so that it replaces that range instead of everything else and prevent the default paste operation. https://jsfiddle.net/ydj6xzb2/ – Guy Incognito Jan 12 '21 at 17:17

1 Answers1

0

Rather than replacing specific characters, I would argue what you really want is to replace everything except valid characters:

const ensureAscii = (x) => x.replace(/[^\x20-\x7e]/g, ' ');

$().ready(function() {
  $('input').bind('paste', function(e) {
    $(this).val(ensureAscii($(this).val()));
  });
});

Example:

ensureAscii('abc\t\n123')
"abc  123"

Update: Your fiddle has a different problem. The text variable is empty! You need to get the pasted text from the clipboard:

const ensureAscii = (x) => x.replace(/[^\x20-\x7e]/g, ' ');

$().ready(function() {
  $('input').bind('paste', function(e) {
    const text = event.clipboardData.getData('text');
    $(this).val(ensureAscii(text));
  });
});
Christian Fritz
  • 18,961
  • 3
  • 42
  • 63
  • 2
    +1 I do not downvote! But this doesn't replace the TAB when I test it. See https://jsfiddle.net/jp2code/5enmojb2/82/ – jp2code Jan 12 '21 at 16:52
  • hm, well it does in the browser console and in node.js. Example added. – Christian Fritz Jan 12 '21 at 17:07
  • Have you verified that your jsfiddle works otherwise? I mean, does it replace anything? or does this event handler on 'paste' simple not work? – Christian Fritz Jan 12 '21 at 17:11
  • I haven't verified anything. I have a larger project that this needs to go into. I am trying to use the jsFiddle to get the code working before I paste it into the project. – jp2code Jan 12 '21 at 17:16
  • 1
    There was another problem. The `text` variable was empty -- the way you were trying to get the value didn't work (at least in chrome). I've fixed that. See updated answer. – Christian Fritz Jan 12 '21 at 18:45
  • Interesting. Pasting in `a b` comes back as `a ba b`. It replaced the TAB, but did not clear the text field. See https://jsfiddle.net/jp2code/5enmojb2/97/ – jp2code Jan 12 '21 at 21:14