День 25 | Верстаем форму с валидацией на чистом JS
70 минЧто такое валидация формы?
Валидация формы — это проверка данных, которые вводит пользователь, перед отправкой. Валидация нужна, чтобы:
- Убедиться, что все обязательные поля заполнены
- Проверить правильность формата данных (email, телефон)
- Показать пользователю понятные сообщения об ошибках
- Предотвратить отправку неверных данных на сервер
Где происходит валидация?
- На клиенте (JavaScript) — быстрая проверка, хороший UX
- На сервере (PHP, Node.js и т.д.) — обязательная проверка (клиентскую можно обойти)
Важно: Валидация на клиенте — это удобство для пользователя, но не безопасность! Всегда проверяйте данные на сервере.
HTML структура формы
<form class="form" id="contactForm">
<div class="form-group">
<label for="name">Имя *</label>
<input type="text" id="name" name="name" required>
<span class="error-message"></span>
</div>
<div class="form-group">
<label for="email">Email *</label>
<input type="email" id="email" name="email" required>
<span class="error-message"></span>
</div>
<div class="form-group">
<label for="phone">Телефон</label>
<input type="tel" id="phone" name="phone">
<span class="error-message"></span>
</div>
<div class="form-group">
<label for="message">Сообщение *</label>
<textarea id="message" name="message" rows="5" required></textarea>
<span class="error-message"></span>
</div>
<button type="submit" class="submit-btn">Отправить</button>
</form>
Разберём структуру:
<form>— контейнер формы<label>— подпись поля (связана с input черезfor="id")<input>— поле вводаtype— тип поля (text, email, tel, password и т.д.)name— имя поля (используется при отправке формы)id— идентификатор (для связи с label)required— обязательное поле (HTML5 валидация)
<textarea>— многострочное поле ввода<span class="error-message">— место для сообщения об ошибке
Регулярные выражения (RegExp)
Регулярные выражения — это способ проверки формата строки. Выглядит страшно, но очень полезно!
Валидация email
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
Разберём по частям:
/— начало регулярного выражения^— начало строки[^\s@]+— один или более символов, которые НЕ пробел и НЕ @[]— набор символов^внутри [] означает "НЕ"\s— пробел@— символ @+— один или более раз
@— обязательный символ @[^\s@]+— домен (часть после @)\.— точка (экранирована, потому что в RegExp точка означает "любой символ")[^\s@]+— окончание домена (.com, .ru и т.д.)$— конец строки/— конец регулярного выражения
Как использовать:
const email = "user@example.com";
if (emailRegex.test(email)) {
console.log("Email валиден!");
} else {
console.log("Email невалиден!");
}
test() — метод регулярного выражения, который проверяет, соответствует ли строка паттерну. Возвращает true или false.
Валидация телефона
const phoneRegex = /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/;
Этот паттерн принимает телефоны в форматах:
- +7 (999) 123-45-67
- 8-999-123-45-67
- 999 123 4567
- 999.123.4567
Разберём:
[\+]?— необязательный знак +[(]?— необязательная открывающая скобка[0-9]{3}— ровно 3 цифры[)]?— необязательная закрывающая скобка[-\s\.]?— необязательный разделитель (дефис, пробел или точка)[0-9]{4,6}— от 4 до 6 цифр
Разбор JavaScript кода валидации
Предотвращение отправки формы
this.form.addEventListener('submit', (e) => {
e.preventDefault();
if (this.validate()) {
// Форма валидна, можно отправить
}
});
Что такое e.preventDefault()? По умолчанию при отправке формы страница перезагружается. preventDefault() отменяет это поведение, позволяя нам обработать отправку через JavaScript.
Валидация в реальном времени
input.addEventListener('blur', () => this.validateField(input));
input.addEventListener('input', () => {
if (input.classList.contains('error')) {
this.validateField(input);
}
});
События:
blur— когда поле теряет фокус (пользователь ушёл с поля). Проверяем поле сразу после того, как пользователь закончил ввод.input— при каждом изменении значения. Проверяем только если поле уже имеет ошибку (чтобы не мешать пользователю во время ввода).
Метод validateField()
validateField(field) {
const value = field.value.trim();
const fieldName = field.name;
const errorElement = field.parentElement.querySelector('.error-message');
// Очистка предыдущих состояний
field.classList.remove('error', 'success');
errorElement.textContent = '';
// Проверки...
return true; // или false
}
Разберём:
field.value— значение поля.trim()— убирает пробелы в начале и конце строкиfield.parentElement— родительский элемент (form-group)querySelector('.error-message')— находим элемент для сообщения об ошибке- Очищаем предыдущие состояния перед новой проверкой
Практическое задание
- Создайте форму с различными полями (имя, email, телефон, сообщение)
- Стилизуйте форму и поля ввода
- Напишите класс FormValidator
- Реализуйте валидацию для каждого поля
- Добавьте показ ошибок под полями
- Реализуйте валидацию в реальном времени (при blur)
- Добавьте визуальные индикаторы (error/success классы)
- Предотвратите отправку невалидной формы
HTML5 валидация (Constraint Validation API)
Браузеры предоставляют встроенный API для валидации форм. Это дополняет нашу JavaScript валидацию.
Методы валидации
const input = document.querySelector("#email");
// Проверка валидности
if (input.checkValidity()) {
console.log("Поле валидно");
} else {
console.log("Поле невалидно");
console.log(input.validationMessage); // Сообщение об ошибке
}
// Установка кастомного сообщения
input.setCustomValidity("Это поле обязательно!");
input.reportValidity(); // Показать сообщение пользователю
Свойства валидации
const input = document.querySelector("#email");
input.validity.valid; // true/false
input.validity.valueMissing; // true, если required поле пустое
input.validity.typeMismatch; // true, если тип не совпадает (например, email)
input.validity.patternMismatch; // true, если не соответствует pattern
input.validationMessage; // Сообщение об ошибке
CSS псевдоклассы для валидации
/* Валидное поле */
input:valid {
border-color: #10b981;
}
/* Невалидное поле */
input:invalid {
border-color: #ef4444;
}
/* Поле в фокусе */
input:focus:invalid {
border-color: #ef4444;
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
}
Атрибут pattern (регулярное выражение)
<input
type="text"
name="phone"
pattern="[\+]?[0-9]{10,15}"
title="Формат: +79991234567 или 89991234567"
>
Браузер автоматически проверит соответствие паттерну.
Доступность форм
ARIA атрибуты
<div class="form-group">
<label for="email">Email *</label>
<input
type="email"
id="email"
name="email"
required
aria-required="true"
aria-invalid="false"
aria-describedby="email-error"
>
<span id="email-error" class="error-message" role="alert"></span>
</div>
ARIA атрибуты:
aria-required="true"— поле обязательноaria-invalid="true/false"— поле невалидноaria-describedby="id"— связь с сообщением об ошибкеrole="alert"— сообщение об ошибке (скринридер объявит его)
Что дальше?
Отлично! Валидация формы готова. В следующем уроке мы применим табы в реальном проекте — создадим блок программы обучения с использованием табов для разных модулей.