Урок 25

День 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') — находим элемент для сообщения об ошибке
  • Очищаем предыдущие состояния перед новой проверкой

Практическое задание

  1. Создайте форму с различными полями (имя, email, телефон, сообщение)
  2. Стилизуйте форму и поля ввода
  3. Напишите класс FormValidator
  4. Реализуйте валидацию для каждого поля
  5. Добавьте показ ошибок под полями
  6. Реализуйте валидацию в реальном времени (при blur)
  7. Добавьте визуальные индикаторы (error/success классы)
  8. Предотвратите отправку невалидной формы

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" — сообщение об ошибке (скринридер объявит его)

Что дальше?

Отлично! Валидация формы готова. В следующем уроке мы применим табы в реальном проекте — создадим блок программы обучения с использованием табов для разных модулей.

Мы используем файлы cookie для улучшения работы сайта и персонализации контента. Продолжая использовать сайт, вы соглашаетесь с использованием cookies в соответствии с нашей Политикой конфиденциальности.