Last active
August 22, 2021 09:19
-
-
Save b-aleksei/fdcd9f772660a9d66d513a9c772c330d to your computer and use it in GitHub Desktop.
ValidForm
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
const COUNTRY_CODE = 7; | |
const onInputPhoneInput = ({target}) => { | |
const matrix = `+${COUNTRY_CODE} (___) ___-__-__`; | |
let counter = 0; | |
let val = target.value.replace(/\D/g, ''); | |
if (!val.length) { | |
val = `${COUNTRY_CODE}`; | |
} | |
target.value = ''; | |
Array.prototype.forEach.call(matrix, (item) => { | |
let isValNumber = /[_\d]/.test(item) && val.length > counter; | |
if (isValNumber) { | |
target.value += val.charAt(counter++); | |
} else { | |
target.value += val.length <= counter ? '' : item; | |
} | |
}); | |
}; | |
export const onFocusPhoneInput = (target) => { | |
if (!target.value) { | |
target.value = `+${COUNTRY_CODE}`; | |
} | |
target.addEventListener('input', onInputPhoneInput); | |
target.addEventListener('blur', onBlurPhoneInput); | |
}; | |
const onBlurPhoneInput = ({target}) => { | |
if (target.value === `+${COUNTRY_CODE}`) { | |
target.value = ''; | |
} | |
target.removeEventListener('input', onInputPhoneInput); | |
target.removeEventListener('blur', onBlurPhoneInput); | |
}; | |
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
{ | |
"urlServer": "https://echo.htmlacademy.ru", | |
"errorMessages": { | |
"required": "Поле не должно быть пустым", | |
"phone": "Неправильный номер", | |
"email": "Некорректный email" | |
}, | |
"statusMessages": { | |
"success": "Ваша заявка принята", | |
"fail": "Удаленный сервер не найден", | |
"error": "Сетевая ошибка, проверьте интернет соединение" | |
} | |
} |
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
import {onFocusPhoneInput} from './onFocusPhoneInput'; | |
const validationData = {}; | |
const urlData = 'data/sendForm.json'; | |
fetch(urlData).then((res) => res.json()).then((res) => { | |
Object.assign(validationData, res); | |
}).catch(() => {}); | |
/*const getDataFromJson = function(url) { | |
const xhr = new XMLHttpRequest(); | |
xhr.open('GET', url); | |
xhr.onload = function() { | |
if (xhr.status === 200) { | |
Object.assign(validationData, JSON.parse(xhr.response)); | |
} | |
}; | |
xhr.send(); | |
}; | |
getDataFromJson(urlData);*/ | |
export class Validate { | |
constructor(form, config) { | |
this.form = typeof form === 'string' ? document.querySelector(form) : form; | |
if (!(this.form instanceof HTMLElement)) { | |
return; | |
} | |
this.defaultConfig = { | |
url: null, | |
classError: 'form-invalid', | |
statusMessages: null, | |
regEmail: /^\s*[\w.-]+@[\w-]+\.(?:[\w-]+\.)?[A-Za-z]{2,8}\s*$/, | |
}; | |
this.config = Object.assign(this.defaultConfig, config); | |
this.handleEvent = this.handleEvent.bind(this); | |
this.init(); | |
} | |
init() { | |
this.form.addEventListener('focusin', this.handleEvent); | |
this.form.addEventListener('focusout', this.handleEvent); | |
this.form.addEventListener('submit', this.handleEvent); | |
this.form.addEventListener('click', this.handleEvent); | |
this.form.addEventListener('change', this.handleEvent); | |
} | |
handleEvent(e) { | |
switch (e.type) { | |
case 'focusin': | |
if (e.target.hasAttribute('data-validate')) { | |
e.target.setCustomValidity(''); | |
e.target.parentElement.classList.remove('valid'); | |
e.target.parentElement.classList.remove('invalid'); | |
if (e.target.dataset.validate === 'phone') { | |
onFocusPhoneInput(e.target); | |
} | |
} | |
break; | |
case 'focusout': | |
if (e.target.hasAttribute('data-validate')) { | |
this.checkValue(e.target); | |
} | |
break; | |
case 'click': | |
if (e.target.closest('[type="submit"]')) { | |
this.form.classList.remove(this.config.classError); | |
const inputs = e.currentTarget.querySelectorAll('[data-validate]:not([disabled])'); | |
inputs.forEach((input) => { | |
this.checkValue(input); | |
}); | |
if (!this.form.checkValidity()) { // если форма не валидна | |
setTimeout(() => { | |
this.form.classList.add(this.config.classError); | |
}); | |
} | |
} | |
break; | |
case 'submit': | |
e.preventDefault(); | |
this.sendData(); | |
break; | |
} | |
} | |
setErrorMes(target, typeError) { | |
target.parentElement.classList.add('invalid'); | |
const messagesObj = validationData.errorMessages; | |
const errorEl = target.parentElement.querySelector('[data-error]'); | |
if (!messagesObj) return; | |
if (errorEl) { | |
errorEl.innerText = messagesObj[typeError]; | |
} | |
target.setCustomValidity(messagesObj[typeError]); | |
} | |
checkValue(target) { | |
target.parentElement.classList.remove('valid'); | |
target.parentElement.classList.remove('invalid'); | |
if (!target.value && target.required) { | |
this.setErrorMes(target, 'required'); | |
return; | |
} | |
if (target.dataset.validate === 'email') { | |
target.value = target.value.trim(); | |
if (target.value && !this.config.regEmail.test(target.value)) { | |
this.setErrorMes(target, 'email'); | |
return; | |
} | |
} | |
if (target.dataset.validate === 'phone') { | |
const phoneLength = target.value.replace(/\D/g, '').length; | |
if (target.value && phoneLength < 11) { | |
this.setErrorMes(target, 'phone'); | |
return; | |
} | |
} | |
target.parentElement.classList.add('valid'); | |
} | |
beforeSending() { | |
document.body.insertAdjacentHTML('beforeend', '<div id="spinner"><div class="swiper-lazy-preloader"></div></div>'); | |
} | |
afterSending() { | |
const spinner = document.getElementById('spinner'); | |
if (spinner) { | |
spinner.remove(); | |
} | |
} | |
transferStatus(status) { | |
console.log(validationData.statusMessages[status]); | |
} | |
sendData() { | |
this.beforeSending(); | |
fetch(this.config.url || validationData.urlServer, { | |
method: 'post', | |
body: new FormData(this.form), | |
}).then((res) => { | |
if (res.ok) { | |
this.transferStatus('success'); | |
this.form.reset(); | |
this.form.querySelectorAll('.valid').forEach((i) => { | |
i.classList.remove('valid'); | |
}); | |
} else { | |
this.transferStatus('fail'); | |
} | |
}).catch(() => { | |
this.transferStatus('error'); | |
}).finally(() => { | |
this.afterSending(); | |
}); | |
/*const xhr = new XMLHttpRequest(); | |
xhr.open('POST', this.config.url || validationData.urlServer); | |
xhr.onload = () => { | |
if (xhr.status === 200) { | |
console.log(xhr.response); | |
this.transferStatus('success'); | |
this.form.reset(); | |
this.form.querySelectorAll('.valid').forEach((i) => { | |
i.classList.remove('valid'); | |
}); | |
} else { | |
this.transferStatus('fail'); | |
} | |
this.afterSending(); | |
}; | |
xhr.send(new FormData(this.form));*/ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment