8

There's a inputs with six entries. If the desired digits is directly pasted into the inputs..

123456

How do I distribute the numbers to the other boxes when they are pasted into the first box?

on JSfiddle

var $inp = $(".passInput");

$inp.on({
 input: function(ev) {
  if(this.value) {
    $inp.eq($inp.index(this) + 1).focus();
  }
 },
 keydown: function(ev) {
  var i = $inp.index(this);
  if(ev.which===8 && !this.value && i) {
    $inp.eq(i - 1).focus();
  }
 }
});
.passInput {text-align: center;}
<form action="" role="form" method="post" id="passForm">
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" required pattern="\d{1}" autofocus>
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" required pattern="\d{1}">
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" required pattern="\d{1}">
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" required pattern="\d{1}">
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" required pattern="\d{1}">
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" pattern="\d{1}">
  <button type="submit" class="btn btn-lg btn-primary">SUBMIT</button>
</form>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Thank you Roko C. Buljan who helped in the development of the code


P.S.: I've reviewed the answer to the question. But I realized it wasn't working.
J. Doe
  • 121
  • 1
  • 7

2 Answers2

11

To get the clipboardData text use ev.originalEvent.clipboardData.getData('text'),
than make sure the trimmed length is exactly 6 characters long and all are digits.
Assign to each input it's new value by splitting the string, and focus the last input:

// DOM utility functions:

const els = (sel, par) => (par || document).querySelectorAll(sel);


// Task: multiple inputs "field"

els(".pin").forEach((elGroup) => {

  const elsInput = [...elGroup.children];
  const len = elsInput.length;
  
  const handlePaste = (ev) => {
    const clip = ev.clipboardData.getData('text');     // Get clipboard data
    const pin = clip.replace(/\s/g, "");               // Sanitize string
    const ch = [...pin];                               // Create array of chars
    elsInput.forEach((el, i) => el.value = ch[i]??""); // Populate inputs
    elsInput[pin.length - 1].focus();                  // Focus input
  };

  const handleInput = (ev) => {
    const elInp = ev.currentTarget;
    const i = elsInput.indexOf(elInp);
    if (elInp.value && (i+1) % len) elsInput[i + 1].focus();  // focus next
  };
  
  const handleKeyDn = (ev) => {
    const elInp = ev.currentTarget
    const i = elsInput.indexOf(elInp);
    if (!elInp.value && ev.key === "Backspace" && i) elsInput[i - 1].focus(); // Focus previous
  };
  
  
  // Add the same events to every input in group:
  elsInput.forEach(elInp => {
    elInp.addEventListener("paste", handlePaste);   // Handle pasting
    elInp.addEventListener("input", handleInput);   // Handle typing
    elInp.addEventListener("keydown", handleKeyDn); // Handle deleting
  });
  
});
.pin > input {
  text-align: center;
  width: 1em;
}
.pin > input:invalid {
  color: red;
  caret-color: #000;
}
Copy some of thise PINs into any of the below inputs:<br>
<br>
<code>123329</code><br>
<code>6 5 0 3 2 1</code><br>
<code>444-998</code><br>
<code>x1A23z</code>
<code>12</code>
<br>
<form>
  <br>
  <div class="pin">
    PIN: 
    <input type="text" name="pass[]" maxlength="1" autocomplete="off" required pattern="\d{1}" autofocus>
    <input type="text" name="pass[]" maxlength="1" autocomplete="off" required pattern="\d{1}">
    <input type="text" name="pass[]" maxlength="1" autocomplete="off" required pattern="\d{1}">
    <input type="text" name="pass[]" maxlength="1" autocomplete="off" required pattern="\d{1}">
    <input type="text" name="pass[]" maxlength="1" autocomplete="off" required pattern="\d{1}">
    <input type="text" name="pass[]" maxlength="1" autocomplete="off" required pattern="\d{1}">
  </div>
  <br>
  <button type="submit" class="btn btn-lg btn-primary">SUBMIT</button>
</form>
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
1

You can listen to the paste event and grab the pasted text.

Then loop over each pasted char and update each input field like this:

$inp.on('paste', function(e) {

    var pastedData = e.originalEvent.clipboardData.getData('text');
    var pastedChars = pastedData.split("");

    var curIndex = $inp.index(this)

    for (var i=0; i < pastedChars.length; i++) {
      var char = pastedChars[i]
      $inp.eq(curIndex + i).val(char).focus();
    }
 }
});

There might be a little more you can do here to handle edge cases, but the basic principles should be in play in the demo below

var $inp = $(".passInput");

$inp.on({
 input: function(ev) {
  if(this.value) {
    $inp.eq($inp.index(this) + 1).focus();
  }
 },
 keydown: function(ev) {
  var i = $inp.index(this);
  if(ev.which===8 && !this.value && i) {
    $inp.eq(i - 1).focus();
  }
 },
 paste: function(e) {

    var pastedData = e.originalEvent.clipboardData.getData('text');
    var pastedChars = pastedData.split("");
    
    var curIndex = $inp.index(this)
    
    for (var i=0; i < pastedChars.length; i++) {
      var char = pastedChars[i]
      $inp.eq(curIndex + i).val(char).focus();
    }
 }
});
.passInput {text-align: center;}
<p>
Copy some text here: 123 123456
</p>
<form action="" role="form" method="post" id="passForm">
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" required pattern="\d{1}" autofocus>
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" required pattern="\d{1}">
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" required pattern="\d{1}">
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" required pattern="\d{1}">
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" required pattern="\d{1}">
  <input type="text" class="passInput" name="pass[]" maxLength="1" size="1" autocomplete="off" min="0" max="9" pattern="\d{1}">
  <button type="submit" class="btn btn-lg btn-primary">SUBMIT</button>
</form>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
KyleMit
  • 30,350
  • 66
  • 462
  • 664