Cascade-селект — это динамическое изменение опций одного элемента выбора (например, выпадающего списка) в зависимости от значения, выбранного в другом элементе. В web-разработке этот подход используется для создания зависимых выпадающих списков, когда выбор в одном списке влияет на доступные опции в другом. HTMX предоставляет простой и удобный способ реализации cascade-селектов с использованием минимального количества кода.
Для реализации cascade-селектов с помощью HTMX достаточно
минимального набора атрибутов, таких как hx-get,
hx-target и hx-trigger. Эти атрибуты позволяют
автоматически обновлять элементы интерфейса на основе пользовательского
ввода без необходимости перезагрузки страницы.
<select>, один для родительского списка и другой для
зависимого. Родительский список будет управлять доступными вариантами в
зависимом списке.Пример базовой реализации:
<form>
<label for="category">Категория</label>
<select id="category" name="category" hx-get="/get-subcategories" hx-target="#subcategory" hx-trigger="change">
<option value="">Выберите категорию</option>
<option value="electronics">Электроника</option>
<option value="clothing">Одежда</option>
<option value="books">Книги</option>
</select>
<label for="subcategory">Подкатегория</label>
<select id="subcategory" name="subcategory">
<option value="">Выберите подкатегорию</option>
</select>
</form>
hx-get: атрибут, который инициирует
HTTP-запрос при изменении значения родительского элемента. В нашем
примере запрос отправляется на URL /get-subcategories, где
сервер вернёт новые данные.
hx-trigger: указывает на событие,
которое должно активировать запрос. В случае с cascade-селектами это
событие change, которое происходит при изменении значения в
родительском списке.
hx-target: определяет, какой
элемент на странице должен быть обновлён результатом запроса. В нашем
примере это элемент с идентификатором #subcategory, то есть
зависимый список будет обновляться новыми подкатегориями.
Сервер должен обрабатывать запросы от клиента и возвращать актуальные данные для зависимых списков. Ответ может быть сгенерирован как HTML, так и в формате JSON. Для простоты в примере будет использоваться HTML-ответ, который HTMX вставит непосредственно в целевой элемент.
Пример серверного кода на Python с использованием Flask:
from flask import Flask, render_template_string, request
app = Flask(__name__)
@app.route('/get-subcategories')
def get_subcategories():
category = request.args.get('category')
subcategories = {
'electronics': ['Телевизоры', 'Смартфоны', 'Компьютеры'],
'clothing': ['Футболки', 'Джинсы', 'Обувь'],
'books': ['Фантастика', 'Детективы', 'Путеводители']
}
options = subcategories.get(category, [])
html = ''.join(f'<option value="{sub}">{sub}</option>' for sub in options)
return html
if __name__ == '__main__':
app.run(debug=True)
Этот серверный код обрабатывает запросы на
/get-subcategories и возвращает список подкатегорий в
зависимости от выбранной категории.
hx-trigger="load", который инициирует
запрос сразу после загрузки страницы.<select id="category" name="category" hx-get="/get-subcategories" hx-target="#subcategory" hx-trigger="change load">
hx-on="htmx:responseError", чтобы отловить ошибку в случае
неудачного запроса и отображать соответствующее сообщение.<div hx-on="htmx:responseError: alert('Ошибка при загрузке данных')">
Иногда необходимо работать не только с двумя списками, но и с несколькими зависимыми селекторами. Например, при фильтрации товаров по категориям, подкатегориям и брендам можно использовать несколько cascade-селектов.
<form>
<label for="category">Категория</label>
<select id="category" name="category" hx-get="/get-subcategories" hx-target="#subcategory" hx-trigger="change">
<option value="">Выберите категорию</option>
<option value="electronics">Электроника</option>
<option value="clothing">Одежда</option>
<option value="books">Книги</option>
</select>
<label for="subcategory">Подкатегория</label>
<select id="subcategory" name="subcategory" hx-get="/get-brands" hx-target="#brand" hx-trigger="change">
<option value="">Выберите подкатегорию</option>
</select>
<label for="brand">Бренд</label>
<select id="brand" name="brand">
<option value="">Выберите бренд</option>
</select>
</form>
В данном случае, при изменении подкатегории, будет отправлен запрос на сервер для получения брендов, доступных для выбранной подкатегории. Серверная логика будет аналогичной, но с учётом добавления новой зависимости — бренда.
Использование HTMX для реализации cascade-селектов позволяет создавать динамичные и отзывчивые формы с минимальными усилиями. Комбинируя различные атрибуты HTMX, можно строить гибкие зависимости между элементами интерфейса, улучшая пользовательский опыт и уменьшив количество кода на стороне клиента.