Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как проверить форму перед отправкой

Короткий ответ

Атрибуты required, minlength и type="email" уже проверяют поля. Браузер не отправит форму, пока они не заполнены правильно:

<form id="form">
  <input name="name" required minlength="2" placeholder="Name">
  <input name="email" type="email" required placeholder="Email">
  <input name="age" type="number" min="18" max="120" placeholder="Age">
  <button>Send</button>
</form>
<p id="out"></p>
<script>
  document.getElementById('form').addEventListener('submit', (event) => {
    event.preventDefault();
    document.getElementById('out').textContent = 'All fields are valid';
  });
</script>

Свои правила

setCustomValidity() добавляет собственную проверку. Непустое сообщение делает поле недействительным, пустая строка — снова действительным:

const password = form.elements.password;
const repeat = form.elements.repeat;
 
repeat.addEventListener('input', () => {
  repeat.setCustomValidity(repeat.value === password.value ? '' : 'Passwords do not match');
});

Свой вывод ошибок

Атрибут novalidate у формы отключает сообщения браузера, и ошибки вы показываете сами, например в элементах с классом error и атрибутом data-for с именем поля:

form.addEventListener('submit', (event) => {
  if (!form.checkValidity()) {
    event.preventDefault();
    for (const field of form.querySelectorAll('input')) {
      const error = form.querySelector(`.error[data-for="${field.name}"]`);
      if (error) error.textContent = field.validationMessage;
    }
  }
});

Те же правила без браузера

Проверки в виде обычных функций можно использовать где угодно, в том числе на сервере:

const validate = (data) => {
  const errors = {};
  if (data.name.trim().length < 2) errors.name = 'Name is too short';
  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) errors.email = 'Invalid email';
  return errors;
};
 
console.log(validate({ name: 'A', email: 'anna@example.com' }));
console.log(Object.keys(validate({ name: 'Anna', email: 'anna@example.com' })).length);

Результат:

{
  "name": "Name is too short"
}
0

Частая ошибка

Проверки в браузере нужны только для удобства. Любой может отправить данные на сервер в обход формы, поэтому сервер должен проверить всё заново.

// a request without any form at all
await fetch('/api/signup', { method: 'POST', body: JSON.stringify({ email: 'not-an-email' }) });

Функции из этого ответа

  • RegExp.prototype.test — Проверяет, есть ли в строке совпадение с шаблоном.
  • Object.keys — Возвращает массив имён свойств объекта.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.