<form action="" class="form" id="form" method="post">
<div class="form__inner">
<label class="form__label">
<input
data-req="name is required"
data-name="Invalid name"
data-success="Valid name"
type="text"
class="form__input"
name="name"
placeholder="il suo nome"
>
</label>
<label class="form__label">
<input
data-req="surname is required"
data-surname="Invalid surname"
data-success="Valid surname"
type="text"
class="form__input"
name="surname"
placeholder="il suo cog"
>
</label>
<label class="form__label">
<input
data-req="email is required"
data-email="Invalid email"
data-success="Valid email"
type="email"
class="form__input"
name="email"
placeholder="E-MAIL"
>
</label>
<label class="form__label form__label--phone">
<input
data-req="phone is required"
data-phone="Invalid phone"
data-success="Valid phone"
type="tel"
class="form__input form__input--phone"
name="phone"
>
</label>
<button class="form__btn" type="submit" disabled>registrati</button>
</div>
</form>
.form {
max-width: 354px;
width: 100%;
border-radius: 15px;
background: rgba(74, 74, 74, 0.82);
box-shadow: 0px 0px 12px 12px rgba(216, 30, 5, 0.29);
padding: 52px 0 45px 0;
box-sizing: border-box;
@include mobile {
background: #FFF;
box-shadow: 0px 4px 19.3px 4px rgba(0, 0, 0, 0.19);
}
}
.form__inner {
max-width: 300px;
width: 100%;
margin: 0 auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 11px;
}
.form__label {
width: 100%;
}
.form__mistake,
.form__success {
display: block;
font-weight: 500;
font-size: 14px;
color: #D81E05;
margin-top: 5px;
padding-left: 5px;
visibility: visible;
}
.form__success {
color: #0aa310;
}
.form__label.error .form__input {
border-color: #fd4a33;
}
.form__label.success .form__input {
border-color: #0aa310;
}
.form__input {
font-family: "Open Sans", sans-serif;
font-size: 16px;
line-height: 109.375%; /* 109.375% */
letter-spacing: 1px;
color: var(--text-color);
width: 100%;
padding: 11px 12px 11px 12px;
border-radius: 4px;
background-color: #F7F7F7;
outline: none;
border: 2px solid transparent;
&::placeholder {
font-family: "Open Sans", sans-serif;
font-size: 16px;
line-height: 109.375%; /* 109.375% */
letter-spacing: 1px;
text-transform: uppercase;
color: #818181;
}
@include mobile {
text-align: center;
}
}
.form__input--phone {
width: 300px;
// display: block;
}
.form__btn {
display: flex;
justify-content: center;
align-items: center;
font-family: "Open Sans", sans-serif;
font-size: 16px;
line-height: 109.375%; /* 109.375% */
letter-spacing: 1px;
text-transform: uppercase;
color: #FFF;
height: 45px;
width: 100%;
border-radius: 4px;
background-color: #D81E05;
margin-top: 41px;
transition: background-color 0.4s ease-out 0s;
&:hover {
background-color: #fd4a33;
}
&:active {
background-color: #a42717;
}
&:disabled {
cursor: not-allowed;
}
}
function ValidateForm(_form) {
const errorWrapperClass = 'error';
const successWrapperClass = 'success';
const parentItemClass = 'form__label';
const errorItemClass = 'form__mistake';
const successItemClass = 'form__success';
const _elements = _form.elements;
const submitButton = _form.querySelector('.form__btn');
_form.addEventListener('submit', event => {
// event.preventDefault();
this.checkFormElements();
if (!this.checkAllFields()) {
submitButton.disabled = false;
}
});
for (let _element of _elements) {
_element.addEventListener('input', () => {
this.checkFormElements(); // Проверяем поля при вводе
// Проверяем, валидны ли все поля, чтобы активировать кнопку
submitButton.disabled = this.checkAllFields();
});
}
this.checkFormElements = function() {
for(let _element of _elements) {
const reqMessage = _element.dataset.req;
const emailMessage = _element.dataset.email;
const nameMessage = _element.dataset.name;
const surnameMessage = _element.dataset.surname;
const phoneMessage = _element.dataset.phone;
const successMessage = _element.dataset.success;
this.clearErrorAndSuccess(_element);
if (reqMessage) {
this.checkRequired(_element, reqMessage, successMessage);
}
if (emailMessage) {
this.checkEmail(_element, emailMessage, successMessage);
}
if (nameMessage) {
this.checkName(_element, nameMessage, successMessage);
}
if (surnameMessage) {
this.checkName(_element, surnameMessage, successMessage);
}
if (phoneMessage) {
this.checkPhone(_element, phoneMessage, successMessage);
}
}
}
this.checkAllFields = function () {
let allValid = false;
for(let _element of _elements) {
const parent = _element.closest(`.${parentItemClass}`);
if (!parent || parent.classList.contains(successWrapperClass)) {
allValid = true;
break;
}
}
return allValid;
}
this.checkPhone = function (_element, phoneMessage, successMessage) {
const code = document.querySelector(`.${parentItemClass} .iti__selected-dial-code`).textContent.trim().toLowerCase();
const phoneSring = code + _element.value.trim();
const phoneRegExp = /^\+?[0-9\s\-()]{7,}$/;
if (!phoneRegExp.test(phoneSring)) {
this.errorTemplate(_element, phoneMessage);
} else {
this.successTemplate(_element, successMessage);
}
}
this.checkName = function (_element, nameMessage, successMessage) {
const nameString = _element.value.trim();
const nameRegExp = /^[a-zA-Zа-яА-ЯёЁ\s-]{2,50}$/;
if (!nameRegExp.test(nameString)) {
this.errorTemplate(_element, nameMessage);
} else {
this.successTemplate(_element, successMessage);
}
}
this.checkEmail = function (_element, emailMessage, successMessage) {
const emailString = _element.value.trim();
const emailRegExp = /^[^\s@]{1,64}@[^\s@]{1,255}\.[^\s@]{2,10}$/;
if (!emailRegExp.test(emailString)) {
this.errorTemplate(_element, emailMessage);
} else {
this.successTemplate(_element, successMessage);
}
}
this.checkRequired = function (_element, reqMessage, successMessage) {
const notValidString = _element.value.length === 0;
if (notValidString) {
this.errorTemplate(_element, reqMessage);
} else {
this.successTemplate(_element, successMessage);
}
}
this.errorTemplate = function (_element, reqMessage) {
const parent = _element.closest(`.${parentItemClass}`);
parent.classList.add(errorWrapperClass);
parent.insertAdjacentHTML('beforeend', `<small class='${errorItemClass}'>${reqMessage}</small>`);
}
this.successTemplate = function (_element, successMessage) {
const parent = _element.closest(`.${parentItemClass}`);
parent.classList.add(`${successWrapperClass}`);
if (!parent.querySelector(`.${successItemClass}`)) {
parent.insertAdjacentHTML('beforeend',`<small class='${successItemClass}'>${successMessage}</small>`)
}
}
this.clearErrorAndSuccess = function (_element) {
const parent = _element.closest(`.${parentItemClass}`);
if (parent !== null) {
parent.classList.remove(errorWrapperClass, successWrapperClass);
parent.querySelectorAll(`.${errorItemClass}, .${successItemClass}`).forEach(item => item.remove());
}
}
}
new ValidateForm(document.querySelector('#form'));
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.