mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-09-30 14:31:47 +00:00
clean our references to extensions, link to the new extensions website
This commit is contained in:
parent
6da79f2e32
commit
30a9941b61
@ -1,117 +0,0 @@
|
||||
+++
|
||||
title = "Extensions"
|
||||
insert_anchor_links = "left"
|
||||
+++
|
||||
|
||||
Htmx provides an extension mechanism for defining and using extensions within htmx-based applications.
|
||||
|
||||
## Using Extensions {#using}
|
||||
|
||||
Using an extension involves two steps:
|
||||
|
||||
* include the extension definition, which will add it to the `htmx` extension registry
|
||||
* reference the extension via the [hx-ext](@/attributes/hx-ext.md) attribute
|
||||
|
||||
Here is an example
|
||||
|
||||
```html
|
||||
<script src="/path/to/ext/debug.js" defer></script>
|
||||
<button hx-post="/example" hx-ext="debug">This Button Uses The Debug Extension</button>
|
||||
```
|
||||
|
||||
This loads the debug extension off of the `unpkg` CDN and then adds the debug extension to the given button. (This
|
||||
will print out extensive logging for the button, for debugging purposes.)
|
||||
|
||||
Note that the `hx-ext` tag may be placed on parent elements if you want a plugin to apply to an entire part of the DOM,
|
||||
and on the `body` tag for it to apply to all htmx requests.
|
||||
|
||||
**Tip:** To use multiple extensions on one element, separate them with a comma:
|
||||
|
||||
```html
|
||||
<button hx-post="/example" hx-ext="debug, json-enc">This Button Uses Two Extensions</button>
|
||||
```
|
||||
|
||||
## Ignoring Extensions {#ignoring}
|
||||
|
||||
By default, extensions are applied to the DOM node where it is invoked, along with all child elements inside of that parent node.
|
||||
If you need to disable an extension somewhere within the DOM tree, you can use the `ignore:` keyword to stop it from being used.
|
||||
|
||||
```html
|
||||
<div hx-ext="debug">
|
||||
<button hx-post="/example">This button used the debug extension</button>
|
||||
<button hx-post="/example" hx-ext="ignore:debug">This button does not</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Included Extensions {#included}
|
||||
|
||||
htmx includes a set of extensions out of the box that address common developer needs. These extensions are tested
|
||||
against `htmx` in each distribution.
|
||||
|
||||
### Installing Extensions {#installing}
|
||||
|
||||
You can find the source for the bundled extensions at `https://unpkg.com/browse/htmx.org@1.9.11/dist/ext/`. You will need
|
||||
to include the javascript file for the extension and then install it using the [hx-ext](@/attributes/hx-ext.md) attributes.
|
||||
|
||||
See the individual extension documentation for more details.
|
||||
|
||||
### Included Extensions List {#reference}
|
||||
|
||||
<div class="info-table">
|
||||
|
||||
| Extension | Description
|
||||
|------------------------------------------------------------------|-------------
|
||||
| [`ajax-header`](@/extensions/ajax-header.md) | includes the commonly-used `X-Requested-With` header that identifies ajax requests in many backend frameworks
|
||||
| [`alpine-morph`](@/extensions/alpine-morph.md) | an extension for using the [Alpine.js morph](https://alpinejs.dev/plugins/morph) plugin as the swapping mechanism in htmx.
|
||||
| [`class-tools`](@/extensions/class-tools.md) | an extension for manipulating timed addition and removal of classes on HTML elements
|
||||
| [`client-side-templates`](@/extensions/client-side-templates.md) | support for client side template processing of JSON/XML responses
|
||||
| [`debug`](@/extensions/debug.md) | an extension for debugging of a particular element using htmx
|
||||
| [`event-header`](@/extensions/event-header.md) | includes a JSON serialized version of the triggering event, if any
|
||||
| [`head-support`](@/extensions/head-support.md) | support for merging the `head` tag from responses into the existing documents `head`
|
||||
| [`include-vals`](@/extensions/include-vals.md) | allows you to include additional values in a request
|
||||
| [`json-enc`](@/extensions/json-enc.md) | use JSON encoding in the body of requests, rather than the default `x-www-form-urlencoded`
|
||||
| [`idiomorph`](https://github.com/bigskysoftware/idiomorph) | an extension for using the idiomorph morphing algorithm as a swapping mechanism
|
||||
| [`loading-states`](@/extensions/loading-states.md) | allows you to disable inputs, add and remove CSS classes to any element while a request is in-flight.
|
||||
| [`method-override`](@/extensions/method-override.md) | use the `X-HTTP-Method-Override` header for non-`GET` and `POST` requests
|
||||
| [`morphdom-swap`](@/extensions/morphdom-swap.md) | an extension for using the [morphdom](https://github.com/patrick-steele-idem/morphdom) library as the swapping mechanism in htmx.
|
||||
| [`multi-swap`](@/extensions/multi-swap.md) | allows to swap multiple elements with different swap methods
|
||||
| [`path-deps`](@/extensions/path-deps.md) | an extension for expressing path-based dependencies [similar to intercoolerjs](http://intercoolerjs.org/docs.html#dependencies)
|
||||
| [`preload`](@/extensions/preload.md) | preloads selected `href` and `hx-get` targets based on rules you control.
|
||||
| [`remove-me`](@/extensions/remove-me.md) | allows you to remove an element after a given amount of time
|
||||
| [`response-targets`](@/extensions/response-targets.md) | allows to specify different target elements to be swapped when different HTTP response codes are received
|
||||
| [`restored`](@/extensions/restored.md) | allows you to trigger events when the back button has been pressed
|
||||
| [`server-sent-events`](@/extensions/server-sent-events.md) | uni-directional server push messaging via [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)
|
||||
| [`web-sockets`](@/extensions/web-sockets.md) | bi-directional connection to WebSocket servers
|
||||
| [`path-params`](@/extensions/path-params.md) | allows to use parameters for path variables instead of sending them in query or body
|
||||
|
||||
</div>
|
||||
|
||||
## Defining an Extension {#defining}
|
||||
|
||||
To define an extension you call the `htmx.defineExtension()` function:
|
||||
|
||||
```html
|
||||
<script>
|
||||
htmx.defineExtension('my-ext', {
|
||||
onEvent : function(name, evt) {
|
||||
console.log("Fired event: " + name, evt);
|
||||
}
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
Typically, this is done in a stand-alone javascript file, rather than in an inline `script` tag.
|
||||
|
||||
Extensions should have names that are dash separated and that are reasonably short and descriptive.
|
||||
|
||||
Extensions can override the following default extension points to add or change functionality:
|
||||
|
||||
```javascript
|
||||
{
|
||||
onEvent : function(name, evt) {return true;},
|
||||
transformResponse : function(text, xhr, elt) {return text;},
|
||||
isInlineSwap : function(swapStyle) {return false;},
|
||||
handleSwap : function(swapStyle, target, fragment, settleInfo) {return false;},
|
||||
encodeParameters : function(xhr, parameters, elt) {return null;}
|
||||
}
|
||||
```
|
@ -1,21 +0,0 @@
|
||||
+++
|
||||
title = "ajax-header"
|
||||
+++
|
||||
|
||||
This extension adds the `X-Requested-With` header to requests with the value "XMLHttpRequest".
|
||||
|
||||
This header is commonly used by javascript frameworks to differentiate ajax requests from normal http requests.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/ajax-header.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<body hx-ext="ajax-header">
|
||||
...
|
||||
</body>
|
||||
```
|
@ -1,43 +0,0 @@
|
||||
+++
|
||||
title = "alpine-morph"
|
||||
+++
|
||||
|
||||
Alpine.js now has a lightweight [morph plugin](https://alpinejs.dev/plugins/morph) and this extension allows you to use it as the swapping mechanism in htmx which is necessary to retain Alpine state when you have entire Alpine components swapped by htmx.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/alpine-morph.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<header>
|
||||
<script src="https://unpkg.com/htmx.org@latest"></script>
|
||||
<script src="https://unpkg.com/htmx.org@latest/dist/ext/alpine-morph.js"></script>
|
||||
<!-- Alpine Plugins -->
|
||||
<script defer src="https://unpkg.com/@alpinejs/morph@3.x.x/dist/cdn.min.js"></script>
|
||||
<!-- Alpine Core -->
|
||||
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||
</header>
|
||||
|
||||
<body>
|
||||
<div hx-target="this" hx-ext="alpine-morph" hx-swap="morph">
|
||||
<div x-data="{ count: 0, replaced: false,
|
||||
message: 'Change me, then press the button!' }">
|
||||
<input type="text" x-model="message">
|
||||
<div x-text="count"></div>
|
||||
<button x-bind:style="replaced && {'backgroundColor': '#fecaca'}"
|
||||
x-on:click="replaced = true; count++"
|
||||
hx-get="/swap">
|
||||
Morph
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
In the above example, all the Alpine x-data states (count, replaced, and message) are preserved even the entire Alpine component is swapped.
|
||||
|
||||
NOTE: `/swap` response from the example above should return actual element that is being replaced (this is `<div hx-target="this"...` element).
|
@ -1,36 +0,0 @@
|
||||
+++
|
||||
title = "class-tools"
|
||||
+++
|
||||
|
||||
The `class-tools` extension allows you to specify CSS classes that will be swapped onto or off of the elements by using
|
||||
a `classes` or `data-classes` attribute. This functionality allows you to apply
|
||||
[CSS Transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions)
|
||||
to your HTML without resorting to javascript.
|
||||
|
||||
A `classes` attribute value consists of "runs", which are separated by an `&` character. All
|
||||
class operations within a given run will be applied sequentially, with the delay specified.
|
||||
|
||||
Within a run, a `,` character separates distinct class operations.
|
||||
|
||||
A class operation is an operation name `add`, `remove`, or `toggle`, followed by a CSS class name,
|
||||
optionally followed by a colon `:` and a time delay.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/class-tools.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<div hx-ext="class-tools">
|
||||
<div classes="add foo"/> <!-- adds the class "foo" after 100ms -->
|
||||
<div class="bar" classes="remove bar:1s"/> <!-- removes the class "bar" after 1s -->
|
||||
<div class="bar" classes="remove bar:1s, add foo:1s"/> <!-- removes the class "bar" after 1s
|
||||
then adds the class "foo" 1s after that -->
|
||||
<div class="bar" classes="remove bar:1s & add foo:1s"/> <!-- removes the class "bar" and adds
|
||||
class "foo" after 1s -->
|
||||
<div classes="toggle foo:1s"/> <!-- toggles the class "foo" every 1s -->
|
||||
</div>
|
||||
```
|
@ -1,180 +0,0 @@
|
||||
+++
|
||||
title = "client-side-templates"
|
||||
+++
|
||||
|
||||
This extension supports transforming a JSON/XML request response into HTML via a client-side template before it is
|
||||
swapped into the DOM. Currently four client-side templating engines are supported:
|
||||
|
||||
* [mustache](https://github.com/janl/mustache.js)
|
||||
* [handlebars](https://handlebarsjs.com/)
|
||||
* [nunjucks](https://mozilla.github.io/nunjucks/)
|
||||
* [xslt](https://developer.mozilla.org/en-US/docs/Web/XSLT)
|
||||
|
||||
When you add this extension on an element, any element below it in the DOM can use one of four attributes named
|
||||
`<template-engine>-template` (e.g. `mustache-template`) with a template ID, and the extension will resolve and render
|
||||
the template the standard way for that template engine:
|
||||
|
||||
* `mustache` - looks a mustache <script> tag up by ID for the template content
|
||||
* `handlebars` - looks a handlebars <script> tag up by ID for the template content
|
||||
* `nunjucks` - resolves the template by name via `nunjucks.render(<template-name>)
|
||||
* `xslt` - looks an XSLT <script> tag up by ID for the template content
|
||||
|
||||
The AJAX response body will be parsed as JSON/XML and passed into the template rendering.
|
||||
|
||||
A second "array" version of each template is now offered, which is particularly helpful for APIs that return arrays of data. These templates are referenced as `<template-engine>-array-template`, and the data is accessed as `data.my_server_field`. At least in the case of `mustache`, it also enables use of loops using the `{{#data}} my_server_field {{/data}}` syntax.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/client-side-templates.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<div hx-ext="client-side-templates">
|
||||
<button hx-get="/some_json"
|
||||
mustache-template="my-mustache-template">
|
||||
Handle with mustache
|
||||
</button>
|
||||
<button hx-get="/some_json"
|
||||
handlebars-template="my-handlebars-template">
|
||||
Handle with handlebars
|
||||
</button>
|
||||
<button hx-get="/some_json"
|
||||
nunjucks-template="my-nunjucks-template">
|
||||
Handle with nunjucks
|
||||
</button>
|
||||
<button hx-get="/some_xml"
|
||||
xslt-template="my-xslt-template">
|
||||
Handle with XSLT
|
||||
</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Full Mustache HTML Example
|
||||
|
||||
To use the client side template, you will need to include htmx, the extension, and the rendering engine.
|
||||
Here is an example of this setup for Mustache using
|
||||
a [`<template>` tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>JS Bin</title>
|
||||
<script src="https://unpkg.com/htmx.org"></script>
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/client-side-templates.js"></script>
|
||||
<script src="https://unpkg.com/mustache@latest"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div hx-ext="client-side-templates">
|
||||
<button hx-get="https://jsonplaceholder.typicode.com/todos/1"
|
||||
hx-swap="innerHTML"
|
||||
hx-target="#content"
|
||||
mustache-template="foo">
|
||||
Click Me
|
||||
</button>
|
||||
|
||||
<p id="content">Start</p>
|
||||
|
||||
<template id="foo">
|
||||
<p> {% raw %}{{userID}}{% endraw %} and {% raw %}{{id}}{% endraw %} and {% raw %}{{title}}{% endraw %} and {% raw %}{{completed}}{% endraw %}</p>
|
||||
</template>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Here is a [jsbin](https://jsbin.com/qonutovico/edit?html,output) playground to try this out.
|
||||
|
||||
Here's a working example using the `mustache-array-template` working against an API that returns an array:
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>JS Bin</title>
|
||||
<script src="https://unpkg.com/htmx.org"></script>
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/client-side-templates.js"></script>
|
||||
<script src="https://unpkg.com/mustache@latest"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div hx-ext="client-side-templates">
|
||||
<button hx-get="https://jsonplaceholder.typicode.com/users"
|
||||
hx-swap="innerHTML"
|
||||
hx-target="#content"
|
||||
mustache-array-template="foo">
|
||||
Click Me
|
||||
</button>
|
||||
|
||||
<p id="content">Start</p>
|
||||
|
||||
<template id="foo">
|
||||
{{#data}}
|
||||
<p> {{name}} at {{email}} is with {{company.name}}</p>
|
||||
{{/data}}
|
||||
</template>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### Full XSLT HTML Example
|
||||
|
||||
To use the client side template, you will need to include htmx and the extension.
|
||||
Here is an example of this setup for XSLT using a [`<script>` tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script).
|
||||
|
||||
If you wish to put a template into another file, you can use a directive such as
|
||||
`<object id="template-id" data="my-template.xml" style="position: absolute; bottom: 0px; width: 0px; height: 0px;">`.
|
||||
Some styling is needed to keep the object visible while not taking any space.
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>JS Bin</title>
|
||||
<script src="https://unpkg.com/htmx.org"></script>
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/client-side-templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div hx-ext="client-side-templates">
|
||||
<button hx-get="http://restapi.adequateshop.com/api/Traveler"
|
||||
hx-swap="innerHTML"
|
||||
hx-target="#content"
|
||||
xslt-template="foo">
|
||||
Click Me
|
||||
</button>
|
||||
|
||||
<p id="content">Start</p>
|
||||
|
||||
<script id="foo" type="application/xml">
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:template match="/">
|
||||
page <xsl:value-of select="/TravelerinformationResponse/page" /> of <xsl:value-of select="/TravelerinformationResponse/total_pages" />
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
|
||||
## CORS and REST/JSON
|
||||
|
||||
As a warning, many web services use CORS protection and/or other protection schemes to reject a
|
||||
REST/JSON request from a web browser - for example, GitHub will issue a CORS error if you try to
|
||||
use the above snippet to access public APIs. This can be frustrating, as a dedicated REST development
|
||||
client may work fine, but the CORS error will appear when running JavaScript. This doesn't really
|
||||
have anything to do with HTMX (as you'd have the same issues with any JavaScript code), but can be
|
||||
a frustrating surprise.
|
||||
|
||||
Unfortunately, the solution will vary depending on the provider of the web service. Depending on
|
||||
what you are trying to do, you may find it easier to rely on your server-side framework to manage/proxy
|
||||
these requests to 3rd parties services.
|
@ -1,18 +0,0 @@
|
||||
+++
|
||||
title = "debug"
|
||||
+++
|
||||
|
||||
This extension includes log all htmx events for the element it is on, either through the `console.debug` function
|
||||
or through the `console.log` function with a `DEBUG:` prefix.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/debug.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<button hx-ext="debug">Debug Me...</button>
|
||||
```
|
@ -1,33 +0,0 @@
|
||||
+++
|
||||
title = "disable-element"
|
||||
+++
|
||||
|
||||
**NOTE: This extensions functionality has been folded into the core of htmx via the `hx-disabled-elt` attribute**
|
||||
|
||||
This extension disables an element during an htmx request, when configured on the element triggering the request.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/disable-element.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Nominal case: disabling the element triggering the request
|
||||
```html
|
||||
<button hx-get="/whatever" hx-ext="disable-element" hx-disable-element="self">Click me</button>
|
||||
```
|
||||
|
||||
### Disabling another element
|
||||
```html
|
||||
<button hx-get="/whatever" hx-ext="disable-element" hx-disable-element="#to-disable">Click me</button>
|
||||
<button id="to-disable">Watch me being disabled</button>
|
||||
```
|
||||
|
||||
### Disabling multiple elements
|
||||
```html
|
||||
<button hx-get="/whatever" hx-ext="disable-element" hx-disable-element=".to-disable">Click me</button>
|
||||
<button class="to-disable">Watch me being disabled</button>
|
||||
<button class="to-disable">Watch me being disabled also</button>
|
||||
```
|
@ -1,25 +0,0 @@
|
||||
+++
|
||||
title = "event-header"
|
||||
+++
|
||||
|
||||
This extension adds the `Triggering-Event` header to requests. The value of
|
||||
the header is a JSON serialized version of the event that triggered the
|
||||
request.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/event-header.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<button hx-ext="event-header">
|
||||
Click Me!
|
||||
</button>
|
||||
```
|
||||
Sends something like this:
|
||||
```txt
|
||||
Triggering-Event: '{ "isTrusted": false, "htmx-internal-data": { "handled": true }, "screenX": 0, "screenY": 0, "clientX": 0, "clientY": 0, "ctrlKey": false, "shiftKey": false, "altKey": false, "metaKey": false, "button": 0, "buttons": 0, "relatedTarget": null, "pageX": 0, "pageY": 0, "x": 0, "y": 0, "offsetX": 0, "offsetY": 0, "movementX": 0, "movementY": 0, "fromElement": null, "toElement": "button", "layerX": 0, "layerY": 0, "view": "Window", "detail": 0, "sourceCapabilities": null, "which": 1, "NONE": 0, "CAPTURING_PHASE": 1, "AT_TARGET": 2, "BUBBLING_PHASE": 3, "type": "click", "target": "button", "currentTarget": "button", "eventPhase": 2, "bubbles": true, "cancelable": true, "defaultPrevented": true, "composed": true, "timeStamp": 188.86999995447695, "srcElement": "button", "returnValue": false, "cancelBubble": false, "path": [ "button", "div#work-area", "body", "html", "Node", "Window" ] }'
|
||||
```
|
@ -1,114 +0,0 @@
|
||||
+++
|
||||
title = "head-support"
|
||||
+++
|
||||
|
||||
The `head-support` extension adds support for [head tags](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head)
|
||||
in responses to htmx requests.
|
||||
|
||||
htmx began as a library focused on _partial replacement_ of HTML within the `body` tag. As such, merging additional
|
||||
information such as the head tag was not a focus of the library. (This is in contrast with, for example, TurboLinks,
|
||||
which was focused on merging entire web pages retrieved via AJAX into the browser.)
|
||||
|
||||
The [`hx-boost`](@/attributes/hx-boost.md) attribute moved htmx closer to this world of full HTML-document support &
|
||||
support for extracting the `title` tag out of head elements was eventually added, but full head tag support has never been
|
||||
a feature of the library.
|
||||
|
||||
This extension addresses that shortcoming & will likely be integrated into htmx for the 2.0 release.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/head-support.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<body hx-ext="head-support">
|
||||
...
|
||||
```
|
||||
|
||||
With this installed, all responses that htmx receives that contain a `head` tag in them (even if they are not complete
|
||||
HTML documents with a root `<html>` element) will be processed.
|
||||
|
||||
How the head tag is handled depends on the type of htmx request.
|
||||
|
||||
If the htmx request is from a boosted element, then the following merge algorithm is used:
|
||||
|
||||
* Elements that exist in the current head as exact textual matches will be left in place
|
||||
* Elements that do not exist in the current head will be added at the end of the head tag
|
||||
* Elements that exist in the current head, but not in the new head will be removed from the head
|
||||
|
||||
If the htmx request is from a non-boosted element, then all content will be _appended_ to the existing head element.
|
||||
|
||||
If you wish to override this behavior in either case, you can place the `hx-head` attribute on the new `<head>` tag,
|
||||
with either of the following two values:
|
||||
|
||||
* `merge` - follow the merging algorithm outlined above
|
||||
* `append` - append the elements to the existing head
|
||||
|
||||
### Controlling Merge Behavior
|
||||
|
||||
Beyond this, you may also control merging behavior of individual elements with the following attributes:
|
||||
|
||||
* If you place `hx-head="re-eval"` on a head element, it will be re-added (removed and appended) to the head tag on every
|
||||
request, even if it already exists. This can be useful to execute a script on every htmx request, for example.
|
||||
* If you place `hx-preserve="true"` on an element, it will never be removed from the head
|
||||
|
||||
### Example
|
||||
|
||||
As an example, consider the following head tag in an existing document:
|
||||
|
||||
```html
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://the.missing.style">
|
||||
<link rel="stylesheet" href="/css/site1.css">
|
||||
<script src="/js/script1.js"></script>
|
||||
<script src="/js/script2.js"></script>
|
||||
</head>
|
||||
```
|
||||
|
||||
If htmx receives a request containing this new head tag:
|
||||
|
||||
```html
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://the.missing.style">
|
||||
<link rel="stylesheet" href="/css/site2.css">
|
||||
<script src="/js/script2.js"></script>
|
||||
<script src="/js/script3.js"></script>
|
||||
</head>
|
||||
```
|
||||
|
||||
Then the following operations will occur:
|
||||
|
||||
* `<link rel="stylesheet" href="https://the.missing.style">` will be left alone
|
||||
* `<link rel="stylesheet" href="/css/site1.css">` will be removed from the head
|
||||
* `<link rel="stylesheet" href="/css/site2.css">` will be added to the head
|
||||
* `<script src="/js/script1.js"></script>` will be removed from the head
|
||||
* `<script src="/js/script2.js"></script>` will be left alone
|
||||
* `<script src="/js/script3.js"></script>` will be added to the head
|
||||
|
||||
The final head element will look like this:
|
||||
|
||||
```html
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://the.missing.style">
|
||||
<script src="/js/script2.js"></script>
|
||||
<link rel="stylesheet" href="/css/site2.css">
|
||||
<script src="/js/script3.js"></script>
|
||||
</head>
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
This extension triggers the following events:
|
||||
|
||||
* `htmx:removingHeadElement` - triggered when a head element is about to be removed, with the element being removed
|
||||
available in `event.detail.headElement`. If `preventDefault()` is invoked on the event, the element will not be removed.
|
||||
* `htmx:addingHeadElement` - triggered when a head element is about to be added, with the element being added
|
||||
available in `event.detail.headElement`. If `preventDefault()` is invoked on the event, the element will not be added.
|
||||
* `htmx:afterHeadMerge` - triggered after a head tag merge has occurred, with the following values available in the event `detail`:
|
||||
* `added` - added head elements
|
||||
* `kept` - kept head elements
|
||||
* `removed` - removed head elements
|
||||
* `htmx:beforeHeadMerge` - triggered before a head merge occurs
|
@ -1,23 +0,0 @@
|
||||
+++
|
||||
title = "include-vals"
|
||||
+++
|
||||
|
||||
The `include-vals` extension allows you to programmatically include values in a request with
|
||||
a `include-vals` attribute. The value of this attribute is one or more name/value pairs, which
|
||||
will be evaluated as the fields in a javascript object literal.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/include-vals.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<div hx-ext="include-vals">
|
||||
<div hx-get="/test" include-vals="included:true, computed: computeValue()">
|
||||
Will Include Additional Values
|
||||
</div>
|
||||
</div>
|
||||
```
|
@ -1,17 +0,0 @@
|
||||
+++
|
||||
title = "json-enc"
|
||||
+++
|
||||
|
||||
This extension encodes parameters in JSON format instead of url format.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/json-enc.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<div hx-post='/test' hx-ext='json-enc'>click me</div>
|
||||
```
|
@ -1,136 +0,0 @@
|
||||
+++
|
||||
title = "loading-states"
|
||||
+++
|
||||
|
||||
This extension allows you to easily manage loading states while a request is in flight, including disabling elements, and adding and removing CSS classes.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/loading-states.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add the `hx-ext="loading-states"` attribute to the body tag or to any parent element containing your htmx attributes.
|
||||
|
||||
Add the following class to your stylesheet to make sure elements are hidden by default:
|
||||
|
||||
```css
|
||||
[data-loading] {
|
||||
display: none;
|
||||
}
|
||||
```
|
||||
|
||||
## Supported attributes
|
||||
|
||||
- `data-loading`
|
||||
|
||||
Shows the element. The default style is `inline-block`, but it's possible to use any display style by specifying it in the attribute value.
|
||||
|
||||
```html
|
||||
<div data-loading>loading</div>
|
||||
|
||||
<div data-loading="block">loading</div>
|
||||
|
||||
<div data-loading="flex">loading</div>
|
||||
```
|
||||
|
||||
- `data-loading-class`
|
||||
|
||||
Adds, then removes, CSS classes to the element:
|
||||
|
||||
```html
|
||||
<div class="transition-all ease-in-out duration-600" data-loading-class="bg-gray-100 opacity-80">
|
||||
...
|
||||
</div>
|
||||
```
|
||||
|
||||
- `data-loading-class-remove`
|
||||
|
||||
Removes, then adds back, CSS classes from the element.
|
||||
|
||||
```html
|
||||
<div class="p-8 bg-gray-100 transition-all ease-in-out duration-600" data-loading-class-remove="bg-gray-100">
|
||||
...
|
||||
</div>
|
||||
```
|
||||
- `data-loading-disable`
|
||||
|
||||
Disables an element for the duration of the request.
|
||||
|
||||
```html
|
||||
<button data-loading-disable>Submit</button>
|
||||
```
|
||||
|
||||
- `data-loading-aria-busy`
|
||||
|
||||
Add [`aria-busy="true"`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-busy) attribute to the element for the duration of the request
|
||||
|
||||
```html
|
||||
<button data-loading-aria-busy>Submit</button>
|
||||
```
|
||||
|
||||
- `data-loading-delay`
|
||||
|
||||
Some actions may update quickly and showing a loading state in these cases may be more of a distraction. This attribute ensures that the loading state changes are applied only after 200ms if the request is not finished. The default delay can be modified through the attribute value and expressed in milliseconds:
|
||||
|
||||
```html
|
||||
<button type="submit" data-loading-disable data-loading-delay="1000">Submit</button>
|
||||
```
|
||||
|
||||
You can place the `data-loading-delay` attribute directly on the element you want to disable, or in any parent element.
|
||||
|
||||
- `data-loading-target`
|
||||
|
||||
Allows setting a different target to apply the loading states. The attribute value can be any valid CSS selector. The example below disables the submit button and shows the loading state when the form is submitted.
|
||||
|
||||
```html
|
||||
<form hx-post="/save"
|
||||
data-loading-target="#loading"
|
||||
data-loading-class-remove="hidden">
|
||||
|
||||
<button type="submit" data-loading-disable>Submit</button>
|
||||
|
||||
</form>
|
||||
|
||||
<div id="loading" class="hidden">Loading ...</div>
|
||||
```
|
||||
|
||||
- `data-loading-path`
|
||||
|
||||
Allows filtering the processing of loading states only for specific requests based on the request path.
|
||||
|
||||
```html
|
||||
<form hx-post="/save">
|
||||
<button type="submit" data-loading-disable data-loading-path="/save">Submit</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
You can place the `data-loading-path` attribute directly on the loading state element, or in any parent element.
|
||||
|
||||
```html
|
||||
<form hx-post="/save" data-loading-path="/save">
|
||||
<button type="submit" data-loading-disable>Submit</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
- `data-loading-states`
|
||||
|
||||
This attribute is optional and it allows defining a scope for the loading states so only elements within that scope are processed.
|
||||
|
||||
```html
|
||||
<div data-loading-states>
|
||||
<div hx-get=""></div>
|
||||
<div data-loading>loading</div>
|
||||
</div>
|
||||
|
||||
<div data-loading-states>
|
||||
<div hx-get=""></div>
|
||||
<div data-loading>loading</div>
|
||||
</div>
|
||||
|
||||
<form data-loading-states hx-post="">
|
||||
<div data-loading>loading</div>
|
||||
</form>
|
||||
```
|
@ -1,22 +0,0 @@
|
||||
+++
|
||||
title = "method-override"
|
||||
+++
|
||||
|
||||
This extension makes non-`GET` and `POST` requests use a `POST` with the `X-HTTP-Method-Override` header set to the
|
||||
actual HTTP method. This is necessary when dealing with some firewall or proxy situations.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/method-override.js"></script>
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```html
|
||||
<body hx-ext="method-override">
|
||||
<button hx-put="/update">
|
||||
This request will be made as a POST w/ the X-HTTP-Method-Override Header Set
|
||||
</button>
|
||||
</body>
|
||||
```
|
@ -1,25 +0,0 @@
|
||||
+++
|
||||
title = "morphdom-swap"
|
||||
+++
|
||||
|
||||
This extension allows you to use the [morphdom](https://github.com/patrick-steele-idem/morphdom) library as the
|
||||
swapping mechanism in htmx.
|
||||
|
||||
The `morphdom` library does not support morph element to multiple elements. If the result of `hx-select` is more than one element, it will pick the first one.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/morphdom-swap.js"></script>
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```html
|
||||
<header>
|
||||
<script src="lib/morphdom-umd.js"></script> <!-- include the morphdom library -->
|
||||
</header>
|
||||
<body hx-ext="morphdom-swap">
|
||||
<button hx-swap="morphdom">This button will be swapped with morphdom!</button>
|
||||
</body>
|
||||
```
|
@ -1,69 +0,0 @@
|
||||
+++
|
||||
title = "multi-swap"
|
||||
+++
|
||||
|
||||
This extension allows you to swap multiple elements marked with the `id` attribute from the HTML response. You can also choose for each element which [swap method](@/docs.md#swapping) should be used.
|
||||
|
||||
Multi-swap can help in cases where OOB ([Out of Band Swaps](@/docs.md#oob_swaps)) is not enough for you. OOB requires HTML tags marked with `hx-swap-oob` attributes to be at the TOP level of HTML, which significantly limited its use. With OOB, it's impossible to swap multiple elements arbitrarily placed and nested in the DOM tree.
|
||||
|
||||
It is a very powerful tool in conjunction with `hx-boost` and `preload` extension.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/multi-swap.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
1. Set `hx-ext="multi-swap"` attribute on `<body>`, on some parent element, or on each action element that should trigger an action (typically anchors or buttons).
|
||||
2. On your action elements set `hx-swap="multi:ID-SELECTORS"`, e.g. `hx-swap="multi:#id1,#id2:outerHTML,#id3:afterend"`.
|
||||
3. If you're not using e.g. `hx-get` to enable HTMX behavior, set `hx-boost="true"` on your action elements, or on some parent element, so that all elements inherit the hx-boost setting.
|
||||
|
||||
Selectors must be separated by a comma (without surrounding spaces) and a colon with the desired swap method can optionally be placed after the selector. Default swap method is `innerHTML`.
|
||||
|
||||
```html
|
||||
<body hx-boost="true" hx-ext="multi-swap">
|
||||
<!-- simple example how to swap #id1 and #id2 from /example by innerHTML (default swap method) -->
|
||||
<button hx-get="/example" hx-swap="multi:#id1,#id2">Click to swap #id1 and #id2 content</button>
|
||||
|
||||
<!-- advanced example how to swap multiple elements from /example by different swap methods -->
|
||||
<a href="/example" hx-swap="multi:#id1,#id2:outerHTML,#id3:beforeend,#id4:delete">Click to swap #id1 and #id2, extend #id3 content and delete #id4 element</a>
|
||||
|
||||
<div id="id1">Old 1 content</div>
|
||||
<div id="id2">Old 2 content</div>
|
||||
<div id="id3">Old 3 content</div>
|
||||
<div id="id4">Old 4 content</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
**Real world example with preloading**
|
||||
|
||||
The use case below shows how to ensure that only the `#submenu` and `#content` elements are redrawn when the main menu items are clicked. Thanks to the combination with the preload extension, the page, including its images, is preloaded on `mouseover` event.
|
||||
|
||||
```html
|
||||
<head>
|
||||
<script src="/path/to/htmx.js"></script>
|
||||
<script src="/path/to/ext/multi-swap.js"></script>
|
||||
<script src="/path/to/ext/preload.js"></script>
|
||||
</head>
|
||||
<body hx-ext="multi-swap,preload">
|
||||
<header>...</header>
|
||||
<menu hx-boost="true">
|
||||
<ul>
|
||||
<li><a href="/page-1" hx-swap="multi:#submenu,#content" preload="mouseover" preload-images="true">Page 1</a></li>
|
||||
<li><a href="/page-2" hx-swap="multi:#submenu,#content" preload="mouseover" preload-images="true">Page 2</a></li>
|
||||
</ul>
|
||||
<div id="submenu">... submenu contains items by selected top-level menu ...</div>
|
||||
<menu>
|
||||
<main id="content">...</div>
|
||||
<footer>...</footer>
|
||||
</body>
|
||||
```
|
||||
|
||||
|
||||
### Notes and limitations
|
||||
|
||||
* Attribute `hx-swap` value **must not contain spaces**, otherwise only the part of the value up to the first space will be accepted.
|
||||
* If the `delete` swap method is used, the HTML response must also contain deleted element (it can be empty div with `id` attribute).
|
||||
* Only elements with an `id` selector are supported, as the function internally uses OOB internal method. So it is not possible to use `class` or any other selectors.
|
@ -1,60 +0,0 @@
|
||||
+++
|
||||
title = "path-deps"
|
||||
+++
|
||||
|
||||
This extension supports expressing inter-element dependencies based on paths, inspired by the
|
||||
[intercooler.js dependencies mechanism](http://intercoolerjs.org/docs.html#dependencies). When this
|
||||
extension is installed an element can express a dependency on another path by using the `path-deps` property
|
||||
and then setting `hx-trigger` to `path-deps`:
|
||||
|
||||
```html
|
||||
<div hx-get="/example"
|
||||
hx-trigger="path-deps"
|
||||
path-deps="/foo/bar">...</div>
|
||||
```
|
||||
|
||||
This div will fire a `GET` request to `/example` when any other element issues a mutating request (that is, a non-`GET`
|
||||
request like a `POST`) to `/foo/bar` or any sub-paths of that path.
|
||||
|
||||
You can use a `*` to match any path component:
|
||||
|
||||
```html
|
||||
<div hx-get="/example"
|
||||
hx-trigger="path-deps"
|
||||
path-deps="/contacts/*">...</div>
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/path-deps.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<div hx-ext='path-deps'>
|
||||
<ul hx-get="/list" hx-trigger="path-deps" path-deps="/list">
|
||||
</ul>
|
||||
<button hx-post="/list">
|
||||
Post To List
|
||||
</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Javascript API
|
||||
|
||||
#### Method - `PathDeps.refresh()` {#refresh}
|
||||
|
||||
This method manually triggers a refresh for the given path.
|
||||
|
||||
##### Parameters
|
||||
|
||||
* `path` - the path to refresh
|
||||
|
||||
##### Example
|
||||
|
||||
```js
|
||||
// Trigger a refresh on all elements with the path-deps attribute '/path/to/refresh', including elements with a parent path, e.g. '/path'
|
||||
PathDeps.refresh('/path/to/refresh');
|
||||
```
|
@ -1,21 +0,0 @@
|
||||
+++
|
||||
title = "path-params"
|
||||
+++
|
||||
|
||||
This extension uses request parameters to populate path variables. Used parameters are removed so they won't be sent in the query string or body anymore.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/path-params.js">
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
This would invoke URL `/items/42?foo=bar`
|
||||
|
||||
```html
|
||||
<div hx-ext="path-params">
|
||||
<a hx-get="/items/{itemId}" hx-vals='{"itemId": "42", "foo": "bar"}'>test</div>
|
||||
</div>
|
||||
```
|
@ -1,104 +0,0 @@
|
||||
+++
|
||||
title = "preload"
|
||||
+++
|
||||
|
||||
The `preload` extension allows you to load HTML fragments into your browser's cache before they are requested by the user, so that additional pages appear to users to load nearly instantaneously. As a developer, you can customize its behavior to fit your applications needs and use cases.
|
||||
|
||||
**IMPORTANT:** Preloading content judiciously can improve your web application's perceived performance, but preloading too many resources can negatively impact your visitors' bandwidth and your server performance by initiating too many unused requests. Use this extension carefully!
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/preload.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Register the extension with htmx using the `hx-ext` attribute. Then, add a `preload` attribute to any hyperlinks and `hx-get` elements you want to preload. By default, resources will be loaded as soon as the `mousedown` event begins, giving your application a roughly 100-200ms head start on serving responses. See configuration below for other options.
|
||||
|
||||
```html
|
||||
<body hx-ext="preload">
|
||||
<h1>What Works</h2>
|
||||
<a href="/server/1" preload>WILL BE requested using a standard XMLHttpRequest() and default options (below)</a>
|
||||
<button hx-get="/server/2" preload>WILL BE requested with additional htmx headers.</button>
|
||||
|
||||
<h1>What WILL NOT WORK</h1>
|
||||
<a href="/server/3">WILL NOT be preloaded because it does not have an explicit "preload" attribute</a>
|
||||
<a hx-post="/server/4" preload>WILL NOT be preloaded because it is an HX-POST transaction.</a>
|
||||
</body>
|
||||
```
|
||||
|
||||
### Inheriting Preload Settings
|
||||
|
||||
You can add the `preload` attribute to the top-level element that contains several `<a href="">` or `hx-get=""` elements, and all of them will be preloaded. Be careful with this setting, because you can end up wasting bandwidth if you preload many more resources than you need.
|
||||
|
||||
```html
|
||||
<body hx-ext="preload">
|
||||
<ul preload>
|
||||
<li><a href="/server/1">This will be preloaded because of the attribute in the node above.</a>
|
||||
<li><a href="/server/2">This will also be preloaded for the same reason.</a>
|
||||
<li><a href="/server/3">This will be preloaded, too. Lorem ipsum.</a>
|
||||
</ul>
|
||||
</body>
|
||||
```
|
||||
|
||||
### Preloading of Linked Images
|
||||
|
||||
After an HTML page (or page fragment) is preloaded, this extension can also preload linked image resources. It will not load or run linked Javascript or Cascading Stylesheet content, whether linked or embedded in the preloaded HTML. To preload images as well, use the following syntax.
|
||||
|
||||
```html
|
||||
<div hx-ext="preload">
|
||||
<a href="/my-next-page" preload="mouseover" preload-images="true">Next Page</a>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
Defaults for this extension are chosen to balance users' perceived performance with potential load on your servers from unused requests. As a developer, you can modify two settings to customize this behavior to your specific use cases.
|
||||
|
||||
#### preload="mousedown" (DEFAULT)
|
||||
|
||||
The default behavior for this extension is to begin loading a resource when the user presses the mouse down. This is a conservative setting that guarantees the user actually intends to use the linked resource. Because user click events typically take 100-200ms to complete, this setting gives your server a significant headstart compared with a regular click.
|
||||
|
||||
```html
|
||||
<a href="/server/1" preload="mousedown">This will be preloaded when the user begins to click.</a>
|
||||
```
|
||||
|
||||
#### preload="mouseover"
|
||||
|
||||
To preload links more aggressively, you can trigger the preload to happen when the user's mouse hovers over the link instead. To prevent many resources from being loaded when the user scrolls or moves the mouse across a large list of objects, a 100ms delay is built in to this action. If the user's mouse leaves the element *before* this timeout expires, then the resource is not preloaded.
|
||||
|
||||
Typical users hover over links for several hundred milliseconds before they click, which gives your server even more time to respond to the request than the `mousedown` option above. [Test your own hover timing here.](http://instantclick.io/click-test). However, be careful when using this option because it can increase server load by requesting resources unnecessarily.
|
||||
|
||||
```html
|
||||
<a href="/server/1" preload="mouseover">This will be preloaded when the user's mouse remains over it for more than 100ms.</a>
|
||||
```
|
||||
|
||||
#### preload="custom-event-name"
|
||||
|
||||
Preload can also listen to any custom event within the system, triggering resources to be preloaded (if they have not already been cached by the browser). The extension itself generates an event called `preload:init` that can be used to trigger preloads as soon as an object has been processed by htmx.
|
||||
|
||||
```html
|
||||
<body hx-ext="preload">
|
||||
<button hx-get="/server" preload="preload:init" hx-target="idLoadMore">Load More</a>
|
||||
<div id="idLoadMore">
|
||||
Content for this DIV will be preloaded as soon as the page is ready.
|
||||
Clicking the button above will swap it into the DOM.
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
### About Touch Events
|
||||
|
||||
To accommodate touchscreen devices, an additional `ontouchstart` event handler is added whenever you specify a `mouseover` or `mousedown` trigger. This extra trigger fires immediately (no waiting period) whenever the user touches the screen, saving you 300ms of waiting time on Android, and 450ms on iOS.
|
||||
|
||||
### Limitations
|
||||
|
||||
* Links must be marked with a `preload` attribute, or have an ancestor node that has the `preload` attribute.
|
||||
* Only `GET` transactions (including `<a href="">` and `hx-get=""`) can be preloaded. Following REST principles, `GET` transactions are assumed to not make any significant changes to a resource. Transactions that can potentially make a change (such as `POST`, `PUT`, and `DELETE`) will not be preloaded under any circumstances.
|
||||
* When listening to `mouseover` events, preload waits for 100ms before downloading the linked resource. If the mouse leaves the resource before this timeout expires, the resource is not preloaded.
|
||||
* Preloaded responses will only be cached in the browser if the response headers allow it. For example, the response header `Cache-Control: private, max-age=60` allows the browser to cache the response, whereas `Cache-Control: no-cache` prevents it.
|
||||
|
||||
## Credits
|
||||
|
||||
The behavior for this plugin was inspired by the work done by [Alexandre Dieulot](https://github.com/dieulot) on [InstantClick](http://instantclick.io/), which is released under the MIT license.
|
@ -1,20 +0,0 @@
|
||||
+++
|
||||
title = "remove-me"
|
||||
+++
|
||||
|
||||
The `remove-me` extension allows you to remove an element after a specified interval.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/remove-me.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<div hx-ext="remove-me">
|
||||
<!-- Removes this div after 1 second -->
|
||||
<div remove-me="1s">To Be Removed...</div>
|
||||
</div>
|
||||
```
|
@ -1,141 +0,0 @@
|
||||
+++
|
||||
title = "response-targets"
|
||||
+++
|
||||
|
||||
This extension allows you to specify different target elements to be swapped when
|
||||
different HTTP response codes are received.
|
||||
|
||||
It uses attribute names in a form of ``hx-target-[CODE]`` where `[CODE]` is a numeric
|
||||
HTTP response code with the optional wildcard character at its end. You can also use
|
||||
`hx-target-error`, which handles both 4xx and 5xx response codes.
|
||||
|
||||
The value of each attribute can be:
|
||||
|
||||
* A CSS query selector of the element to target.
|
||||
* `this` which indicates that the element that the `hx-target` attribute is on is the target.
|
||||
* `closest <CSS selector>` which will find the closest parent ancestor that matches the given CSS selector
|
||||
(e.g. `closest tr` will target the closest table row to the element).
|
||||
* `find <CSS selector>` which will find the first child descendant element that matches the given CSS selector.
|
||||
* `next <CSS selector>` which will scan the DOM forward for the first element that matches the given CSS selector.
|
||||
(e.g. `next .error` will target the closest following sibling element with `error` class)
|
||||
* `previous <CSS selector>` which will scan the DOM backwards for the first element that matches the given CSS selector.
|
||||
(e.g `previous .error` will target the closest previous sibling with `error` class)
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/response-targets.js"></script>
|
||||
```
|
||||
|
||||
## Configure (optional)
|
||||
|
||||
* When `HX-Retarget` response header is received it disables any lookup that would be
|
||||
performed by this extension but any responses with error status codes will be
|
||||
swapped (normally they would not be, even with target set via header) and internal
|
||||
error flag (`isError`) will be modified. You may change this and choose to ignore
|
||||
`HX-Retarget` header when `hx-target-…` is in place by setting a configuration flag
|
||||
`htmx.config.responseTargetPrefersRetargetHeader` to `false` (default is
|
||||
`true`). Note that this extension only performs a simple check whether the header
|
||||
is set and target exists. It is not extracting target's value from the header but
|
||||
trusts it was set by HTMX core logic.
|
||||
|
||||
* Normally, any target which is already established by HTMX built-in functions or
|
||||
extensions called before will be overwritten if a matching `hx-target-…` tag is
|
||||
found. You may change it by using a configuration flag
|
||||
`htmx.config.responseTargetPrefersExisting` to `true` (default is `false`). This is
|
||||
kinky and risky option. It has a real-life applications similar to a skilled,
|
||||
full-stack tardigrade eating parentheses when no one is watching.
|
||||
|
||||
* `isError` flag on the `detail` member of an event associated with swapping the
|
||||
content with `hx-target-[CODE]` will be set to `false` when error response code is
|
||||
received. This is different from the default behavior. You may change this by
|
||||
setting a configuration flag `htmx.config.responseTargetUnsetsError` to `false`
|
||||
(default is `true`).
|
||||
|
||||
* `isError` flag on the `detail` member of an event associated with swapping the
|
||||
content with `hx-target-[CODE]` will be set to `false` when non-erroneous response
|
||||
code is received. This is no different from the default behavior. You may change
|
||||
this by setting a configuration flag `htmx.config.responseTargetSetsError` to
|
||||
`true` (default is `false`). This setting will not affect the response code 200
|
||||
since it is not handled by this extension.
|
||||
|
||||
## Usage
|
||||
|
||||
Here is an example that targets a `div` for normal (200) response but another `div`
|
||||
for 404 (not found) response, and yet another for all 5xx response codes:
|
||||
|
||||
```html
|
||||
<div hx-ext="response-targets">
|
||||
<div id="response-div"></div>
|
||||
<button hx-post="/register"
|
||||
hx-target="#response-div"
|
||||
hx-target-5*="#serious-errors"
|
||||
hx-target-404="#not-found">
|
||||
Register!
|
||||
</button>
|
||||
<div id="serious-errors"></div>
|
||||
<div id="not-found"></div>
|
||||
</div>
|
||||
```
|
||||
|
||||
* The response from the `/register` URL will replace contents of the `div` with the
|
||||
`id` `response-div` when response code is 200 (OK).
|
||||
|
||||
* The response from the `/register` URL will replace contents of the `div` with the `id`
|
||||
`serious-errors` when response code begins with a digit 5 (server errors).
|
||||
|
||||
* The response from the `/register` URL will replace contents of the `div` with
|
||||
the `id` `not-found` when response code is 404 (Not Found).
|
||||
|
||||
Sometimes you may not want to handle 5xx and 4xx errors separately, in which case you
|
||||
can use `hx-target-error`:
|
||||
|
||||
```html
|
||||
<div hx-ext="response-targets">
|
||||
<div id="response-div"></div>
|
||||
<button hx-post="/register"
|
||||
hx-target="#response-div"
|
||||
hx-target-error="#any-errors">
|
||||
Register!
|
||||
</button>
|
||||
<div id="any-errors"></div>
|
||||
</div>
|
||||
```
|
||||
|
||||
2xx codes will be handled as in the previous example. However, when the response code is 5xx
|
||||
or 4xx, the response from `/register` will replace the contents of the `div` with the `id`
|
||||
`any-errors`.
|
||||
|
||||
## Wildcard resolution
|
||||
|
||||
When status response code does not match existing `hx-target-[CODE]` attribute name
|
||||
then its numeric part expressed as a string is trimmed with last character being
|
||||
replaced with the asterisk (`*`). This lookup process continues until the attribute
|
||||
is found or there are no more digits.
|
||||
|
||||
For example, if a browser receives 404 error code, the following attribute names will
|
||||
be looked up (in the given order):
|
||||
|
||||
* `hx-target-404`
|
||||
* `hx-target-40*`
|
||||
* `hx-target-4*`
|
||||
* `hx-target-*`.
|
||||
|
||||
|
||||
_If you are using tools that do not support asterisks in HTML attributes, you
|
||||
may instead use the `x` character, e.g., `hx-target-4xx`._
|
||||
|
||||
## Notes
|
||||
|
||||
* `hx-target-…` is inherited and can be placed on a parent element.
|
||||
* `hx-target-…` cannot be used to handle HTTP response code 200.
|
||||
* `hx-target-…` will honor `HX-Retarget` by default and will prefer it over any
|
||||
calculated target but it can be changed by disabling the
|
||||
`htmx.config.responseTargetPrefersRetargetHeader` configuration option.
|
||||
* To avoid surprises the `hx-ext` attribute used to enable this extension should be
|
||||
placed on a parent element containing elements with `hx-target-…` and `hx-target`
|
||||
attributes.
|
||||
|
||||
## See also
|
||||
|
||||
* [`hx-target`](@/attributes/hx-target.md), specifies the target element to be swapped
|
@ -1,20 +0,0 @@
|
||||
+++
|
||||
title = "restored"
|
||||
+++
|
||||
|
||||
This extension triggers an event ``restored`` whenever a back button even is detected while using ``hx-boost``.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/restored.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
A page utilizing ``hx-boost`` that will reload the ``h1`` each time the back button is pressed:
|
||||
```html
|
||||
<body hx-boost="true">
|
||||
<h1 hx-ext="restored" hx-trigger="restored" hx-get="/header">Come back!</h1>
|
||||
<a href="/other_page">I'll be back</a>
|
||||
</body>
|
||||
```
|
@ -1,124 +0,0 @@
|
||||
+++
|
||||
title = "server-sent-events"
|
||||
+++
|
||||
|
||||
The `Server Sent Events` connects to an [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) directly from HTML. It manages the connections to your web server, listens for server events, and then swaps their contents into your htmx webpage in real-time.
|
||||
|
||||
SSE is a lightweight alternative to WebSockets that works over existing HTTP connections, so it is easy to use through proxy servers and firewalls. Remember, SSE is a uni-directional service, so you cannot send any messages to an SSE server once the connection has been established. If you need bi-directional communication, then you should consider using [WebSockets](@/extensions/web-sockets.md) instead.
|
||||
|
||||
This extension replaces the experimental `hx-sse` attribute built into previous versions of htmx. For help migrating from older versions, see the migration guide at the bottom of this page.
|
||||
|
||||
Use the following attributes to configure how SSE connections behave:
|
||||
|
||||
* `sse-connect="<url>"` - The URL of the SSE server.
|
||||
* `sse-swap="<message-name>"` - The name of the message to swap into the DOM.
|
||||
* `hx-swap` - You can control the swap strategy by using the [hx-swap](@/attributes/hx-swap.md) attribute, though note that modifiers like `scroll` are not supported.
|
||||
* `hx-trigger="sse:<message-name>"` - SSE messages can also trigger HTTP callbacks using the [`hx-trigger`](@/attributes/hx-trigger.md) attribute.
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/sse.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<div hx-ext="sse" sse-connect="/chatroom" sse-swap="message">
|
||||
Contents of this box will be updated in real time
|
||||
with every SSE message received from the chatroom.
|
||||
</div>
|
||||
```
|
||||
|
||||
### Connecting to an SSE Server
|
||||
|
||||
To connect to an SSE server, use the `hx-ext="sse"` attribute to install the extension on that HTML element, then add `sse-connect="<url>"` to the element to make the connection.
|
||||
|
||||
When designing your server application, remember that SSE works just like any HTTP request. Although you cannot send any messages to the server after you have established a connection, you can send parameters to the server along with your request. So, instead of making an SSE connection to your server at `https://my-server/chat-updates` you can also connect to `https://my-server/chat-updates?friends=true&format=detailed`. This allows your server to customize its responses to what your client needs.
|
||||
|
||||
### Receiving Named Events
|
||||
|
||||
SSE messages consist of an event name and a data packet. No other metadata is allowed in the message. Here is an example:
|
||||
|
||||
```txt
|
||||
event: EventName
|
||||
data: <div>Content to swap into your HTML page.</div>
|
||||
```
|
||||
|
||||
We'll use the `sse-swap` attribute to listen for this event and swap its contents into our webpage.
|
||||
|
||||
```html
|
||||
<div hx-ext="sse" sse-connect="/event-source" sse-swap="EventName"></div>
|
||||
```
|
||||
|
||||
Notice that the name `EventName` from the server's message must match the value in the `sse-swap` attribute. Your server can use as many different event names as necessary, but be careful: browsers can only listen for events that have been explicitly named. So, if your server sends an event named `ChatroomUpdate` but your browser is only listening for events named `ChatUpdate` then the extra event will be discarded.
|
||||
|
||||
### Receiving Unnamed Events
|
||||
|
||||
SSE messages can also be sent without any event name. In this case, the browser uses the default name `message` in its place. The same rules specified above still apply. If your server sends an unnamed message, then you must listen for it by including `sse-swap="message"`. There is no option for using a catch-all name. Here's how this looks:
|
||||
|
||||
```txt
|
||||
data: <div>Content to swap into your HTML page.</div>
|
||||
```
|
||||
|
||||
```html
|
||||
<div hx-ext="sse" sse-connect="/event-source" sse-swap="message"></div>
|
||||
```
|
||||
|
||||
### Receiving Multiple Events
|
||||
|
||||
You can also listen to multiple events (named or unnamed) from a single EventSource. Listeners must be either 1) the same element that contains the `hx-ext` and `sse-connect` attributes, or 2) child elements of the element containing the `hx-ext` and `sse-connect` attributes.
|
||||
|
||||
```html
|
||||
|
||||
Multiple events in the same element
|
||||
<div hx-ext="sse" sse-connect="/server-url" sse-swap="event1,event2"></div>
|
||||
|
||||
Multiple events in different elements (from the same source).
|
||||
<div hx-ext="sse" sse-connect="/server-url">
|
||||
<div sse-swap="event1"></div>
|
||||
<div sse-swap="event2"></div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Trigger Server Callbacks
|
||||
|
||||
When a connection for server sent events has been established, child elements can listen for these events by using the special [`hx-trigger`](@/attributes/hx-trigger.md) syntax `sse:<event_name>`. This, when combined with an `hx-get` or similar will trigger the element to make a request.
|
||||
|
||||
Here is an example:
|
||||
|
||||
```html
|
||||
<div hx-ext="sse" sse-connect="/event_stream">
|
||||
<div hx-get="/chatroom" hx-trigger="sse:chatter">
|
||||
...
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
This example establishes an SSE connection to the `event_stream` end point which then triggers
|
||||
a `GET` to the `/chatroom` url whenever the `chatter` event is seen.
|
||||
|
||||
### Automatic Reconnection
|
||||
|
||||
If the SSE Event Stream is closed unexpectedly, browsers are supposed to attempt to reconnect automatically. However, in rare situations this does not work and your browser can be left hanging. This extension adds its own reconnection logic (using an [exponential-backoff algorithm](https://en.wikipedia.org/wiki/Exponential_backoff)) on top of the browser's automatic reconnection, so that your SSE streams will always be as reliable as possible.
|
||||
|
||||
### Testing SSE Connections with the Demo Server
|
||||
|
||||
Htmx includes a demo SSE server written in Node.js that will help you to see SSE in action, and begin bootstrapping your own SSE code. It is located in the /test/ws-sse folder of the htmx distribution. Look at /test/ws-sse/README.md for instructions on running and using the test server.
|
||||
|
||||
### Migrating from Previous Versions
|
||||
|
||||
Previous versions of htmx used a built-in tag `hx-sse` to implement Server Sent Events. This code has been migrated into an extension instead. Here are the steps you need to take to migrate to this version:
|
||||
|
||||
| Old Attribute | New Attribute | Comments |
|
||||
|--------------------------------|--------------------------|------------------|
|
||||
| `hx-sse=""` | `hx-ext="sse"` | Use the `hx-ext="sse"` attribute to install the SSE extension into any HTML element. |
|
||||
| `hx-sse="connect:<url>"` | `sse-connect="<url>"` | Add a new attribute `sse-connect` to the tag that specifies the URL of the Event Stream. This attribute must be in the same tag as the `hx-ext` attribute. |
|
||||
| `hx-sse="swap:<EventName>"` | `sse-swap="<EventName>"` | Add a new attribute `sse-swap` to any elements that will be swapped in via the SSE extension. This attribute must be placed **on** or **inside of** the tag containing the `hx-ext` attribute. |
|
||||
| `hx-trigger="sse:<EventName>"` | NO CHANGE | any `hx-trigger` attributes do not need to change. The extension will identify these attributes and add listeners for any events prefixed with `sse:` |
|
||||
|
||||
### Additional SSE Resources
|
||||
|
||||
* [Wikipedia](https://en.wikipedia.org/wiki/Server-sent_events)
|
||||
* [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)
|
||||
* [Can I Use?](https://caniuse.com/eventsource)
|
@ -1,253 +0,0 @@
|
||||
+++
|
||||
title = "websockets"
|
||||
+++
|
||||
|
||||
The `WebSockets` extension enables easy, bi-directional communication
|
||||
with [Web Sockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications)
|
||||
servers directly from HTML. This replaces the experimental `hx-ws` attribute built into previous versions of htmx. For
|
||||
help migrating from older versions, see the [Migrating](#migrating-from-previous-versions) guide at the bottom of this page.
|
||||
|
||||
Use the following attributes to configure how WebSockets behave:
|
||||
|
||||
* `ws-connect="<url>"` or `ws-connect="<prefix>:<url>"` - A URL to establish an `WebSocket` connection against.
|
||||
* Prefixes `ws` or `wss` can optionally be specified. If not specified, HTMX defaults to add the location's scheme-type,
|
||||
host and port to have browsers send cookies via websockets.
|
||||
* `ws-send` - Sends a message to the nearest websocket based on the trigger value for the element (either the natural
|
||||
event
|
||||
or the event specified by [`hx-trigger`])
|
||||
|
||||
## Install
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11/dist/ext/ws.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
|
||||
<div hx-ext="ws" ws-connect="/chatroom">
|
||||
<div id="notifications"></div>
|
||||
<div id="chat_room">
|
||||
...
|
||||
</div>
|
||||
<form id="form" ws-send>
|
||||
<input name="chat_message">
|
||||
</form>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
WebSockets extension support two configuration options:
|
||||
|
||||
- `createWebSocket` - a factory function that can be used to create a custom WebSocket instances. Must be a function,
|
||||
returning `WebSocket` object
|
||||
- `wsBinaryType` - a string value, that defines
|
||||
socket's [`binaryType`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/binaryType) property. Default value
|
||||
is `blob`
|
||||
|
||||
### Receiving Messages from a WebSocket
|
||||
|
||||
The example above establishes a WebSocket to the `/chatroom` end point. Content that is sent down from the websocket
|
||||
will
|
||||
be parsed as HTML and swapped in by the `id` property, using the same logic
|
||||
as [Out of Band Swaps](@/attributes/hx-swap-oob.md).
|
||||
|
||||
As such, if you want to change the swapping method (e.g., append content at the end of an element or delegate swapping
|
||||
to an extension),
|
||||
you need to specify that in the message body, sent by the server.
|
||||
|
||||
```html
|
||||
<!-- will be interpreted as hx-swap-oob="true" by default -->
|
||||
<form id="form">
|
||||
...
|
||||
</form>
|
||||
<!-- will be appended to #notifications div -->
|
||||
<div id="notifications" hx-swap-oob="beforeend">
|
||||
New message received
|
||||
</div>
|
||||
<!-- will be swapped using an extension -->
|
||||
<div id="chat_room" hx-swap-oob="morphdom">
|
||||
....
|
||||
</div>
|
||||
```
|
||||
|
||||
### Sending Messages to a WebSocket
|
||||
|
||||
In the example above, the form uses the `ws-send` attribute to indicate that when it is submitted, the form values
|
||||
should be **serialized as JSON**
|
||||
and send to the nearest enclosing `WebSocket`, in this case the `/chatroom` endpoint.
|
||||
|
||||
The serialized values will include a field, `HEADERS`, that includes the headers normally submitted with an htmx
|
||||
request.
|
||||
|
||||
### Automatic Reconnection
|
||||
|
||||
If the WebSocket is closed unexpectedly, due to `Abnormal Closure`, `Service Restart` or `Try Again Later`, this
|
||||
extension will attempt to reconnect until the connection is reestablished.
|
||||
|
||||
By default, the extension uses a
|
||||
full-jitter [exponential-backoff algorithm](https://en.wikipedia.org/wiki/Exponential_backoff) that chooses a randomized
|
||||
retry delay that grows exponentially over time. You can use a different algorithm by writing it
|
||||
into `htmx.config.wsReconnectDelay`. This function takes a single parameter, the number of retries, and returns the
|
||||
time (in milliseconds) to wait before trying again.
|
||||
|
||||
```javascript
|
||||
// example reconnect delay that you shouldn't use because
|
||||
// it's not as good as the algorithm that's already in place
|
||||
htmx.config.wsReconnectDelay = function (retryCount) {
|
||||
return retryCount * 1000 // return value in milliseconds
|
||||
}
|
||||
```
|
||||
|
||||
The extension also implements a simple queuing mechanism that keeps messages in memory when the socket is not in `OPEN`
|
||||
state and sends them once the connection is restored.
|
||||
|
||||
### Events
|
||||
|
||||
WebSockets extensions exposes a set of events that allow you to observe and customize its behavior.
|
||||
|
||||
#### Event - `htmx:wsConnecting` {#htmx:wsConnecting}
|
||||
|
||||
This event is triggered when a connection to a WebSocket endpoint is being attempted.
|
||||
|
||||
##### Details
|
||||
|
||||
* `detail.event.type` - the type of the event (`'connecting'`)
|
||||
|
||||
#### Event - `htmx:wsOpen` {#htmx:wsOpen}
|
||||
|
||||
This event is triggered when a connection to a WebSocket endpoint has been established.
|
||||
|
||||
##### Details
|
||||
|
||||
* `detail.elt` - the element that holds the socket (the one with `ws-connect` attribute)
|
||||
* `detail.event` - the original event from the socket
|
||||
* `detail.socketWrapper` - the wrapper around socket object
|
||||
|
||||
#### Event - `htmx:wsClose` {#htmx:wsClose}
|
||||
|
||||
This event is triggered when a connection to a WebSocket endpoint has been closed normally.
|
||||
You can check if the event was caused by an error by inspecting `detail.event` property.
|
||||
|
||||
##### Details
|
||||
|
||||
* `detail.elt` - the element that holds the socket (the one with `ws-connect` attribute)
|
||||
* `detail.event` - the original event from the socket
|
||||
* `detail.socketWrapper` - the wrapper around socket object
|
||||
|
||||
#### Event - `htmx:wsError` {#htmx:wsError}
|
||||
|
||||
This event is triggered when `onerror` event on a socket is raised.
|
||||
|
||||
##### Details
|
||||
|
||||
* `detail.elt` - the element that holds the socket (the one with `ws-connect` attribute)
|
||||
* `detail.error` - the error object
|
||||
* `detail.socketWrapper` - the wrapper around socket object
|
||||
|
||||
#### Event - `htmx:wsBeforeMessage` {#htmx:wsBeforeMessage}
|
||||
|
||||
This event is triggered when a message has just been received by a socket, similar to `htmx:beforeOnLoad`. This event
|
||||
fires
|
||||
before any processing occurs.
|
||||
|
||||
If the event is cancelled, no further processing will occur.
|
||||
|
||||
* `detail.elt` - the element that holds the socket (the one with `ws-connect` attribute)
|
||||
* `detail.message` - raw message content
|
||||
* `detail.socketWrapper` - the wrapper around socket object
|
||||
|
||||
#### Event - `htmx:wsAfterMessage` {#htmx:wsAfterMessage}
|
||||
|
||||
This event is triggered when a message has been completely processed by htmx and all changes have been
|
||||
settled, similar to `htmx:afterOnLoad`.
|
||||
|
||||
Cancelling this event has no effect.
|
||||
|
||||
* `detail.elt` - the element that holds the socket (the one with `ws-connect` attribute)
|
||||
* `detail.message` - raw message content
|
||||
* `detail.socketWrapper` - the wrapper around socket object
|
||||
|
||||
#### Event - `htmx:wsConfigSend` {#htmx:wsConfigSend}
|
||||
|
||||
This event is triggered when preparing to send a message from `ws-send` element.
|
||||
Similarly to [`htmx:configRequest`](@/events.md#htmx:configRequest), it allows you to modify the message
|
||||
before sending.
|
||||
|
||||
If the event is cancelled, no further processing will occur and no messages will be sent.
|
||||
|
||||
##### Details
|
||||
|
||||
* `detail.parameters` - the parameters that will be submitted in the request
|
||||
* `detail.unfilteredParameters` - the parameters that were found before filtering
|
||||
by [`hx-select`](@/attributes/hx-select.md)
|
||||
* `detail.headers` - the request headers. Will be attached to the body in `HEADERS` property, if not falsy
|
||||
* `detail.errors` - validation errors. Will prevent sending and
|
||||
trigger [`htmx:validation:halted`](@/events.md#htmx:validation:halted) event if not empty
|
||||
* `detail.triggeringEvent` - the event that triggered sending
|
||||
* `detail.messageBody` - raw message body that will be sent to the socket. Undefined, can be set to value of any type,
|
||||
supported by WebSockets. If set, will override
|
||||
default JSON serialization. Useful, if you want to use some other format, like XML or MessagePack
|
||||
* `detail.elt` - the element that dispatched the sending (the one with `ws-send` attribute)
|
||||
* `detail.socketWrapper` - the wrapper around socket object
|
||||
|
||||
#### Event - `htmx:wsBeforeSend` {#htmx:wsBeforeSend}
|
||||
|
||||
This event is triggered just before sending a message. This includes messages from the queue.
|
||||
Message can not be modified at this point.
|
||||
|
||||
If the event is cancelled, the message will be discarded from the queue and not sent.
|
||||
|
||||
##### Details
|
||||
|
||||
* `detail.elt` - the element that dispatched the request (the one with `ws-connect` attribute)
|
||||
* `detail.message` - the raw message content
|
||||
* `detail.socketWrapper` - the wrapper around socket object
|
||||
|
||||
#### Event - `htmx:wsAfterSend` {#htmx:wsAfterSend}
|
||||
|
||||
This event is triggered just after sending a message. This includes messages from the queue.
|
||||
|
||||
Cancelling the event has no effect.
|
||||
|
||||
##### Details
|
||||
|
||||
* `detail.elt` - the element that dispatched the request (the one with `ws-connect` attribute)
|
||||
* `detail.message` - the raw message content
|
||||
* `detail.socketWrapper` - the wrapper around socket object
|
||||
|
||||
#### Socket wrapper
|
||||
|
||||
You may notice that all events expose `detail.socketWrapper` property. This wrapper holds the socket
|
||||
object itself and the message queue. It also encapsulates reconnection algorithm. It exposes a few members:
|
||||
|
||||
- `send(message, fromElt)` - sends a message safely. If the socket is not open, the message will be persisted in the
|
||||
queue
|
||||
instead and sent when the socket is ready.
|
||||
- `sendImmediately(message, fromElt)` - attempts to send a message regardless of socket state, bypassing the queue. May
|
||||
fail
|
||||
- `queue` - an array of messages, awaiting in the queue.
|
||||
|
||||
This wrapper can be used in your event handlers to monitor and manipulate the queue (e.g., you can reset the queue when
|
||||
reconnecting), and to send additional messages (e.g., if you want to send data in batches).
|
||||
The `fromElt` parameter is optional and, when specified, will trigger corresponding websocket events from
|
||||
specified element, namely `htmx:wsBeforeSend` and `htmx:wsAfterSend` events when sending your messages.
|
||||
|
||||
### Testing with the Demo Server
|
||||
|
||||
Htmx includes a demo WebSockets server written in Node.js that will help you to see WebSockets in action, and begin
|
||||
bootstrapping your own WebSockets code. It is located in the /test/ws-sse folder of the htmx distribution. Look at
|
||||
/test/ws-sse/README.md for instructions on running and using the test server.
|
||||
|
||||
### Migrating from Previous Versions
|
||||
|
||||
Previous versions of htmx used a built-in tag `hx-ws` to implement WebSockets. This code has been migrated into an
|
||||
extension instead. Here are the steps you need to take to migrate to this version:
|
||||
|
||||
| Old Attribute | New Attribute | Comments |
|
||||
|-------------------------|----------------------|----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `hx-ws=""` | `hx-ext="ws"` | Use the `hx-ext="ws"` attribute to install the WebSockets extension into any HTML element. |
|
||||
| `hx-ws="connect:<url>"` | `ws-connect="<url>"` | Add a new attribute `ws-connect` to the tag that defines the extension to specify the URL of the WebSockets server you're using. |
|
||||
| `hx-ws="send"` | `ws-send=""` | Add a new attribute `ws-send` to mark any child forms that should send data to your WebSocket server |
|
@ -10,7 +10,7 @@ title = "Reference"
|
||||
* [htmx Request Headers](#request_headers)
|
||||
* [htmx Response Headers](#response_headers)
|
||||
* [htmx Events](#events)
|
||||
* [htmx Extensions](/extensions#included)
|
||||
* [htmx Extensions](https://extensions.htmx.org)
|
||||
* [JavaScript API](#api)
|
||||
* [Configuration Options](#config)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user