hx-prompt
Запрос подтверждения перед запросами с hx-prompt='Reason?'
Расширение hx-prompt возвращает атрибут hx-prompt из htmx 2.
Перед каждым запросом появляется диалог браузера с запросом ввода. Ответ становится заголовком HX-Prompt. Если пользователь отменяет ввод, запрос не отправляется.
Установка
<script src="https://cdn.jsdelivr.net/npm/htmx.org@4.0.0/dist/htmx.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@4.0.0/dist/ext/hx-prompt.js"></script>
Использование
<button hx-delete="/items/1" hx-prompt="Reason for deletion?">
Delete
</button> При щелчке:
- Браузер спрашивает
Reason for deletion?. - Отмена прерывает запрос.
- При любом ответе (даже пустом) генерируется отменяемое событие
htmx:prompt, содержащее ответ вevent.detail.prompt. - Если событие не отменено, htmx отправляет запрос с заголовком
HX-Prompt, содержащим ответ.
Событие htmx:prompt
Событие htmx:prompt генерируется на исходном элементе после получения допустимого ответа.
Подпишитесь на него с помощью hx-on::prompt и вызовите event.preventDefault(), чтобы прервать запрос:
<button hx-delete="/items/1"
hx-prompt="Reason?"
hx-on::prompt="if (prompt.length < 3) event.preventDefault()">
Delete
</button> event.detail содержит { prompt, target }. hx-on предоставляет его напрямую, поэтому его можно использовать без извлечения из обёртки.
Наследование
Атрибут hx-prompt поддерживает наследование.
<div hx-prompt:inherited="Reason?">
<button hx-delete="/items/1">Delete</button>
<button hx-delete="/items/2">Delete</button>
</div> Совместное использование с hx-confirm
hx-prompt выполняется до hx-confirm. Для продолжения запроса необходимо пройти обе проверки:
<button hx-delete="/items/1"
hx-prompt="Reason?"
hx-confirm="Are you sure?">
Delete
</button> Если пользователь отменяет ввод, диалог подтверждения не отображается.
Пользовательские диалоговые окна
Назначьте функцию для window.htmxPrompt, чтобы использовать пользовательский (синхронный) диалог.
// receives the question, returns the answer string or null to cancel window.htmxPrompt = (question) => myCustomSyncDialog(question);
По умолчанию расширение использует window.prompt.
Пример на стороне сервера
HX-Prompt — это обычный заголовок запроса. Получайте его так же, как ваш сервер получает другие заголовки.
def delete_item(request, id):
reason = request.headers.get("HX-Prompt", "")
Item.objects.filter(id=id).delete(reason=reason)
return HttpResponse("") # empty response removes the row Без расширения
Если вы предпочитаете обойтись без расширения, то то же самое можно сделать с помощью одного hx-on:
<button hx-delete="/items/1"
hx-on::config:request="ctx.request.headers['HX-Prompt'] = prompt('Reason?') ?? event.preventDefault()">
Delete
</button>
Licensed under the Zero-Clause BSD License.
https://four.htmx.org/extensions/hx-prompt/