Как проверить форму перед отправкой
Короткий ответ
Атрибуты 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 — Возвращает массив имён свойств объекта.