Валидация при отправке формы строится вокруг перехвата события
submit, в котором данные формы проходят полный цикл
проверки до передачи на сервер. Основная задача — предотвратить
некорректные данные ещё на клиентском уровне и сформировать
структурированный набор ошибок.
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
event.preventDefault();
const data = {
email: form.email.value,
password: form.password.value,
phone: form.phone.value
};
const errors = validateForm(data);
if (Object.keys(errors).length > 0) {
renderErrors(errors);
return;
}
form.submit();
});
В этом подходе отправка формы блокируется до завершения всех проверок, что позволяет контролировать поток данных и исключать некорректные запросы.
Перед валидацией данные приводятся к единому виду. Это снижает количество ложных ошибок и упрощает правила проверки.
const normalizeData = (data) => {
return {
email: data.email.trim().toLowerCase(),
password: data.password,
phone: data.phone.replace(/\s+/g, '')
};
};
Часто используется:
trim)null и undefined на пустые
строкиПервичный этап валидации связан с контролем заполненности полей. Для
этого используется validator.js:
import validator from 'validator';
if (validator.isEmpty(data.email)) {
errors.email = 'Email обязателен';
}
if (validator.isEmpty(data.password)) {
errors.password = 'Пароль обязателен';
}
Функция isEmpty проверяет не только пустую строку, но и
строки, содержащие только пробелы (при соответствующей предварительной
нормализации).
Библиотека предоставляет набор универсальных функций, применяемых при проверке формы.
if (!validator.isEmail(data.email)) {
errors.email = 'Некорректный email';
}
if (!validator.isLength(data.password, { min: 8 })) {
errors.password = 'Пароль должен содержать минимум 8 символов';
}
if (!validator.isInt(data.age, { min: 18 })) {
errors.age = 'Возраст должен быть не менее 18';
}
if (!validator.isMobilePhone(data.phone, 'any')) {
errors.phone = 'Некорректный номер телефона';
}
if (!validator.isURL(data.website)) {
errors.website = 'Некорректный URL';
}
Реальные формы требуют комбинированных проверок, где одно поле проходит несколько условий одновременно.
if (
!validator.isLength(data.password, { min: 8 }) ||
!/[A-Z]/.test(data.password) ||
!/[0-9]/.test(data.password)
) {
errors.password = 'Пароль не соответствует требованиям сложности';
}
Также часто применяется проверка совпадения значений:
if (!validator.equals(data.password, data.confirmPassword)) {
errors.confirmPassword = 'Пароли не совпадают';
}
Для удобной обработки ошибок на интерфейсе используется объект с привязкой к полям формы.
const validateForm = (data) => {
const errors = {};
if (validator.isEmpty(data.email)) {
errors.email = 'Email обязателен';
} else if (!validator.isEmail(data.email)) {
errors.email = 'Некорректный email';
}
if (!validator.isLength(data.password, { min: 8 })) {
errors.password = 'Пароль слишком короткий';
}
return errors;
};
Такая структура позволяет напрямую связывать ошибки с элементами DOM.
Ошибки обычно отображаются рядом с соответствующими полями.
const renderErrors = (errors) => {
Object.keys(errors).forEach((field) => {
const errorElement = document.querySelector(`#${field}-error`);
if (errorElement) {
errorElement.textContent = errors[field];
}
});
};
Перед повторной валидацией старые сообщения очищаются:
const clearErrors = () => {
document.querySelectorAll('.error').forEach((el) => {
el.textContent = '';
});
};
Логика отправки зависит от результата проверки. При наличии ошибок процесс останавливается.
form.addEventListener('submit', (event) => {
event.preventDefault();
clearErrors();
const normalized = normalizeData({
email: form.email.value,
password: form.password.value
});
const errors = validateForm(normalized);
if (Object.keys(errors).length > 0) {
renderErrors(errors);
return;
}
form.submit();
});
Помимо проверки, библиотека используется для подготовки данных к безопасному использованию.
const safeData = {
email: validator.normalizeEmail(data.email),
comment: validator.escape(data.comment)
};
Основные функции:
normalizeEmail — приводит email к каноническому
видуescape — экранирует HTML-символыtrim — удаляет лишние пробелыВ формах с зависимыми полями применяется динамическая валидация.
if (data.hasCompany === true) {
if (validator.isEmpty(data.companyName)) {
errors.companyName = 'Укажите название компании';
}
}
Такие условия позволяют адаптировать проверку под контекст заполнения.
Некоторые проверки требуют обращения к серверу, например проверка уникальности email.
const checkEmailExists = async (email) => {
const response = await fetch(`/api/check-email?email=${email}`);
const result = await response.json();
return result.exists;
};
Интеграция в общий поток:
if (await checkEmailExists(data.email)) {
errors.email = 'Email уже используется';
}
При увеличении сложности формы правила выносятся в отдельные функции.
const rules = {
email: (value) => {
if (validator.isEmpty(value)) return 'Email обязателен';
if (!validator.isEmail(value)) return 'Некорректный email';
return null;
},
password: (value) => {
if (!validator.isLength(value, { min: 8 })) {
return 'Минимум 8 символов';
}
return null;
}
};
Применение:
Object.keys(rules).forEach((field) => {
const error = rules[field](data[field]);
if (error) errors[field] = error;
});
Иногда требуется возвращать сразу несколько сообщений для одного поля.
const passwordErrors = [];
if (!validator.isLength(data.password, { min: 8 })) {
passwordErrors.push('Минимум 8 символов');
}
if (!/[A-Z]/.test(data.password)) {
passwordErrors.push('Должна быть заглавная буква');
}
if (passwordErrors.length > 0) {
errors.password = passwordErrors;
}
Валидация часто связана с динамическим состоянием интерфейса: блокировка кнопки, подсветка полей, индикация загрузки.
const submitButton = form.querySelector('button');
if (Object.keys(errors).length > 0) {
submitButton.disabled = true;
} else {
submitButton.disabled = false;
}
При асинхронной проверке важно предотвращать повторный submit.
let isSubmitting = false;
form.addEventListener('submit', async (event) => {
event.preventDefault();
if (isSubmitting) return;
isSubmitting = true;
const errors = await validateFormAsync(data);
isSubmitting = false;
if (Object.keys(errors).length > 0) {
renderErrors(errors);
return;
}
form.submit();
});