Home > Net >  Max length to an input
Max length to an input

Time:11-21

My mission is: SMS Code input separately and inputs have to be just one number.

My inputs jump from one line to the next, and while pressing backspace deletes them backwards, it also allows for multiple number entries, which I don't want.

I have an SMS code section, like this: enter image description here

and my HTML code like this:

<form >
  <input  type="number" placeholder="·" tabindex="1" name="pincode-1" id="txt1" max="1" maxlength="1" onkeydown="move(event, '', 'txt1', 'txt2')" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="2" name="pincode-1" id="txt2" max="1" maxlength="1" onkeydown="move(event, 'txt1', 'txt2', 'txt3')" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="3" name="pincode-1" id="txt3" max="1" maxlength="1" onkeydown="move(event, 'txt2', 'txt3', 'txt4')" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="4" name="pincode-1" id="txt4" max="1" maxlength="1" onkeydown="move(event, 'txt3', 'txt4', 'txt5')" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="5" name="pincode-1" id="txt5" max="1" maxlength="1" onkeydown="move(event, 'txt4', 'txt5', 'txt6')" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="6" name="pincode-1" id="txt6" max="1" maxlength="1" onkeydown="move(event, 'txt5', 'txt6', '')" autocomplete="off">
</form>

and my function like this :

function move(e, p, c, n) {
    var length = document.getElementById(c).value.length;
    var maxlength = document.getElementById(c).getAttribute("maxlength");

    if (length == maxlength) {
        if (n !== "") {
            document.getElementById(n).focus();
        }
    }
    if (e.key === "Backspace") {
        if (p !== "") {
            document.getElementById(p).focus();
        }
    }
}

CodePudding user response:

I hope it will help

function move(e, p, c, n) {
    var length = document.getElementById(c).value.length;
    var maxlength = document.getElementById(c).getAttribute("maxlength");

    if (length == maxlength) {
        if (n !== "") {
            document.getElementById(n).focus();
        }
    }
    if (e.key === "Backspace") {
        if (p !== "") {
            document.getElementById(p).focus();
        }
    }
}
<form >
  <input  type="number" placeholder="·" tabindex="1" name="pincode-1" id="txt1" max="1" maxlength="1" onkeydown="move(event, '', 'txt1', 'txt2')" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="2" name="pincode-1" id="txt2" max="1" maxlength="1" onkeydown="move(event, 'txt1', 'txt2', 'txt3')" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="3" name="pincode-1" id="txt3" max="1" maxlength="1" onkeydown="move(event, 'txt2', 'txt3', 'txt4')" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="4" name="pincode-1" id="txt4" max="1" maxlength="1" onkeydown="move(event, 'txt3', 'txt4', 'txt5')" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="5" name="pincode-1" id="txt5" max="1" maxlength="1" onkeydown="move(event, 'txt4', 'txt5', 'txt6')" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="6" name="pincode-1" id="txt6" min="1" max="1" maxlength="1" onkeydown="move(event, 'txt4', 'txt5', 'txt6')" autocomplete="off">
</form>

CodePudding user response:

Your code is not working for a few reasons:

  • As you've seen, maxlength does not work for input type='number';

  • Even if you hard-code a limit of 1 in your JS, eg var maxlength = 1, it won't work because you are finding the number of characters in the current input, but then focussing the target input. You are using keydown, which means the code runs before the character appears - the focus is shifted and the character is added to the target, regardless of how many characters are there already;

  • Your tests are not mutually exclusive - they can both be true for a single keypress. The result of that is that a backspace will delete the previous input value, not the the current one, that's not correct;

  • There's nothing to handle keypresses in the last input when it already has a value;

So you really need a more complex set of rules to correctly handle the different cases.

As you can imagine, you're not the first person to try to build somethng like this, and a little bit of searching turns up many answers already. Here's one, which actually asks a different but related question. The accepted answer solves that different question asked there and is not useful here, but another of the answers solves not only that different question but includes code which you can use to solve your question too.

That answer still has a few issues, and some incompatibilities with your requirements:

  • backspace in the last input deletes the last 2 input values;

  • behaviour of backspace in the last input should depend on whether or not there is a character in the last input;

  • it uses input type="text", and accepts text input;

  • I found some of the logic confusing, so I rewrote and simplified it;

Note I've made the code more verbose than really necessary to make each case clear, you could simplify this by removing some of that.

Credit to this answer for much of this code:

function handleInput() {
    // Find all inputs
    const inputs = document.querySelectorAll('.pincode');

    // Add an event handler for each 
    for (let i = 0; i < inputs.length; i  ) {
        inputs[i].addEventListener('keydown', function(event) {
            if (event.key === "Backspace") {
                if (i === inputs.length - 1) {
                    // If we're in the last input ...
                    if (inputs[i].value === '') {
                        // ... and it is empty, shift back to previous input, 
                        // where the backspace will actually happen
                        inputs[i - 1].focus();
                    } else {
                        // ... and it has a value, do nothing, and let the 
                        // backspace happen
                        return;
                    }
                    
                } else if (i > 0) {
                  // In any other input except the first, move to previous
                  // input, and let the backspace happen
                  inputs[i - 1].focus();
              }
              
            } else {
                // Set the current input value to the key that was typed
                inputs[i].value = event.key;

                // If we're not in the last input, move focus forward
                if (i !== inputs.length - 1) {
                    inputs[i   1].focus();
                }

                // We've already used the typed value, don't do it again
                event.preventDefault();
            }
        });
    }
}

handleInput();
<form >
  <input  type="number" placeholder="·" tabindex="1" name="pincode-1" id="txt1" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="2" name="pincode-1" id="txt2" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="3" name="pincode-1" id="txt3" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="4" name="pincode-1" id="txt4" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="5" name="pincode-1" id="txt5" autocomplete="off">
  <input  type="number" placeholder="·" tabindex="6" name="pincode-1" id="txt6" autocomplete="off">
</form>

  • Related