Limit text input to numbers only

2019-09-21 02:06发布

问题:

I want to implement a text input with the following implementations:

  • Only allow numbers
  • Limit numbers from 0 - 255
  • If an 'illegal' character was entered (non numbers, or over or under 255), the input should get disabled, wait a second, then delete the invalid char, and get back to focus.

I got all that implemented thanks to this answer. There's an issue though. If you enter 35 (that's 'legal'), then move the cursor between 3 and 5, then enter 1, which comes out to 315. That becomes 'illegal' because it's more than 255. So the 5 gets deleted. I don't want the 5 to get removed, I want the 1 to get deleted because that was the last one entered.

But if you enter 31, then 5, 5 should get removed. Basically, I want the last number entered to get deleted when an illegal amount gets inserted.

Also, I want the cursor to go to the position of the last removed character, whether it's a number or letter.

Here's the code:

JSFiddle

function disableInput(el) {
  var checks = [/\D/g.test(el.value), el.value > 255];
  if (checks.some(Boolean)) {
    $(el).prop("disabled", true)
      .queue("disabled", function() {
        $(this).prop("disabled", false)
      });
    setTimeout(function() {
      if (checks[0]) {
        el.value = el.value.replace(/\D/g, '');
      }
      if (checks[1]) {
        el.value = el.value.slice(0, 2);
      };
      $(el).dequeue("disabled").val(el.value).focus()
    }, 1000)
  }

}


$('input[name="number"]').keyup(function(e) {
  disableInput(this)
  $(this).focus();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input name="number" />

回答1:

You can use selectionStart and selectionEnd to see where the cursor is in the input and then use those values to remove the correct character.

Fiddle: http://jsfiddle.net/o4bz0wr7/3/

function disableInput(el) {
  var checks = [/\D/g.test(el.value), el.value > 255];
  if (checks.some(Boolean)) {
    $(el).prop("disabled", true)
      .queue("disabled", function() {
        $(this).prop("disabled", false)
      });
    setTimeout(function() {
      if (checks[0] || checks[1]) {
        el.value = el.value.slice(0, el.selectionStart - 1) + el.value.slice(el.selectionEnd);
      }
      $(el).dequeue("disabled").val(el.value).focus()
    }, 1000)
  }

}


$('input[name="number"]').keyup(function(e) {
  disableInput(this)
  $(this).focus();
});

EDIT: You can set the cursor position using setSelectionRange.

Fiddle: http://jsfiddle.net/o4bz0wr7/7/

function disableInput(el) {
  var checks = [/\D/g.test(el.value), el.value > 255];
  if (checks.some(Boolean)) {
    $(el).prop("disabled", true)
      .queue("disabled", function() {
        $(this).prop("disabled", false)
      });
    setTimeout(function() {
      var start = el.selectionStart - 1;
      if (checks[0] || checks[1]) {
        el.value = el.value.slice(0, start) + el.value.slice(el.selectionEnd);
      }
      $(el).dequeue("disabled").val(el.value).focus();
      el.setSelectionRange(start, start);
    }, 1000)
  }

}


回答2:

This should work fine with you, however if there is still any problem add it in comment.

Check it out in action here

var which = null;

function disableInput(el, $which) {
  console.log(el.value);
  var checks = [/\D/g.test(el.value), el.value > 255];
  if (checks.some(Boolean)) {
    $(el).prop("disabled", true)
      .queue("disabled", function() {
        $(this).prop("disabled", false)
      });
    setTimeout(function() {
     console.log(String.fromCharCode($which));
       el.value = el.value.replace($which, '');
       // el.value = el.value.slice(0,el.value.length - 1);


      $(el).dequeue("disabled").val(el.value).focus()
    }, 1000)
  }

}


$('input[name="number"]').keypress(function(e) {
    which = String.fromCharCode(e.which);
    $(this).focus();
}).keyup(function(){
    disableInput(this, which);

})