В настоящее время есть множество сервисов обработки форм, предлагающих, в том числе, бесплатный тариф с ограниченным функционалом. Сервис FormBold выделяется, среди конкурентов, довольно щедрым бесплатным тарифом – 5 форм, 100 сообщений в месяц, 2 целевых Email-адреса, на которые будут направляться сообщения из форм.
Рассмотрим пример подключения сервиса FormBold с помощью быстрого и лёгкого реактивного фреймворка Alpine.js.
Для начала необходимо зарегистрироваться на сайте FormBold. Процесс регистрации тривиален, поэтому я не буду его описывать. После успешной регистрации создаём форму и получаем уникальный endpoint
формы в таком виде:
https://formbold.com/s/XXXXX
В корне проекта выполняем команду:
npm install alpinejs
Пример простейшей формы:
<form x-data="feedback" @submit.prevent="handleSubmit" :class="formValidate" novalidate>
<input type="text" name="name" placeholder="Ваше имя" required />
<input type="email" name="email" placeholder="Ваш Email" required />
<input type="text" name="subject" placeholder="Тема" required />
<textarea name="message" placeholder="Сообщение" required></textarea>
<button type="submit" :disabled="submitButtonDisable" x-text="submitButtonText"></button>
</form>
<script src="alpine.js"></script>
Пояснения:
x-data
создаёт компонент Alpine.js
с наименованием feedback
;@submit.prevent
вызывает обработчик формы handleSubmit
, который рассмотрен далее в этой статье, и одновременно блокирует поведение формы по умолчанию preventDefault()
;:class
вызывает геттер formValidate
, который, при нажатии на кнопку «Отправить», добавляет к форме класс validate
, необходимый для валидации полей required
с помощью своих сообщений и стилей, подробнее здесь;novalidate
предотвращает валидацию полей required
браузером.Последние два атрибута можно опустить, если вы полагаетесь на валидацию полей браузером.
import Alpine from 'alpinejs';
window.Alpine = Alpine;
import feedback from './feedback';
Alpine.data('feedback', feedback);
Alpine.start();
Скрипт обработки формы feedback.js
вынесен в отдельный js-файл потому, что основной скрипт alpine.js
может объединять в себе и другие обработчики, которые можно импортировать и подключить аналогично.
Полученный ранее endpoint
формы указываем в качестве значения свойства action
:
export default function () {
return {
status: 'init',
action: 'https://formbold.com/s/XXXXX',
handleSubmit() {
const form = this.$root;
this.status = 'validate';
if (form.checkValidity()) {
this.status = 'sending';
const formdata = new FormData(form);
const body = JSON.stringify(Object.fromEntries(formdata.entries()));
fetch(this.action, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json'
},
body: body
})
.then(() => {
this.status = 'sent';
setTimeout(() => (this.status = 'init'), 5000);
form.reset();
})
.catch((error) => {
this.status = 'error';
setTimeout(() => (this.status = 'init'), 10000);
console.log(error);
});
}
},
get formValidate() {
switch (this.status) {
case 'validate':
return this.status;
default:
return '';
}
},
get submitButtonText() {
switch (this.status) {
case 'sending':
return 'Отправляется';
case 'sent':
return 'Отправлено';
case 'error':
return 'Ошибка';
default:
return 'Отправить';
}
},
get submitButtonDisable() {
switch (this.status) {
case 'sending':
return true;
case 'sent':
return true;
case 'error':
return true;
default:
return false;
}
}
};
}
Таким образом, форма будет поочерёдно получать один из статусов:
init
– форма в процессе ожидания отправки;validate
– нажата кнопка «Отправить», но валидация ещё не подтверждена;sending
– валидация подтверждена и начался процес отправки;sent
– сообщение успешно отправлено;error
– ошибка при отправке сообщения (текст ошибки записывается в консоль).Кнопка «Отправить» отражает текущий статус формы и будет недоступна для нажатия во время отправки сообщения.