Search code examples
javascriptregexkeyup

cursor go backward when triggered the regex in the replace, JavaScript


I have attached the link to fiddle to simulate the problem I got.

eg: I entered 12345 > point the cursor in the middle 12|345 > type "space" > 123|45

the cursor will go backward after I type the "space".

Question: How can I make it stay at the same place as it is before?

Here is the link to fiddle

document.querySelector("#removeSpace").onkeyup =  function()
{

    var start = this.selectionStart,
        end = this.selectionEnd;

    this.value = this.value.replace(/\s/g,"");
    this.setSelectionRange(start, end);
};

Solution

  • You need to check if the whitespace was matched or not, and set the selection with the offset equal to the match length. However, to avoid the whitespace input, you may use input event:

    $(function(){
      $('#removeSpace').bind('input', function(){
          var start = this.selectionStart,
                end = this.selectionEnd;
          var offset=0;
          this.value = this.value.replace(/\s+/g, function($0) {offset=$0.length; return "";});
          if (offset > 0)
        	   this.setSelectionRange(start-offset, end-offset);
      });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <input id="removeSpace" type="Text" />

    The replace(/\s+/g, function($0) {offset=$0.length; return "";}) part matches 1 or more whitespaces and passes them to the callback via $0 variable. Its length is assigned to offset variable and is subtracted from the current start and end cursor positions. return "" removes the match, all the whitespaces found.

    The same logic can be applied to fix your solution using keyup:

    document.querySelector("#removeSpace").onkeyup =  function()
    {
        
        var start = this.selectionStart,
            end = this.selectionEnd;
        var offset=0;
        this.value = this.value.replace(/\s+/g, function($0) {offset=$0.length; return "";});
        if (offset > 0)
        	this.setSelectionRange(start-offset, end-offset);
    };
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <input id="removeSpace" type="Text" />