Files
ave-cms/system/App/Frontend/Auth/assets/phone-mask.js
T

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);