Stimulus — легковесный JavaScript-фреймворк, который позволяет добавлять поведение на HTML-страницы, используя декларативный подход. Одной из наиболее частых задач является управление формами: отслеживание отправки, валидация, асинхронная обработка и динамическое обновление интерфейса. Stimulus предоставляет для этого удобные механизмы через контроллеры, экшены и значения (values).
Для начала контроллер подключается к форме через атрибут
data-controller:
<form data-controller="form" data-action="submit->form#submit">
<input type="text" name="username" />
<button type="submit">Отправить</button>
</form>
data-controller="form" — подключает контроллер
form_controller.js.data-action="submit->form#submit" — связывает
событие submit с методом submit
контроллера.В Stimulus каждое событие связывается с конкретным методом, что делает код структурированным и легко поддерживаемым.
Контроллер описывается как класс, наследуемый от
Controller:
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
submit(event) {
event.preventDefault();
const formData = new FormData(this.element);
// Пример обработки данных
const data = Object.fromEntries(formData.entries());
console.log("Отправка данных:", data);
this.sendRequest(data);
}
async sendRequest(data) {
try {
const response = await fetch(this.element.action, {
method: this.element.method,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
if (!response.ok) throw new Error("Ошибка при отправке формы");
const result = await response.json();
this.handleSuccess(result);
} catch (error) {
this.handleError(error);
}
}
handleSuccess(result) {
console.log("Форма успешно отправлена:", result);
}
handleError(error) {
console.error("Ошибка формы:", error);
}
}
event.preventDefault() блокирует стандартное поведение
браузера.FormData позволяет собрать данные формы в удобном
виде.fetch используется для асинхронной отправки на
сервер.Stimulus позволяет задавать values, чтобы хранить настраиваемые параметры контроллера:
<form data-controller="form"
data-form-url-value="/api/submit"
data-action="submit->form#submit">
<input type="text" name="username" />
<button type="submit">Отправить</button>
</form>
export default class extends Controller {
static values = { url: String }
submit(event) {
event.preventDefault();
const formData = Object.fromEntries(new FormData(this.element).entries());
this.sendRequest(formData, this.urlValue);
}
async sendRequest(data, url) {
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
const result = await response.json();
console.log(result);
}
}
this.urlValue автоматически связывается с
атрибутом data-form-url-value.Stimulus упрощает динамическое изменение состояния формы, например, при отправке:
submit(event) {
event.preventDefault();
this.element.querySelector("button").disabled = true;
const data = Object.fromEntries(new FormData(this.element).entries());
this.sendRequest(data);
}
handleSuccess(result) {
this.element.reset();
this.element.querySelector("button").disabled = false;
alert("Форма успешно отправлена");
}
handleError(error) {
this.element.querySelector("button").disabled = false;
console.error(error);
}
Если на странице несколько форм, можно использовать декларативные экшены с идентификаторами:
<form data-controller="form" data-action="submit->form#submit" data-form-id-value="1">
...
</form>
<form data-controller="form" data-action="submit->form#submit" data-form-id-value="2">
...
</form>
Контроллер получает уникальные значения через
data-form-id-value:
static values = { id: Number }
submit(event) {
event.preventDefault();
console.log("ID формы:", this.idValue);
}
Stimulus позволяет проверять данные перед отправкой:
submit(event) {
event.preventDefault();
const username = this.element.querySelector("input[name='username']").value;
if (!username || username.length < 3) {
this.showError("Имя пользователя должно быть минимум 3 символа");
return;
}
const data = Object.fromEntries(new FormData(this.element).entries());
this.sendRequest(data);
}
showError(message) {
const errorElement = this.element.querySelector(".error") || document.createElement("div");
errorElement.className = "error";
errorElement.textContent = message;
this.element.appendChild(errorElement);
}
Stimulus сочетает декларативное связывание событий с мощными возможностями контроллеров, значений и экшенов, обеспечивая простое и чистое управление формами, их состоянием, асинхронной отправкой и валидацией без громоздкого JavaScript-кода.