mirror of
https://github.com/bigskysoftware/htmx.git
synced 2026-04-19 21:36:31 +00:00
pull hx-classes out to an extension
This commit is contained in:
72
src/ext/class-tools.js
Normal file
72
src/ext/class-tools.js
Normal file
@@ -0,0 +1,72 @@
|
||||
(function(){
|
||||
|
||||
function splitOnWhitespace(trigger) {
|
||||
return trigger.split(/\s+/);
|
||||
}
|
||||
|
||||
function parseClassOperation(trimmedValue) {
|
||||
var split = splitOnWhitespace(trimmedValue);
|
||||
if (split.length > 1) {
|
||||
var operation = split[0];
|
||||
var classDef = split[1].trim();
|
||||
var cssClass;
|
||||
var delay;
|
||||
if (classDef.indexOf(":") > 0) {
|
||||
var splitCssClass = classDef.split(':');
|
||||
cssClass = splitCssClass[0];
|
||||
delay = parseInterval(splitCssClass[1]);
|
||||
} else {
|
||||
cssClass = classDef;
|
||||
delay = 100;
|
||||
}
|
||||
return {
|
||||
operation:operation,
|
||||
cssClass:cssClass,
|
||||
delay:delay
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function processClassList(elt, classList) {
|
||||
var runs = classList.split("&");
|
||||
for (var i = 0; i < runs.length; i++) {
|
||||
var run = runs[i];
|
||||
var currentRunTime = 0;
|
||||
var classOperations = run.split(",");
|
||||
for (var j = 0; j < classOperations.length; j++) {
|
||||
var value = classOperations[j];
|
||||
var trimmedValue = value.trim();
|
||||
var classOperation = parseClassOperation(trimmedValue);
|
||||
if (classOperation) {
|
||||
if (classOperation.operation === "toggle") {
|
||||
setTimeout(function () {
|
||||
setInterval(function () {
|
||||
elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass);
|
||||
}, classOperation.delay);
|
||||
}, currentRunTime);
|
||||
currentRunTime = currentRunTime + classOperation.delay;
|
||||
} else {
|
||||
currentRunTime = currentRunTime + classOperation.delay;
|
||||
setTimeout(function () {
|
||||
elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass);
|
||||
}, currentRunTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
htmx.defineExtension('class-tools', {
|
||||
onEvent: function (name, evt) {
|
||||
if (name === "processedNode.htmx") {
|
||||
var elt = evt.detail.elt;
|
||||
var classList = elt.getAttribute("classes") || elt.getAttribute("data-classes");
|
||||
if (classList) {
|
||||
processClassList(elt, classList);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
71
src/htmx.js
71
src/htmx.js
@@ -155,10 +155,6 @@ var htmx = htmx || (function () {
|
||||
return getDocument().body.contains(elt);
|
||||
}
|
||||
|
||||
function concat(arr1, arr2) {
|
||||
return arr1.concat(arr2);
|
||||
}
|
||||
|
||||
function splitOnWhitespace(trigger) {
|
||||
return trigger.split(/\s+/);
|
||||
}
|
||||
@@ -519,56 +515,6 @@ var htmx = htmx || (function () {
|
||||
return [{trigger: 'click'}];
|
||||
}
|
||||
|
||||
function parseClassOperation(trimmedValue) {
|
||||
var split = splitOnWhitespace(trimmedValue);
|
||||
if (split.length > 1) {
|
||||
var operation = split[0];
|
||||
var classDef = split[1].trim();
|
||||
var cssClass;
|
||||
var delay;
|
||||
if (classDef.indexOf(":") > 0) {
|
||||
var splitCssClass = classDef.split(':');
|
||||
cssClass = splitCssClass[0];
|
||||
delay = parseInterval(splitCssClass[1]);
|
||||
} else {
|
||||
cssClass = classDef;
|
||||
delay = 100;
|
||||
}
|
||||
return {
|
||||
operation:operation,
|
||||
cssClass:cssClass,
|
||||
delay:delay
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function processClassList(elt, classList) {
|
||||
forEach(classList.split("&"), function (run) {
|
||||
var currentRunTime = 0;
|
||||
forEach(run.split(","), function(value){
|
||||
var trimmedValue = value.trim();
|
||||
var classOperation = parseClassOperation(trimmedValue);
|
||||
if (classOperation) {
|
||||
if (classOperation.operation === "toggle") {
|
||||
setTimeout(function () {
|
||||
setInterval(function () {
|
||||
elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass);
|
||||
}, classOperation.delay);
|
||||
}, currentRunTime);
|
||||
currentRunTime = currentRunTime + classOperation.delay;
|
||||
} else {
|
||||
currentRunTime = currentRunTime + classOperation.delay;
|
||||
setTimeout(function () {
|
||||
elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass);
|
||||
}, currentRunTime);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function cancelPolling(elt) {
|
||||
getInternalData(elt).cancelled = true;
|
||||
}
|
||||
@@ -776,10 +722,7 @@ var htmx = htmx || (function () {
|
||||
if (sseSrc) {
|
||||
initSSESource(elt, sseSrc);
|
||||
}
|
||||
var addClass = getAttributeValue(elt, 'hx-classes');
|
||||
if (addClass) {
|
||||
processClassList(elt, addClass);
|
||||
}
|
||||
triggerEvent(elt, "processedNode.htmx");
|
||||
}
|
||||
if (elt.children) { // IE
|
||||
forEach(elt.children, function(child) { processNode(child) });
|
||||
@@ -815,17 +758,21 @@ var htmx = htmx || (function () {
|
||||
triggerEvent(elt, eventName, mergeObjects({isError:true}, detail));
|
||||
}
|
||||
|
||||
function ignoreEventForLogging(eventName) {
|
||||
return eventName === "processedNode.htmx"
|
||||
}
|
||||
|
||||
function triggerEvent(elt, eventName, detail) {
|
||||
if (detail == null) {
|
||||
detail = {};
|
||||
}
|
||||
detail["elt"] = elt;
|
||||
var event = makeEvent(eventName, detail);
|
||||
if (htmx.logger) {
|
||||
if (htmx.logger && !ignoreEventForLogging(eventName)) {
|
||||
htmx.logger(elt, eventName, detail);
|
||||
if (detail.isError) {
|
||||
sendError(elt, eventName, detail);
|
||||
}
|
||||
}
|
||||
if (detail.isError) {
|
||||
sendError(elt, eventName, detail);
|
||||
}
|
||||
var eventResult = elt.dispatchEvent(event);
|
||||
forEach(getExtensions(elt), function (extension) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe("hx-classes attribute", function(){
|
||||
describe("class-tools extension", function(){
|
||||
beforeEach(function() {
|
||||
this.server = makeServer();
|
||||
clearWorkArea();
|
||||
@@ -10,7 +10,7 @@ describe("hx-classes attribute", function(){
|
||||
|
||||
it('adds classes properly', function(done)
|
||||
{
|
||||
var div = make('<div hx-classes="add c1">Click Me!</div>')
|
||||
var div = make('<div hx-ext="class-tools" classes="add c1">Click Me!</div>')
|
||||
should.equal(div.classList.length, 0);
|
||||
setTimeout(function(){
|
||||
should.equal(div.classList.contains("c1"), true);
|
||||
@@ -20,7 +20,7 @@ describe("hx-classes attribute", function(){
|
||||
|
||||
it('removes classes properly', function(done)
|
||||
{
|
||||
var div = make('<div class="foo bar" hx-classes="remove bar">Click Me!</div>')
|
||||
var div = make('<div class="foo bar" hx-ext="class-tools" classes="remove bar">Click Me!</div>')
|
||||
should.equal(div.classList.contains("foo"), true);
|
||||
should.equal(div.classList.contains("bar"), true);
|
||||
setTimeout(function(){
|
||||
@@ -32,7 +32,7 @@ describe("hx-classes attribute", function(){
|
||||
|
||||
it('adds classes properly w/ data-* prefix', function(done)
|
||||
{
|
||||
var div = make('<div data-hx-classes="add c1">Click Me!</div>')
|
||||
var div = make('<div hx-ext="class-tools" data-classes="add c1">Click Me!</div>')
|
||||
should.equal(div.classList.length, 0);
|
||||
setTimeout(function(){
|
||||
should.equal(div.classList.contains("c1"), true);
|
||||
@@ -40,5 +40,16 @@ describe("hx-classes attribute", function(){
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it('extension can be on parent', function(done)
|
||||
{
|
||||
var div = make('<div hx-ext="class-tools"><div id="d1" classes="add c1">Click Me!</div></div>')
|
||||
should.equal(div.classList.length, 0);
|
||||
setTimeout(function(){
|
||||
should.equal(div.classList.contains("c1"), false);
|
||||
should.equal(byId("d1").classList.contains("c1"), true);
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
|
||||
})
|
||||
@@ -63,7 +63,6 @@
|
||||
|
||||
<!-- attribute tests -->
|
||||
<script src="attributes/hx-boost.js"></script>
|
||||
<script src="attributes/hx-classes.js"></script>
|
||||
<script src="attributes/hx-delete.js"></script>
|
||||
<script src="attributes/hx-error-url.js"></script>
|
||||
<script src="attributes/hx-ext.js"></script>
|
||||
@@ -102,6 +101,9 @@
|
||||
<script src="../src/ext/path-deps.js"></script>
|
||||
<script src="ext/path-deps.js"></script>
|
||||
|
||||
<script src="../src/ext/class-tools.js"></script>
|
||||
<script src="ext/class-tools.js"></script>
|
||||
|
||||
<!-- events last so they don't screw up other tests -->
|
||||
<script src="core/events.js"></script>
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
---
|
||||
layout: layout.njk
|
||||
title: </> htmx - hx-classes
|
||||
---
|
||||
|
||||
## `hx-classes`
|
||||
|
||||
The `hx-classes` attribute allows you to specify CSS classes that will be swapped onto the element that
|
||||
the attribute is on. This 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 `hx-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.
|
||||
|
||||
Here are some examples:
|
||||
|
||||
```html
|
||||
<div hx-classes="add foo"/> <!-- adds the class "foo" after 100ms -->
|
||||
<div hx-classes="remove bar:1s"/> <!-- removes the class "bar" after 1s -->
|
||||
<div hx-classes="remove bar:1s, add foo:1s"/> <!-- removes the class "bar" after 1s
|
||||
then adds the class "foo" 1s after that -->
|
||||
<div hx-classes="remove bar:1s & add foo:1s"/> <!-- removes the class "bar" and adds
|
||||
class "foo" after 1s -->
|
||||
<div hx-classes="toggle foo:1s"/> <!-- toggles the class "foo" every 1s -->
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
* `hx-classes` is not inherited
|
||||
* The default delay if none is specified is 100ms
|
||||
74
www/docs.md
74
www/docs.md
@@ -21,9 +21,9 @@ title: </> htmx - high power tools for html
|
||||
* [indicators](#indicators)
|
||||
* [swapping](#swapping)
|
||||
* [parameters](#parameters)
|
||||
* [boosting](#boosting)
|
||||
* [history](#history)
|
||||
* [requests & responses](#requests)
|
||||
* [miscellaneous](#miscellaneous)
|
||||
* [extensions](#extensions)
|
||||
* [events & logging](#events)
|
||||
* [configuring](#config)
|
||||
@@ -364,6 +364,24 @@ If you wish to filter out some parameters you can use the [hx-params](/attribute
|
||||
Finally, if you want to programatically modify the parameters, you can use the [configRequest.htmx](/events#configRequest.htmx)
|
||||
event.
|
||||
|
||||
## <a name="boosting"></a>[Boosting](#boosting)
|
||||
|
||||
Htmx supports "boosting" regular HTML anchors and forms with the [hx-boost](/attributes/hx-boost) attribute. This
|
||||
attribute will convert all anchor tags and forms into AJAX requests that, by default, target the body of the page.
|
||||
|
||||
Here is an example:
|
||||
|
||||
```html
|
||||
<div hx-boost="true">
|
||||
<a href="/blog">Blog</a>
|
||||
</div>
|
||||
```
|
||||
|
||||
The anchor tag in this div will issue an AJAX `GET` request to `/blog` and swap the response into the `body` tag.
|
||||
|
||||
This functionality is somewhat similar to [Turbolinks](https://github.com/turbolinks/turbolinks) and allows you to use
|
||||
htmx for [progressive enhancement](https://en.wikipedia.org/wiki/Progressive_enhancement).
|
||||
|
||||
## <a name="history"></a> [History Support](#history)
|
||||
|
||||
Htmx provides a simple mechanism for interacting with the [browser history API](https://developer.mozilla.org/en-US/docs/Web/API/History_API):
|
||||
@@ -448,46 +466,6 @@ The order of operations in a htmx request are:
|
||||
You can use the `htmx-swapping` and `htmx-settling` classes to create
|
||||
[CSS transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions) between pages.
|
||||
|
||||
## <a name="miscellaneous"></a> [Miscellaneous](#miscellaneous)
|
||||
|
||||
In addition to the core AJAX functionality, htmx also has a few other tricks up its sleeve that help you build
|
||||
nice interfaces without javascript.
|
||||
|
||||
### Class Swapping
|
||||
|
||||
Htmx supports an attribute, [hx-classes](/attributes/hx-classes) that allows you to add, remove and toggle classes after
|
||||
a delay. This can be used to create CSS transition effects.
|
||||
|
||||
Here are some examples:
|
||||
|
||||
```html
|
||||
<!-- adds the class "foo" after 100ms -->
|
||||
<div hx-classes="add foo"/>
|
||||
|
||||
<!-- removes the class "bar" after 1s -->
|
||||
<div hx-classes="remove bar:1s"/>
|
||||
|
||||
<!-- removes the class "bar" after 1s
|
||||
then adds the class "foo" 1s after that -->
|
||||
<div hx-classes="remove bar:1s, add foo:1s"/>
|
||||
|
||||
<!-- removes the class "bar" and adds
|
||||
class "foo" after 1s -->
|
||||
<div hx-classes="remove bar:1s & add foo:1s"/>
|
||||
|
||||
<!-- toggles the class "foo" every 1s -->
|
||||
<div hx-classes="toggle foo:1s"/>
|
||||
```
|
||||
|
||||
Full documentation is available [on the documentation page.](/attributes/hx-classes)
|
||||
|
||||
### Boosting
|
||||
|
||||
Htmx supports "boosting" regular HTML anchors and forms with the [hx-boost](/attributes/hx-boost) attribute. This
|
||||
attribute will convert all anchor tags and forms into AJAX requests that, by default, target the body of the page.
|
||||
|
||||
This functionality is somewhat similar to [Turbolinks](https://github.com/turbolinks/turbolinks).
|
||||
|
||||
## <a name="extensions"></a> [Extensions](#extensions)
|
||||
|
||||
Htmx has an extension mechanism that allows you to customize the libraries' behavior. Extensions [are
|
||||
@@ -505,14 +483,14 @@ Htmx offers some officially supported extensions that are tested against the htm
|
||||
|
||||
| Extension | Description
|
||||
|-----------|-------------
|
||||
| [`json-enc`](/official-extensions#json-enc) | use JSON encoding in the body of requests, rather than the default `x-www-form-urlencoded`
|
||||
| [`morphdom-swap`](/official-extensions#morphdom-swap) | an extension for using the [morphdom](https://github.com/patrick-steele-idem/morphdom) library as the swapping mechanism in htmx.
|
||||
| [`client-side-templates`](/official-extensions#client-side-templates) | support for client side template processing of JSON responses
|
||||
| [`debug`](/official-extensions#debug) | an extension for debugging of a particular element using htmx
|
||||
| [`path-deps`](/official-extensions#path-deps) | an extension for expressing path-based dependencies [similar to intercoolerjs](http://intercoolerjs.org/docs.html#dependencies)
|
||||
| [`rails-method`](/official-extensions#rails-method) | an extension for including the `_method` parameter that [that rails uses](https://guides.rubyonrails.org/form_helpers.html#how-do-forms-with-patch-put-or-delete-methods-work-questionmark) for non-`POST` or `GET` HTTP methods.
|
||||
| [`json-enc`](/extensions/json-enc) | use JSON encoding in the body of requests, rather than the default `x-www-form-urlencoded`
|
||||
| [`morphdom-swap`](/extensions/morphdom-swap) | an extension for using the [morphdom](https://github.com/patrick-steele-idem/morphdom) library as the swapping mechanism in htmx.
|
||||
| [`client-side-templates`](/extensions/client-side-templates) | support for client side template processing of JSON responses
|
||||
| [`debug`](/extensions/debug) | an extension for debugging of a particular element using htmx
|
||||
| [`path-deps`](/extensions/path-deps) | an extension for expressing path-based dependencies [similar to intercoolerjs](http://intercoolerjs.org/docs.html#dependencies)
|
||||
| [`class-tools`](/extensions/class-tools) | an extension for manipulating timed addition and removal of classes on HTML elements
|
||||
|
||||
See the [officially extensions](/official-extensions) page for a complete list.
|
||||
See the [references page](/reference#extensions) for a complete list.
|
||||
|
||||
## <a name="events"></a> [Events & Logging](#events)
|
||||
|
||||
|
||||
37
www/extensions/class-tools.md
Normal file
37
www/extensions/class-tools.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
layout: layout.njk
|
||||
title: </> htmx - high power tools for html
|
||||
---
|
||||
|
||||
## The `class-tools` Extension
|
||||
|
||||
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.
|
||||
|
||||
### 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>
|
||||
```
|
||||
|
||||
### Source
|
||||
|
||||
<https://unpkg.com/htmx.org/ext/class-tools.js>
|
||||
46
www/extensions/client-side-templates.md
Normal file
46
www/extensions/client-side-templates.md
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
layout: layout.njk
|
||||
title: </> htmx - high power tools for html
|
||||
---
|
||||
|
||||
## The `client-side-templates` Extension
|
||||
|
||||
This extension supports transforming a JSON request response into HTML via a client-side template before it is
|
||||
swapped into the DOM. Currently three client-side templating engines are supported:
|
||||
|
||||
* [mustache](https://github.com/janl/mustache.js)
|
||||
* [handlebars](https://handlebarsjs.com/)
|
||||
* [nunjucks](https://mozilla.github.io/nunjucks/)
|
||||
|
||||
When you add this extension on an element, any element below it in the DOM can use one of three attributes named
|
||||
`<template-engine>-temlpate` (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 in the `Handlebars.partials` collection fot a template with that name
|
||||
* `nunjucks` - resolves the template by name via `nunjucks.render(<template-name>)
|
||||
|
||||
The AJAX response body will be parsed as JSON and passed into the template rendering.
|
||||
|
||||
### Usage
|
||||
|
||||
```html
|
||||
<div hx-ext='client-side-template'>
|
||||
<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>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Source
|
||||
|
||||
<https://unpkg.com/htmx.org/ext/client-side-templates.js>
|
||||
19
www/extensions/debug.md
Normal file
19
www/extensions/debug.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
layout: layout.njk
|
||||
title: </> htmx - high power tools for html
|
||||
---
|
||||
|
||||
## The `debug` Extension
|
||||
|
||||
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.
|
||||
|
||||
### Usage
|
||||
|
||||
```html
|
||||
<button hx-ext="debug">Debug Me...</button>
|
||||
```
|
||||
|
||||
### Source
|
||||
|
||||
<https://unpkg.com/htmx.org/ext/debug.js>
|
||||
18
www/extensions/json-enc.md
Normal file
18
www/extensions/json-enc.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
layout: layout.njk
|
||||
title: </> htmx - high power tools for html
|
||||
---
|
||||
|
||||
## The `json-enc` Extension
|
||||
|
||||
This extension encodes parameters in JSON format instead of url format.
|
||||
|
||||
### Usage
|
||||
|
||||
```html
|
||||
<div hx-post='/test' hx-ext='json-enc'>click me</div>
|
||||
```
|
||||
|
||||
### Source
|
||||
|
||||
<https://unpkg.com/htmx.org/ext/json-enc.js>
|
||||
25
www/extensions/morphdom-swap.md
Normal file
25
www/extensions/morphdom-swap.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
layout: layout.njk
|
||||
title: </> htmx - high power tools for html
|
||||
---
|
||||
|
||||
## The `morphdom-swap` Extension
|
||||
|
||||
This extension allows you to use the [morphdom](https://github.com/patrick-steele-idem/morphdom) library as the
|
||||
swapping mechanism in htmx.
|
||||
|
||||
#### 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>
|
||||
```
|
||||
|
||||
#### Source
|
||||
|
||||
<https://unpkg.com/htmx.org/ext/morphdom-swap.js>
|
||||
|
||||
44
www/extensions/path-deps.md
Normal file
44
www/extensions/path-deps.md
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
layout: layout.njk
|
||||
title: </> htmx - high power tools for html
|
||||
---
|
||||
|
||||
## The `path-deps` Extension
|
||||
|
||||
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>
|
||||
```
|
||||
|
||||
#### 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>
|
||||
```
|
||||
|
||||
#### Source
|
||||
|
||||
<https://unpkg.com/htmx.org/ext/path-deps.js>
|
||||
20
www/extensions/rails-method.md
Normal file
20
www/extensions/rails-method.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
layout: layout.njk
|
||||
title: </> htmx - high power tools for html
|
||||
---
|
||||
|
||||
## The `rails-method` Extension
|
||||
|
||||
This extension includes the rails `_method` parameter in non-`GET` or `POST` requests.
|
||||
|
||||
### Usage
|
||||
|
||||
```html
|
||||
<body hx-ext="rails-method">
|
||||
...
|
||||
</body>
|
||||
```
|
||||
|
||||
### Source
|
||||
|
||||
<https://unpkg.com/htmx.org/ext/rails-method.js>
|
||||
@@ -1,207 +0,0 @@
|
||||
---
|
||||
layout: layout.njk
|
||||
title: </> htmx - high power tools for html
|
||||
---
|
||||
|
||||
## Official Extensions
|
||||
|
||||
The following extensions are tested against htmx and thus are considered officially supported.
|
||||
|
||||
### <a name="debug">[`debug`](#debug)
|
||||
|
||||
#### Description
|
||||
|
||||
This extension includes log all htmx events for the element it is on with the `"DEBUG:"` prefix.
|
||||
|
||||
#### Usage
|
||||
|
||||
```html
|
||||
<button hx-ext="debug">Debug Me...</button>
|
||||
```
|
||||
|
||||
#### Source
|
||||
|
||||
```javascript
|
||||
htmx.defineExtension('debug', {
|
||||
onEvent : function(name, evt) {
|
||||
if(console.debug){
|
||||
console.debug(name, evt);
|
||||
} else if(console) {
|
||||
console.log("DEBUG:", name, evt);
|
||||
} else {
|
||||
throw "NO CONSOLE SUPPORTED"
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### <a name="rails-method">[`rails-method`](#rails-method)
|
||||
|
||||
#### Description
|
||||
|
||||
This extension includes the rails `_method` parameter in non-`GET` or `POST` requests.
|
||||
|
||||
#### Usage
|
||||
|
||||
```html
|
||||
<body hx-ext="rails-method">
|
||||
...
|
||||
</body>
|
||||
```
|
||||
|
||||
#### Source
|
||||
|
||||
```javascript
|
||||
htmx.defineExtension('rails-method', {
|
||||
onEvent : function(name, evt) {
|
||||
if(name === "configRequest.htmx"){
|
||||
var methodOverride = evt.detail.headers['X-HTTP-Method-Override'];
|
||||
if(methodOverride){
|
||||
evt.detail.parameters['_method'] = methodOverride;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### <a name="morphdom-swap">[`morphdom-swap`](#morphdom-swap)
|
||||
|
||||
#### Description
|
||||
|
||||
This extension allows you to use the [morphdom](https://github.com/patrick-steele-idem/morphdom) library as the
|
||||
swapping mechanism in htmx.
|
||||
|
||||
#### 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>
|
||||
```
|
||||
|
||||
#### Source
|
||||
|
||||
```javascript
|
||||
htmx.defineExtension('morphdom-swap', {
|
||||
handleSwap : function(swapStyle, target, fragment, settleInfo) {
|
||||
if (swapStyle === 'morphdom') {
|
||||
morphdom(target, fragment.outerHTML);
|
||||
true; // no settle phase when using morphdom!
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### <a name="json-enc">[`json-enc`](#json-enc)
|
||||
|
||||
#### Description
|
||||
|
||||
This extension encodes parameters in JSON format instead of url format.
|
||||
|
||||
#### Usage
|
||||
|
||||
```html
|
||||
<div hx-post='/test' hx-ext='json-enc'>click me</div>
|
||||
```
|
||||
|
||||
#### Source
|
||||
|
||||
```javascript
|
||||
htmx.defineExtension('json-enc', {
|
||||
encodeParameters : function(xhr, parameters, elt) {
|
||||
xhr.requestHeaders['Content-Type'] = 'application/json';
|
||||
xhr.overrideMimeType('text/json');
|
||||
return (JSON.stringify(parameters));
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
### <a name="client-side-templates">[`client-side-templates`](#client-side-templates)
|
||||
|
||||
#### Description
|
||||
|
||||
This extension supports transforming a JSON request response into HTML via a client-side template before it is
|
||||
swapped into the DOM. Currently three client-side templating engines are supported:
|
||||
|
||||
* [mustache](https://github.com/janl/mustache.js)
|
||||
* [handlebars](https://handlebarsjs.com/)
|
||||
* [nunjucks](https://mozilla.github.io/nunjucks/)
|
||||
|
||||
When you add this extension on an element, any element below it in the DOM can use one of three attributes named
|
||||
`<template-engine>-temlpate` (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 in the `Handlebars.partials` collection fot a template with that name
|
||||
* `nunjucks` - resolves the template by name via `nunjucks.render(<template-name>)
|
||||
|
||||
The AJAX response body will be parsed as JSON and passed into the template rendering.
|
||||
|
||||
#### Usage
|
||||
|
||||
```html
|
||||
<div hx-ext='client-side-template'>
|
||||
<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>
|
||||
</div>
|
||||
```
|
||||
|
||||
#### Source
|
||||
|
||||
<https://unpkg.com/htmx.org/ext/client-side-templates.js>
|
||||
|
||||
### <a name="path-deps">[`path-deps`](#path-deps)
|
||||
|
||||
#### Description
|
||||
|
||||
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>
|
||||
```
|
||||
|
||||
#### 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>
|
||||
```
|
||||
|
||||
#### Source
|
||||
|
||||
<https://unpkg.com/htmx.org/ext/path-deps.js>
|
||||
@@ -8,7 +8,6 @@ title: </> htmx - Attributes
|
||||
| Attribute | Description |
|
||||
|-----------|-------------|
|
||||
| [`hx-boost`](/attributes/hx-boost) | progressively enhances anchors and forms to use AJAX requests
|
||||
| [`hx-classes`](/attributes/hx-classes) | timed modification of classes on an element
|
||||
| [`hx-confirm`](/attributes/hx-confirm) | shows a confim() dialog before issuing a request
|
||||
| [`hx-delete`](/attributes/hx-delete) | issues a `DELETE` to the specified URL
|
||||
| [`hx-error-url`](/attributes/hx-error-url) | a URL to send client-side errors to
|
||||
@@ -93,3 +92,14 @@ title: </> htmx - Attributes
|
||||
| [`sseError.htmx`](/events#sseError.htmx) | triggered when an error occurs with a SSE source
|
||||
| [`swapError.htmx`](/events#swapError.htmx) | triggered when an error occurs during the swap phase
|
||||
| [`targetError.htmx`](/events#targetError.htmx) | triggered when an invalid target is specified
|
||||
|
||||
## <a name="extensions"></a> [Extensions Reference](#extensions)
|
||||
|
||||
| Extension | Description
|
||||
|-----------|-------------
|
||||
| [`json-enc`](/extensions/json-enc) | use JSON encoding in the body of requests, rather than the default `x-www-form-urlencoded`
|
||||
| [`morphdom-swap`](/extensions/morphdom-swap) | an extension for using the [morphdom](https://github.com/patrick-steele-idem/morphdom) library as the swapping mechanism in htmx.
|
||||
| [`client-side-templates`](/extensions/client-side-templates) | support for client side template processing of JSON responses
|
||||
| [`debug`](/extensions/debug) | an extension for debugging of a particular element using htmx
|
||||
| [`path-deps`](/extensions/path-deps) | an extension for expressing path-based dependencies [similar to intercoolerjs](http://intercoolerjs.org/docs.html#dependencies)
|
||||
| [`class-tools`](/extensions/class-tools) | an extension for manipulating timed addition and removal of classes on HTML elements
|
||||
|
||||
Reference in New Issue
Block a user