Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The 'input' element's cursor position is reset when replacing the value on keyup

I need my regex to accept arrow keys, letters, and numbers. I got the letters and numbers, but im stuck on arrow keys. I have this so far.

var patt = /[^a-zA-Z0-9]+/g;
var helper;
$('#name').keyup(function(e){
    helper = $('#name').val();
    helper = helper.replace(patt,' ');
    $('#name').val(helper);
});

Thanks for any help.

like image 881
Zapp Avatar asked Feb 15 '16 02:02

Zapp


2 Answers

The problem is that you're replacing the element's entire value when the keyup event is fired. In doing so, the cursor will always be reset to the end.

To resolve this, you can capture the cursor's initial position by accessing the selectionStart property of the element. Then after replacing the value, you can simply set it back to where it initially was:

Here is an example in plain JS demonstrating this:

document.getElementById('name').addEventListener('input', function() {
  var position = this.selectionStart;
  
  this.value = this.value.replace(/[^a-zA-Z0-9]+/g, '');
  this.selectionEnd = position;
});
<input id="name" type="text" />

Likewise, the jQuery-version would be the same. I also changed the keyup event to an input event so that the event is only fired when the value is actually changed.

$('#name').on('input', function(e) {
  var position = this.selectionStart;

  this.value = this.value.replace(/[^a-zA-Z0-9]+/g, '');
  this.selectionEnd = position;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="name" type="text" />

As an alternative, you could also just listen to the change event and then replace the value; however, this wouldn't update the value while typing.

like image 111
Josh Crozier Avatar answered Oct 12 '22 19:10

Josh Crozier


When you press the arrow key you're changing the value of the input, so the cursor will lose its place. This is unrelated to the regex you're using.

You should not modify user input while they're typing. Instead do it on the .change() jQuery callback listener, not .keyup()

like image 29
Andy Ray Avatar answered Oct 12 '22 17:10

Andy Ray