Last active
August 12, 2020 13:03
-
-
Save b-aleksei/fbfa3f27190258b86ce9f34b77cbc108 to your computer and use it in GitHub Desktop.
phone-validation-regExp
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
/* 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