Skip to content

Instantly share code, notes, and snippets.

@b-aleksei
Last active August 12, 2020 13:03
Show Gist options
  • Save b-aleksei/fbfa3f27190258b86ce9f34b77cbc108 to your computer and use it in GitHub Desktop.
Save b-aleksei/fbfa3f27190258b86ce9f34b77cbc108 to your computer and use it in GitHub Desktop.
phone-validation-regExp
/* html
<div class="form__input-wrap">
<input name="name" data-validate="true" type="text" pattern="[A-z,А-я]{2,}" placeholder="Введите Ваше Имя"
aria-label="Введите Ваше Имя" required>
<span class="form__error form__error--name">Имя должно содержать минимум 2 буквы</span>
</div>
<div class="form__input-wrap">
<input name="phone" data-validate="true" type="text" pattern="\+7\s\([0-9]{3}\)\s[0-9]{3}\s[0-9]{2}\s[0-9]{2}"
placeholder="Введите Ваш номер телефона"
aria-label="Введите Ваш номер телефона" required>
<span class="form__error form__error--phone">Поле телефон не заполнено</span>
</div>
*/
/* scss
.form__input-wrap {
position: relative;
margin-bottom: 20px;
}
.form__input-valid {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 5px;
overflow: hidden;
width: 20px;
height: 18px;
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: $color-default-white;
transition: transform $default-transition;
}
}
.form__valid .form__input-valid::after {
transform: translate(100%);
}
.form__invalid input {
border: 1px solid red;
}
.form__error {
position: absolute;
bottom: -13px;
left: 0;
width: 100%;
color: red;
font-size: 10px;
opacity: 0;
transition: opacity $default-transition;
}
.form__invalid .form__error {
opacity: 1;
}
*/
const START_INDEX = 4;
const FIRST_NUMBER = '7';
const substrateThree = '___';
const substrateTwo = '__';
const delimiter = ' ';
const regExp = /^7? ?\(?(\d{0,3})\)? ?(\d{0,3})-?(\d{0,2})-?(\d{0,2})/;
const regE = /7.*/;
const pln = /(?:\d\D*)$/g; // позиция последней цифры
const controlKeys = ['Tab', 'ArrowRight', 'ArrowLeft', 'ArrowDown', 'ArrowUp'];
const signSuccess = `
<span class="form__input-valid">
<svg width="20" height="18">
<use href="img/sprite_auto.svg#tick"></use>
</svg>
</span>`;
const forms = document.querySelectorAll('form');
const enterPhoneValue = function (e) {
const isControlKey = controlKeys.some(function (key) {
return e.key === key;
});
if (!e.ctrlKey && !isControlKey) {
let cursor = this.selectionStart = this.selectionEnd;
setTimeout(() => {
let number = this.value.match(regE) || [FIRST_NUMBER];
let arr = Array.from(number[0]);
let str = arr.filter((item) => /\d/.test(item));
str = str.join('').slice(0, 11);
this.value = str.replace(regExp, (m, p1, p2, p3, p4) => {
return '+' + FIRST_NUMBER + ' (' + (p1 + substrateThree).slice(0, substrateThree.length) + ') '
+ (p2 + substrateThree).slice(0, substrateThree.length) + delimiter
+ (p3 + substrateTwo).slice(0, substrateTwo.length) + delimiter
+ (p4 + substrateTwo).slice(0, substrateTwo.length);
});
// управление курсором
let search = this.value.search(pln);
this.selectionStart = this.selectionEnd = (e.key === 'Delete') ? cursor : search + 1;
if (cursor < START_INDEX) {
this.selectionStart = this.selectionEnd = START_INDEX;
}
checkValidity.call(this);
}, 1);
}
};
const checkValidity = function () {
if (!this.validity.valid) {
this.parentElement.classList.remove('form__valid');
this.parentElement.classList.add('form__invalid');
} else {
this.parentElement.classList.remove('form__invalid');
this.parentElement.classList.add('form__valid');
}
};
// обработчик события focus на form
const onValidate = function (e) {
if (e.target.name === 'phone') {
e.target.addEventListener('keydown', enterPhoneValue);
}
if (e.target.name === 'name') {
e.target.addEventListener('input', checkValidity);
}
this.addEventListener('focusout', deleteHandler);
};
const deleteHandler = function (e) {
if (e.target.name === 'phone') {
e.target.removeEventListener('keydown', enterPhoneValue);
}
if (e.target.name === 'name') {
e.target.removeEventListener('input', checkValidity);
}
this.removeEventListener('focusout', deleteHandler);
};
const onSubmit = function (e) {
for (const input of this.elements) {
if (input.dataset.validate) {
localStorage.setItem(input.name, input.value);
}
}
console.log('form success');
// openClosePopup(modalSuccess); // успешная отправка формы
e.preventDefault();
};
// валидация форм на главной странице
forms.forEach(function (form) {
for (const input of form.elements) {
if (input.dataset.validate) {
input.value = localStorage.getItem(input.name);
input.parentElement.insertAdjacentHTML('afterbegin', signSuccess); // добавляет зеленую галочку если валидно
}
}
form.addEventListener('focusin', onValidate);
form.addEventListener('submit', onSubmit);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment