Обработка множественных submit-кнопок

HTMX предоставляет удобные механизмы для динамического взаимодействия с сервером без необходимости написания полноценного JavaScript-кода. Одной из частых задач при работе с формами является обработка нескольких submit-кнопок, каждая из которых должна инициировать разные действия на сервере. В HTMX это реализуется через атрибуты hx-post, hx-get, hx-target и hx-vals, а также через работу с событиями htmx:configRequest и htmx:beforeRequest.


Разделение действий через name и value кнопок

HTML-форма может содержать несколько кнопок:

<form id="multi-action-form" hx-post="/process" hx-target="#response">
    <input type="text" name="username" placeholder="Имя">
    <button type="submit" name="action" value="save">Сохранить</button>
    <button type="submit" name="action" value="delete">Удалить</button>
</form>

<div id="response"></div>

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

  • action=save — выполнить сохранение данных.
  • action=delete — выполнить удаление записи.

HTMX автоматически сериализует нажатую кнопку в тело запроса.


Использование hx-vals для передачи динамических данных

Иногда требуется отправить дополнительные данные, зависящие от конкретной кнопки. Атрибут hx-vals позволяет задать JSON-значения, которые будут добавлены к запросу:

<button type="submit" hx-vals='{"operation":"archive"}'>Архивировать</button>
<button type="submit" hx-vals='{"operation":"publish"}'>Опубликовать</button>

В этом случае к стандартным данным формы добавляется поле operation, и сервер получает точное указание, какую операцию выполнить.


Перехват запросов через события

HTMX предоставляет события, позволяющие программно модифицировать запрос перед отправкой. Для сложных сценариев с множественными submit-кнопками полезно использовать событие htmx:configRequest:

<script>
document.body.addEventListener('htmx:configRequest', function(event) {
    const triggered = event.target.querySelector('[type="submit"][hx-trigger]');
    if (triggered) {
        event.detail.parameters['clicked_button'] = triggered.value;
    }
});
</script>

event.detail.parameters позволяет добавлять или изменять параметры запроса, что расширяет возможности обычной сериализации формы.


Контекстные targets для каждой кнопки

Если нужно, чтобы результат каждого действия отображался в разных частях страницы, можно использовать индивидуальные hx-target для кнопок:

<button type="submit" hx-post="/save" hx-target="#save-response">Сохранить</button>
<button type="submit" hx-post="/delete" hx-target="#delete-response">Удалить</button>

<div id="save-response"></div>
<div id="delete-response"></div>

Такой подход избавляет от необходимости анализировать действие на сервере, так как каждая кнопка направляет запрос по своему URL и отображает результат в своём контейнере.


Условная отправка формы

С помощью hx-trigger можно привязать отправку к определённым условиям. Например, можно настроить, чтобы определённая кнопка отправляла форму только при валидном заполнении:

<button type="submit" hx-post="/submit" hx-trigger="click from:#multi-action-form" hx-disable="true">Отправить</button>

Здесь hx-disable="true" временно блокирует кнопку после нажатия до завершения запроса, предотвращая многократные отправки.


Интеграция с серверной логикой

Для корректной работы множественных submit-кнопок серверная часть должна учитывать:

  1. Проверку поля name кнопки для определения действия.
  2. Приоритет данных формы и hx-vals, чтобы не потерять дополнительные параметры.
  3. Разделение маршрутов (опционально), если каждая кнопка должна вызывать отдельный endpoint.

Пример на Python (Flask):

from flask import Flask, request, render_template_string

app = Flask(__name__)

@app.route('/process', methods=['POST'])
def process():
    action = request.form.get('action')
    username = request.form.get('username')
    
    if action == 'save':
        return f"Пользователь {username} сохранён"
    elif action == 'delete':
        return f"Пользователь {username} удалён"
    return "Неизвестное действие"

С помощью этого подхода HTMX позволяет управлять множественными submit-кнопками без написания отдельного JavaScript-кода для каждой кнопки, обеспечивая чистую и поддерживаемую архитектуру форм.


Итоговая структура подхода

  1. Каждая кнопка имеет name и value, чтобы сервер понимал действие.
  2. Используется hx-vals для передачи дополнительных данных.
  3. Можно привязывать индивидуальные hx-post и hx-target для каждой кнопки.
  4. События htmx:configRequest позволяют динамически изменять параметры запроса.
  5. Сервер обрабатывает действия в зависимости от полученных данных формы.

Такой набор инструментов обеспечивает гибкую обработку множественных submit-кнопок в HTMX, минимизируя количество клиентского кода и упрощая поддержку динамических форм.