Created
December 9, 2022 15:09
-
-
Save enlightenedpie/4deceed54307e34571dc9a393de9dde6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const optcode1 = document.getElementById("otpcode1"); | |
const optcodes = document.querySelectorAll('input[id^="otpcode"]'); | |
const codeInput = document.getElementById("code"); | |
const otpForm = document.getElementById("validation-code-submit-form"); | |
let popuNext = (el, data) => { | |
el.value = data[0]; // Apply first item to first input | |
data = data.substring(1); // remove the first char. | |
if (el.nextElementSibling && data.length) { | |
// Do the same with the next element and next data | |
popuNext(el.nextElementSibling, data); | |
} | |
}; | |
let splitNumber = (e) => { | |
let data = e.data || e.target.value; // Chrome doesn't get the e.data, it's always empty, fallback to value then. | |
if (!data) return; // Shouldn't happen, just in case. | |
if (data.length === 1) return; // Here is a normal behavior, not a paste action. | |
popuNext(e.target, data); | |
}; | |
if (optcodes.length > 0) | |
optcodes.forEach((input) => { | |
input.addEventListener("keyup", function (e) { | |
// Break if Shift, Tab, CMD, Option, Control. | |
if ( | |
e.keyCode === 16 || | |
e.keyCode == 9 || | |
e.keyCode == 224 || | |
e.keyCode == 18 || | |
e.keyCode == 17 | |
) { | |
return; | |
} | |
// On Backspace or left arrow, go to the previous field. | |
if ( | |
(e.keyCode === 8 || e.keyCode === 37) && | |
this.previousElementSibling && | |
this.previousElementSibling.tagName === "INPUT" | |
) { | |
this.previousElementSibling.select(); | |
} else if ( | |
e.keyCode !== 8 && | |
this.nextElementSibling && | |
this.nextElementSibling.tagName === "INPUT" | |
) { | |
this.nextElementSibling.select(); | |
} | |
// If the target is populated too quickly, value length can be > 1 | |
if (this.value.length > 1) { | |
splitNumber(e); | |
} | |
}); | |
/** | |
* Better control on Focus | |
* - don't allow focus on other field if the first one is empty | |
* - don't allow focus on field if the previous one if empty (debatable) | |
* - get the focus on the first empty field | |
*/ | |
input.addEventListener("focus", function (e) { | |
// If the focus element is the first one, do nothing | |
if (e.target === optcode1) return; | |
// If value of input 1 is empty, focus it. | |
if (optcode1.value == "") { | |
optcode1.focus(); | |
} | |
// If value of a previous input is empty, focus it. | |
// To remove if you don't wanna force user respecting the fields order. | |
if (this.previousElementSibling.value == "") { | |
this.previousElementSibling.focus(); | |
} | |
}); | |
}); | |
/** | |
* Handle copy/paste of a big number. | |
* It catches the value pasted on the first field and spread it into the inputs. | |
*/ | |
if (optcode1) optcode1.addEventListener("input", splitNumber); | |
otpForm.addEventListener("submit", (e) => { | |
// concatenate input values as one string and set it as hidden input value | |
let hiddenValue = Array.from(optcodes).map((inp) => inp.value).join(''); | |
codeInput.value = hiddenValue; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment