Я написал более общий ответ здесь об использовании видимой маски для форматированного ввода фиксированного размера.Это должно работать для вас, если вы принимаете, что маска ввода всегда видна.Чтобы это работало, добавьте следующие атрибуты к вашему input
:
<input placeholder="__-__-__-____" data-slots="_" data-accept="\w" size="13">
Обратите внимание, что он не превращает строчные буквы в прописные (что-то, против чего я бы посоветовал: вы не хотите, чтобы люди думали, что ихCAPS-замок не работает).Если вы не хотите, чтобы это работало (с маской или отсутствием верхнего регистра), вот код, специально адаптированный к вашим требованиям:
const el = document.getElementById("vname"),
pattern = "__-__-__-____",
prev = [1, 2, 2, 4, 5, 5, 7, 8, 8, 10, 11, 12, 13],
accept = /\w/g,
clean = input => {
input = input.match(accept) || [];
return Array.from(pattern, c =>
input[0] === c || c == "_" ? input.shift() || c : c
);
},
format = () => {
const [i, j] = [el.selectionStart, el.selectionEnd].map(i => {
i = clean(el.value.slice(0, i)).indexOf("_");
return i<0? prev[prev.length-1]: back? prev[i-1] || 0: i;
});
let s = clean(el.value).join``.toUpperCase();
el.value = s.slice(0, (s+"_").indexOf("_"));
el.setSelectionRange(i, j);
back = false;
};
let back = false;
el.addEventListener("keydown", (e) => back = e.key === "Backspace");
el.addEventListener("input", format);
<input type="text" id="vname" />
Как и в ответе, о котором я говорил, это также относится к копированию / вставке (даже если в копируемых значениях нет дефисов), с выделением, помещаякурсор на полпути, удаление символов там ... и т. д.