Improved documentation for htmx:confirm event and examples for implementing sweetalert (#2926)

* Add detail.question and detail.issueRequest(skipConfirmation=false) documentation to htmx:confirm event

* Update htmx:confirm event documentation

* Update htmx:confirm event documentation

* Update htmx:confirm event documentation

* Modify htmx:confirm event documentation
This commit is contained in:
Luis Eduardo 2024-09-25 01:39:28 -06:00 committed by GitHub
parent 44c4de41cc
commit 27b5bcc438
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 63 additions and 24 deletions

View File

@ -179,43 +179,70 @@ than a single value.
### Event - `htmx:confirm` {#htmx:confirm}
This event is triggered immediately after a trigger occurs on an element. It allows you to cancel (or delay) issuing
the AJAX request. If you call `preventDefault()` on the event, it will not issue the given request. The `detail`
object contains a function, `evt.detail.issueRequest()`, that can be used to issue the actual AJAX request at a
later point. Combining these two features allows you to create an asynchronous confirmation dialog.
This event is fired on every trigger for a request (not just on elements that have a hx-confirm attribute).
It allows you to cancel (or delay) issuing the AJAX request.
If you call `preventDefault()` on the event, it will not issue the given request.
The `detail` object contains a function, `evt.detail.issueRequest(skipConfirmation=false)`, that can be used to issue the actual AJAX request at a later point.
Combining these two features allows you to create an asynchronous confirmation dialog.
Here is an example using [sweet alert](https://sweetalert.js.org/guides/) on any element with a `confirm-with-sweet-alert='true'` attribute on it:
Here is a basic example that shows the basic usage of the `htmx:confirm` event without altering the default behavior:
```javascript
document.body.addEventListener('htmx:confirm', function(evt) {
if (evt.target.matches("[confirm-with-sweet-alert='true']")) {
evt.preventDefault();
swal({
title: "Are you sure?",
text: "Are you sure you are sure?",
icon: "warning",
buttons: true,
dangerMode: true,
}).then((confirmed) => {
if (confirmed) {
evt.detail.issueRequest();
}
});
}
// 0. To modify the behavior only for elements with the hx-confirm attribute,
// check if evt.detail.target.hasAttribute('hx-confirm')
// 1. Prevent the default behavior (this will prevent the request from being issued)
evt.preventDefault();
// 2. Do your own logic here
console.log(evt.detail)
// 3. Manually issue the request when you are ready
evt.detail.issueRequest(); // or evt.detail.issueRequest(true) to skip the built-in window.confirm()
});
```
And here is an example using [sweet alert](https://sweetalert.js.org/guides/) on any element with a `confirm-with-sweet-alert="{question}"` attribute on it:
```javascript
document.body.addEventListener('htmx:confirm', function(evt) {
// 1. The requirement to show the sweet alert is that the element has a confirm-with-sweet-alert
// attribute on it, if it doesn't we can return early and let the default behavior happen
if (!evt.detail.target.hasAttribute('confirm-with-sweet-alert')) return
// 2. Get the question from the attribute
const question = evt.detail.target.getAttribute('confirm-with-sweet-alert');
// 3. Prevent the default behavior (this will prevent the request from being issued)
evt.preventDefault();
// 4. Show the sweet alert
swal({
title: "Are you sure?",
text: question || "Are you sure you want to continue?",
icon: "warning",
buttons: true,
dangerMode: true,
}).then((confirmed) => {
if (confirmed) {
// 5. If the user confirms, we can manually issue the request
evt.detail.issueRequest(true); // true to skip the built-in window.confirm()
}
});
});
```
##### Details
{target: target, elt: elt, path: path, verb: verb, triggeringEvent: event, etc: etc, issueRequest: issueRequest}
* `detail.elt` - the element in question
* `detail.etc` - additional request information (mostly unused)
* `detail.issueRequest` - a no argument function that can be invoked to issue the request (should be paired with `evt.preventDefault()`!)
* `detail.issueRequest(skipConfirmation=false)` - a function that can be invoked to issue the request (should be paired with `evt.preventDefault()`!), if skipConfirmation is `true` the original `window.confirm()` is not executed
* `detail.path` - the path of the request
* `detail.target` - the target of the request
* `detail.target` - the element that triggered the request
* `detail.triggeringEvent` - the original event that triggered this request
* `detail.verb` - the verb of the request (e.g. `GET`)
* `detail.question` - the question passed to `hx-confirm` attribute (only available if `hx-confirm` attribute is present)
### Event - `htmx:historyCacheError` {#htmx:historyCacheError}

View File

@ -36,12 +36,22 @@ which is then picked up by `hx-trigger`.
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
document.addEventListener("htmx:confirm", function(e) {
// The event is triggered on every trigger for a request, so we need to check if the element
// that triggered the request has a hx-confirm attribute, if not we can return early and let
// the default behavior happen
if (!evt.detail.target.hasAttribute('hx-confirm')) return
// This will prevent the request from being issued to later manually issue it
e.preventDefault()
Swal.fire({
title: "Proceed?",
text: `I ask you... ${e.detail.question}`
}).then(function(result) {
if(result.isConfirmed) e.detail.issueRequest(true) // use true to skip window.confirm
if (result.isConfirmed) {
// If the user confirms, we manually issue the request
e.detail.issueRequest(true); // true to skip the built-in window.confirm()
}
})
})
</script>
@ -62,3 +72,5 @@ when the question depends on the element e.g. a django list:
<button hx-post="/delete/{{client.pk}}" hx-confirm="Delete {{client.name}}??">Delete</button>
{% endfor %}
```
Learn more about the [`htmx:confirm`](@/events.md#htmx:confirm) event [here](@/events.md#htmx:confirm).