Подключение сервиса обработки форм FormBold с помощью фреймворка Alpine.js
В настоящее время есть множество сервисов обработки форм, предлагающих, в том числе, бесплатный тариф с ограниченным функционалом. Сервис FormBold выделяется, среди конкурентов, довольно щедрым бесплатным тарифом – 5 форм, 100 сообщений в месяц, 2 целевых Email-адреса, на которые будут направляться сообщения из форм.
Рассмотрим пример подключения сервиса FormBold с помощью быстрого и лёгкого реактивного фреймворка Alpine.js.
Регистрация в FormBold и получение Endpoint
Для начала необходимо зарегистрироваться на сайте FormBold. Процесс регистрации тривиален, поэтому я не буду его описывать. После успешной регистрации создаём форму и получаем уникальный endpoint
формы в таком виде:
https://formbold.com/s/XXXXX
Установка фреймворка Alpine.js
В корне проекта выполняем команду:
# terminal
npm install alpinejs
Создание формы
Пример простейшей формы:
<!-- feedback.html -->
<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
браузером.
Последние два атрибута можно опустить, если вы полагаетесь на валидацию полей браузером.
Основной скрипт
// alpine.js
import Alpine from "alpinejs";
window.Alpine = Alpine;
import feedback from "./feedback";
Alpine.data("feedback", feedback);
Alpine.start();
Скрипт обработки формы feedback.js
вынесен в отдельный js-файл потому, что основной скрипт alpine.js
может объединять в себе и другие обработчики, которые можно импортировать и подключить аналогично.
Скрипт обработки формы
Полученный ранее endpoint
формы указываем в качестве значения свойства action
:
// feedback.js
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
– ошибка при отправке сообщения (текст ошибки записывается в консоль).
Кнопка «Отправить» отражает текущий статус формы и будет недоступна для нажатия во время отправки сообщения.
Рабочий пример этого решения можно посмотреть на странице Контакты.