Last active
September 16, 2023 20:08
-
-
Save marvinhagemeister/dfec9220a40d4ac08660224812ec9ca7 to your computer and use it in GitHub Desktop.
DOM input masking
This file contains hidden or 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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>Document</title> | |
</head> | |
<body> | |
<label for="foo">Input mask demo</label> | |
<input id="foo" type="text" pattern="\d{6}" /> | |
<script> | |
/** | |
* @param {Event} ev | |
* @param {Array<string | RegExp>} expected - The input mask | |
*/ | |
function maskHandler(ev, expected) { | |
const value = ev.target.value; | |
// Save selection or cursor position | |
const selStart = el.selectionStart; | |
const selEnd = el.selectionEnd; | |
let next = ""; | |
let clearStart = 0; | |
let clearEnd = 0; | |
let checkIdx = 0; | |
for (let i = 0; i < value.length; i++) { | |
const check = expected[checkIdx]; | |
const ch = value[i]; | |
if ( | |
check !== undefined && | |
(typeof check === "string" ? ch === check : check.test(ch)) | |
) { | |
checkIdx++; | |
next += ch; | |
continue; | |
} | |
// Adjust selection/cursor position for removed characters | |
if (i < selStart) clearStart++; | |
if (i > selStart && i < clearEnd) clearEnd++; | |
} | |
// Overwrite value if we needed to replace something | |
if (value !== next) { | |
ev.target.value = next; | |
const nextSelStart = selStart - clearStart; | |
const nextSelEnd = selEnd - clearStart - clearEnd; | |
el.setSelectionRange(nextSelStart, nextSelEnd); | |
} | |
} | |
const el = document.querySelector("input"); | |
el.addEventListener("input", (ev) => { | |
// Usage | |
maskHandler(ev, [/\d/, /\d/, /\d/, /\d/, /\d/, /\d/]); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment