macca1
macca1

Reputation: 9681

How do you replace many characters in a regex?

I am sanitizing an input field and manually getting and setting the caret position in the process. With some abstraction, here's the basic idea:

<input type="text" onkeyup"check(this)">

And javascript...

function check(element) {
  var charPosition = getCaretPosition(element);
  $(element).val( sanitize( $(element).val() ) );
  setCaretPosition(element, charPosition);
}

function sanitize(s) {
  return s.replace(/[^a-zA-Z0-9\s]/g, '');
}

This is working fine except when a character does actually get sanitized, my caret position is off by one. Basically I'd like a way to see if the sanitize function has actually replaced a character (and at what index) so then I can adjust the charPosition if necessary. Any ideas?

Upvotes: 2

Views: 351

Answers (3)

nicerobot
nicerobot

Reputation: 9235

I personally believe you should reconsider changing data as it's being typed. It's unusual and potentially confusing. A better technique might be to visually notify the user and possibly disallow blur or simply sanitize during onblur.

Alternatively, consider using onkeydown and return false if an incorrect key is typed which will short-circuit they key press entirely and avoid the need to replace text in the field.

<input type="text" onkeydown="return check(event)">

Though you'll have to handle the key-codes manually, including modifiers (shift, ctrl, ...):

<script>
  function check(e) {
    var w = e.which;
    var k = e.ctrlKey||e.altKey||e.metaKey;
    var m = k||e.shiftKey;
    return (!k && w>=65&&w<90)    // a-z allowing shift
           ||(!m && w>=48&&w<=57) // 0-9 no modifiers
           ||(w>=33&&w<=40)       // navigation keys
           ||w==8                 // Backspace
           ||w==9                 // Tab
           ||w==13                // Return
           ||w==32                // Space
           ||w==46                // Delete
           ;
  }
</script>

Upvotes: 2

Ender
Ender

Reputation: 27283

J-P's answer is the simplest for your particular problem.

In general, if you want to know the result of a replacement, the easiest way is to write your own replacement function:

var numReplaced = 0;

function sanitize(s) {
    return s.replace(/[^a-zA-Z0-9\s]/g, replacementFunc);
}
function replacementFunc() {
    numReplaced += arguments[0].length;
    return "";
}

Upvotes: 2

James
James

Reputation: 111920

Hmm, wouldn't it be simpler to compare the before and after values, and then compensate accordingly? -

charPosition -= beforeVal.length - afterVal.length; 

Upvotes: 3

Related Questions