mirror of
https://github.com/avecms/AVE.cms.git
synced 2026-09-10 02:01:52 +00:00
144 lines
4.8 KiB
JavaScript
144 lines
4.8 KiB
JavaScript
(function (window, document) {
|
|
'use strict';
|
|
|
|
if (window.AvePhoneMask) {
|
|
window.AvePhoneMask.refresh(document);
|
|
return;
|
|
}
|
|
|
|
var selector = '[data-phone-mask]';
|
|
|
|
function rawDigits(value) {
|
|
return String(value || '').replace(/\D/g, '');
|
|
}
|
|
|
|
function phoneDigits(value) {
|
|
var digits = rawDigits(value);
|
|
if (!digits) { return ''; }
|
|
if (digits.charAt(0) === '8') {
|
|
digits = '7' + digits.slice(1);
|
|
} else if (digits.charAt(0) !== '7') {
|
|
digits = '7' + digits;
|
|
}
|
|
return digits.slice(0, 11);
|
|
}
|
|
|
|
function format(value) {
|
|
var digits = phoneDigits(value);
|
|
if (!digits) { return ''; }
|
|
var local = digits.slice(1);
|
|
var result = '+7';
|
|
if (local.length > 0) { result += ' (' + local.slice(0, 3); }
|
|
if (local.length >= 3) { result += ') ' + local.slice(3, 6); }
|
|
if (local.length >= 6) { result += '-' + local.slice(6, 8); }
|
|
if (local.length >= 8) { result += '-' + local.slice(8, 10); }
|
|
return result;
|
|
}
|
|
|
|
function caretAfterDigits(value, count) {
|
|
if (count <= 0) { return 0; }
|
|
var seen = 0;
|
|
for (var index = 0; index < value.length; index += 1) {
|
|
if (/\d/.test(value.charAt(index))) { seen += 1; }
|
|
if (seen >= count) { return index + 1; }
|
|
}
|
|
return value.length;
|
|
}
|
|
|
|
function validate(input) {
|
|
var digits = phoneDigits(input.value);
|
|
input.setCustomValidity(!digits || digits.length === 11 ? '' : 'Введите номер телефона полностью');
|
|
}
|
|
|
|
function prepare(input) {
|
|
if (!input || !input.matches || !input.matches(selector)) { return; }
|
|
input.type = 'tel';
|
|
input.inputMode = 'tel';
|
|
if (!input.autocomplete || input.autocomplete === 'off') { input.autocomplete = 'tel'; }
|
|
if (!input.placeholder) { input.placeholder = '+7 (000) 000-00-00'; }
|
|
if (!input.maxLength || input.maxLength < 0 || input.maxLength > 18) { input.maxLength = 18; }
|
|
validate(input);
|
|
}
|
|
|
|
function apply(input) {
|
|
if (!input || !input.matches || !input.matches(selector)) { return; }
|
|
var source = input.value;
|
|
var start = typeof input.selectionStart === 'number' ? input.selectionStart : source.length;
|
|
var digitsBefore = rawDigits(source.slice(0, start)).length;
|
|
var sourceDigits = rawDigits(source);
|
|
if (sourceDigits && sourceDigits.charAt(0) !== '7' && sourceDigits.charAt(0) !== '8') {
|
|
digitsBefore += 1;
|
|
}
|
|
input.value = format(source);
|
|
prepare(input);
|
|
if (document.activeElement === input && input.setSelectionRange) {
|
|
var caret = caretAfterDigits(input.value, digitsBefore);
|
|
input.setSelectionRange(caret, caret);
|
|
}
|
|
}
|
|
|
|
function refresh(root) {
|
|
root = root || document;
|
|
if (root.matches && root.matches(selector)) {
|
|
prepare(root);
|
|
if (root.value) { apply(root); }
|
|
}
|
|
if (!root.querySelectorAll) { return; }
|
|
Array.prototype.forEach.call(root.querySelectorAll(selector), function (input) {
|
|
prepare(input);
|
|
if (input.value) { apply(input); }
|
|
});
|
|
}
|
|
|
|
document.addEventListener('focusin', function (event) {
|
|
var input = event.target.closest ? event.target.closest(selector) : null;
|
|
if (input) { prepare(input); }
|
|
});
|
|
|
|
document.addEventListener('input', function (event) {
|
|
var input = event.target.closest ? event.target.closest(selector) : null;
|
|
if (input) { apply(input); }
|
|
});
|
|
|
|
document.addEventListener('paste', function (event) {
|
|
var input = event.target.closest ? event.target.closest(selector) : null;
|
|
if (!input) { return; }
|
|
window.setTimeout(function () { apply(input); }, 0);
|
|
});
|
|
|
|
document.addEventListener('keydown', function (event) {
|
|
var input = event.target.closest ? event.target.closest(selector) : null;
|
|
if (!input || event.key !== 'Backspace' || input.selectionStart !== input.selectionEnd) { return; }
|
|
var caret = input.selectionStart;
|
|
if (caret <= 0 || /\d/.test(input.value.charAt(caret - 1))) { return; }
|
|
var digitIndex = caret - 1;
|
|
while (digitIndex >= 0 && !/\d/.test(input.value.charAt(digitIndex))) { digitIndex -= 1; }
|
|
if (digitIndex <= 1) { return; }
|
|
event.preventDefault();
|
|
input.value = input.value.slice(0, digitIndex) + input.value.slice(digitIndex + 1);
|
|
input.setSelectionRange(digitIndex, digitIndex);
|
|
apply(input);
|
|
});
|
|
|
|
document.addEventListener('focusout', function (event) {
|
|
var input = event.target.closest ? event.target.closest(selector) : null;
|
|
if (!input) { return; }
|
|
if (phoneDigits(input.value) === '7') { input.value = ''; }
|
|
validate(input);
|
|
});
|
|
|
|
document.addEventListener('submit', function (event) {
|
|
if (!event.target.querySelectorAll) { return; }
|
|
Array.prototype.forEach.call(event.target.querySelectorAll(selector), function (input) {
|
|
apply(input);
|
|
});
|
|
}, true);
|
|
|
|
window.AvePhoneMask = {
|
|
apply: apply,
|
|
format: format,
|
|
refresh: refresh
|
|
};
|
|
refresh(document);
|
|
})(window, document);
|