summaryrefslogtreecommitdiffstatshomepage
path: root/www
diff options
context:
space:
mode:
Diffstat (limited to 'www')
-rw-r--r--www/_includes/layout.njk20
-rw-r--r--www/attributes/hx-boost.md (renamed from www/attributes/kt-boost.md)10
-rw-r--r--www/attributes/hx-classes.md (renamed from www/attributes/kt-classes.md)20
-rw-r--r--www/attributes/hx-confirm.md (renamed from www/attributes/kt-confirm.md)10
-rw-r--r--www/attributes/hx-delete.md (renamed from www/attributes/kt-delete.md)16
-rw-r--r--www/attributes/hx-error-url.md24
-rw-r--r--www/attributes/hx-get.md25
-rw-r--r--www/attributes/hx-history-elt.md (renamed from www/attributes/kt-history-elt.md)12
-rw-r--r--www/attributes/hx-include.md (renamed from www/attributes/kt-include.md)10
-rw-r--r--www/attributes/hx-indicator.md (renamed from www/attributes/kt-indicator.md)40
-rw-r--r--www/attributes/hx-params.md (renamed from www/attributes/kt-params.md)10
-rw-r--r--www/attributes/hx-patch.md (renamed from www/attributes/kt-patch.md)16
-rw-r--r--www/attributes/hx-post.md25
-rw-r--r--www/attributes/hx-prompt.md21
-rw-r--r--www/attributes/hx-push-url.md26
-rw-r--r--www/attributes/hx-put.md (renamed from www/attributes/kt-put.md)16
-rw-r--r--www/attributes/hx-select.md (renamed from www/attributes/kt-select.md)10
-rw-r--r--www/attributes/hx-sse-src.md (renamed from www/attributes/kt-sse-src.md)12
-rw-r--r--www/attributes/hx-swap-oob.md (renamed from www/attributes/kt-swap-oob.md)12
-rw-r--r--www/attributes/hx-swap.md (renamed from www/attributes/kt-swap.md)20
-rw-r--r--www/attributes/hx-target.md (renamed from www/attributes/kt-target.md)10
-rw-r--r--www/attributes/hx-trigger.md (renamed from www/attributes/kt-trigger.md)22
-rw-r--r--www/attributes/kt-error-url.md24
-rw-r--r--www/attributes/kt-get.md25
-rw-r--r--www/attributes/kt-post.md25
-rw-r--r--www/attributes/kt-prompt.md21
-rw-r--r--www/attributes/kt-push-url.md26
-rw-r--r--www/css/prism-htmx.css (renamed from www/css/prism-kutty.css)2
-rw-r--r--www/docs.md264
-rw-r--r--www/events.md66
-rw-r--r--www/examples.md4
-rw-r--r--www/examples/active-search.md22
-rw-r--r--www/examples/bulk-update.md20
-rw-r--r--www/examples/click-to-edit.md16
-rw-r--r--www/examples/click-to-load.md16
-rw-r--r--www/examples/infinite-scroll.md14
-rw-r--r--www/examples/inline-validation.md26
-rw-r--r--www/examples/lazy-load.md12
-rw-r--r--www/examples/progress-bar.md38
-rw-r--r--www/examples/value-select.md6
-rw-r--r--www/headers/x-ht-trigger.md (renamed from www/headers/x-kt-trigger.md)16
-rw-r--r--www/img/htmx_logo.2.png (renamed from www/img/kutty_logo.2.png)bin15693 -> 15693 bytes
-rw-r--r--www/img/kutty_placeholder.pngbin32478 -> 0 bytes
-rw-r--r--www/index.md18
-rw-r--r--www/js/kutty.js1306
-rw-r--r--www/posts/2020-5-18-kutty-er-htmx-0.0.2-is-released.md38
-rw-r--r--www/reference.md122
-rw-r--r--www/talk.md10
48 files changed, 628 insertions, 1896 deletions
diff --git a/www/_includes/layout.njk b/www/_includes/layout.njk
index 9a1676dc..79e22550 100644
--- a/www/_includes/layout.njk
+++ b/www/_includes/layout.njk
@@ -1,19 +1,19 @@
<html lang="en">
<head>
- <title>&lt;/> kutty - high power tools for html</title>
+ <title>&lt;/> htmx - high power tools for html</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/css/site.css"/>
- <link rel="stylesheet" href="/css/prism-kutty.css"/>
+ <link rel="stylesheet" href="/css/prism-htmx.css"/>
<script src="https://unpkg.com/prismjs@1.20.0/components/prism-core.min.js"></script>
<script src="https://unpkg.com/prismjs@1.20.0/plugins/autoloader/prism-autoloader.min.js"></script>
- <script src="/js/kutty.js"></script>
+ <script src="/js/htmx.js"></script>
<script>
- kutty.logger = function(elt, event, data) {
+ htmx.logger = function(elt, event, data) {
if(console) {
//console.log(event, elt, data);
}
}
- kutty.onLoad(function(){
+ htmx.onLoad(function(){
Prism.highlightAll();
})
</script>
@@ -24,9 +24,9 @@
<div class="row">
<div class="2 col">
{% if page.url.indexOf("/examples/") == 0 %}
- <span onclick="document.location = '/';" class="logo light">&lt;<a>/</a>&gt; k<a>u</a>tty</span>
+ <span onclick="document.location = '/';" class="logo light">&lt;<a>/</a>&gt; htm<a>x</a></span>
{% else %}
- <span kt-get="/" kt-target="body" kt-push-url="true" class="logo light">&lt;<a>/</a>&gt; k<a>u</a>tty</span>
+ <span hx-get="/" hx-target="body" hx-push-url="true" class="logo light">&lt;<a>/</a>&gt; htm<a>x</a></span>
{% endif %}
<svg onclick="document.getElementById('nav').classList.toggle('show')" class="hamburger" viewBox="0 0 100 80" width="25" height="25" style="margin-bottom:-5px">
<rect width="100" height="20" style="fill:rgb(52, 101, 164)" rx="10"></rect>
@@ -37,7 +37,7 @@
{% if page.url.indexOf("/examples/") == 0 %}
<div id="nav" class="10 col nav"> <!-- don't boost on demo pages, sinon hijacks everything :/ -->
{% else %}
- <div id="nav" class="10 col" kt-boost="true">
+ <div id="nav" class="10 col" hx-boost="true">
{% endif %}
<div class="row">
<div class="1 col">
@@ -55,8 +55,8 @@
<div class="8 col">
</div>
<div class="8 col" style="text-align: right">
- <a href="https://github.com/bigskysoftware/kutty">github</a>
- <iframe style="margin:auto;" src="https://ghbtns.com/github-btn.html?user=bigskysoftware&repo=kutty&type=star&count=true" frameborder="0" scrolling="0" width="150" height="20" title="Star twbs/bootstrap on GitHub"></iframe>
+ <a href="https://github.com/bigskysoftware/htmx">github</a>
+ <iframe style="margin:auto;" src="https://ghbtns.com/github-btn.html?user=bigskysoftware&repo=htmx&type=star&count=true" frameborder="0" scrolling="0" width="150" height="20" title="Star twbs/bootstrap on GitHub"></iframe>
</div>
</div>
</div>
diff --git a/www/attributes/kt-boost.md b/www/attributes/hx-boost.md
index 99d58525..a6ab1742 100644
--- a/www/attributes/kt-boost.md
+++ b/www/attributes/hx-boost.md
@@ -1,11 +1,11 @@
---
layout: layout.njk
-title: </> kutty - kt-boost
+title: </> htmx - hx-boost
---
-## `kt-boost`
+## `hx-boost`
-The `kt-boost` attribute allows you to "boost" normal anchors and form tags to use AJAX instead. This
+The `hx-boost` attribute allows you to "boost" normal anchors and form tags to use AJAX instead. This
has the [nice fallback](https://en.wikipedia.org/wiki/Progressive_enhancement) that, if the user does not
have javascript enabled, the site will continue to work.
@@ -21,7 +21,7 @@ swap will be used.
Here is an example of some boosted links:
```html
-<div kt-boost="true">
+<div hx-boost="true">
<a href="/page1">Go To Page 1</a>
<a href="/page2">Go To Page 2</a>
</div>
@@ -29,6 +29,6 @@ Here is an example of some boosted links:
### Notes
-* `kt-boost` is inherited and can be placed on a parent element
+* `hx-boost` is inherited and can be placed on a parent element
* Only links that are to the same domain and that are not local anchors will be boosted
* All requests are done via AJAX, so keep that in mind when doing things like redirects \ No newline at end of file
diff --git a/www/attributes/kt-classes.md b/www/attributes/hx-classes.md
index 87ca3844..37f9f846 100644
--- a/www/attributes/kt-classes.md
+++ b/www/attributes/hx-classes.md
@@ -1,15 +1,15 @@
---
layout: layout.njk
-title: </> kutty - kt-classes
+title: </> htmx - hx-classes
---
-## `kt-classes`
+## `hx-classes`
-The `kt-classes` attribute allows you to specify CSS classes that will be swapped onto the element that
+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 `kt-classes` attribute value consists of "runs", which are separated by an `&` character. All
+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.
@@ -20,16 +20,16 @@ optionally followed by a colon `:` and a time delay.
Here are some examples:
```html
-<div kt-classes="add foo"/> <!-- adds the class "foo" after 100ms -->
-<div kt-classes="remove bar:1s"/> <!-- removes the class "bar" after 1s -->
-<div kt-classes="remove bar:1s, add foo:1s"/> <!-- removes the class "bar" after 1s
+<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 kt-classes="remove bar:1s & add foo:1s"/> <!-- removes the class "bar" and adds
+<div hx-classes="remove bar:1s & add foo:1s"/> <!-- removes the class "bar" and adds
class "foo" after 1s -->
-<div kt-classes="toggle foo:1s"/> <!-- toggles the class "foo" every 1s -->
+<div hx-classes="toggle foo:1s"/> <!-- toggles the class "foo" every 1s -->
```
### Notes
-* `kt-classes` is not inherited
+* `hx-classes` is not inherited
* The default delay if none is specified is 100ms
diff --git a/www/attributes/kt-confirm.md b/www/attributes/hx-confirm.md
index f8608724..5de0186b 100644
--- a/www/attributes/kt-confirm.md
+++ b/www/attributes/hx-confirm.md
@@ -1,21 +1,21 @@
---
layout: layout.njk
-title: </> kutty - kt-confirm
+title: </> htmx - hx-confirm
---
-## `kt-confirm`
+## `hx-confirm`
-The `kt-confirm` attribute allows you to confirm an action before issuing a request. This can be useful
+The `hx-confirm` attribute allows you to confirm an action before issuing a request. This can be useful
in cases where the action is destructive and you want to ensure that the user really wants to do it.
Here is an example:
```html
-<button kt-delete="/account" kt-confirm="Are you sure you wish to delete your account?">
+<button hx-delete="/account" hx-confirm="Are you sure you wish to delete your account?">
Delete My Account
</button>
```
### Notes
-* `kt-confirm` is inherited and can be placed on a parent element
+* `hx-confirm` is inherited and can be placed on a parent element
diff --git a/www/attributes/kt-delete.md b/www/attributes/hx-delete.md
index a41a05a6..561e15bd 100644
--- a/www/attributes/kt-delete.md
+++ b/www/attributes/hx-delete.md
@@ -1,15 +1,15 @@
---
layout: layout.njk
-title: </> kutty - kt-delete
+title: </> htmx - hx-delete
---
-## `kt-delete`
+## `hx-delete`
-The `kt-delete` attribute will cause an element to issue a `DELETE` to the specified URL and swap
+The `hx-delete` attribute will cause an element to issue a `DELETE` to the specified URL and swap
the HTML into the DOM using a swap strategy:
```html
-<button kt-delete="/account" kt-target="body">
+<button hx-delete="/account" hx-target="body">
Delete Your Account
</button>
```
@@ -19,9 +19,9 @@ This example will cause the `button` to issue a `DELETE` to `/account` and swap
### Notes
-* `kt-delete` is not inherited
+* `hx-delete` is not inherited
* Since most browsers do not support issuing an actual `DELETE`, the request will actually be issued
as a `POST`, with the [`X-HTTP-Method-Override`](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields) header set to `DELETE`.
-* You can control the target of the swap using the [kt-target](/attributes/kt-target) attribute
-* You can control the swap strategy by using the [kt-swap](/attributes/kt-swap) attribute
-* You can control what event triggers the request with the [kt-trigger](/attributes/kt-trigger) attribute
+* You can control the target of the swap using the [hx-target](/attributes/hx-target) attribute
+* You can control the swap strategy by using the [hx-swap](/attributes/hx-swap) attribute
+* You can control what event triggers the request with the [hx-trigger](/attributes/hx-trigger) attribute
diff --git a/www/attributes/hx-error-url.md b/www/attributes/hx-error-url.md
new file mode 100644
index 00000000..b6d2715b
--- /dev/null
+++ b/www/attributes/hx-error-url.md
@@ -0,0 +1,24 @@
+---
+layout: layout.njk
+title: </> htmx - hx-error-url
+---
+
+## `hx-error-url`
+
+The `hx-error-url` attribute allows you to send client-side errors to a specified URL. It is typically put on the
+body tag, so all errors are caught and send to the server.
+
+```html
+<body hx-error-url="/errors">\
+
+</body>
+```
+When a client side error is caught by htmx it will be `POST`-ed to the given URL, with the following JSON format:
+
+```json
+ { "elt": elt.id, "event": eventName, "detail" : detail }
+```
+
+### Notes
+
+* `hx-error-url` is inherited and can be placed on a parent element
diff --git a/www/attributes/hx-get.md b/www/attributes/hx-get.md
new file mode 100644
index 00000000..8a1d1185
--- /dev/null
+++ b/www/attributes/hx-get.md
@@ -0,0 +1,25 @@
+---
+layout: layout.njk
+title: </> htmx - hx-get
+---
+
+## `hx-get`
+
+The `hx-get` attribute will cause an element to issue a `GET` to the specified URL and swap
+the HTML into the DOM using a swap strategy:
+
+```html
+ <div hx-get="/example">Get Some HTML</div>
+```
+
+This example will cause the `div` to issue a `GET` to `/example` and swap the returned HTML into
+ the `innerHTML` of the `div`.
+
+### Notes
+
+* `hx-get` is not inherited
+* By default `hx-get` does not include any parameters. You can use the [hx-params](/attributes/hx-params)
+ attribute to change this
+* You can control the target of the swap using the [hx-target](/attributes/hx-target) attribute
+* You can control the swap strategy by using the [hx-swap](/attributes/hx-swap) attribute
+* You can control what event triggers the request with the [hx-trigger](/attributes/hx-trigger) attribute
diff --git a/www/attributes/kt-history-elt.md b/www/attributes/hx-history-elt.md
index d074c254..addc1ddb 100644
--- a/www/attributes/kt-history-elt.md
+++ b/www/attributes/hx-history-elt.md
@@ -1,14 +1,14 @@
---
layout: layout.njk
-title: </> kutty - kt-history-elt
+title: </> htmx - hx-history-elt
---
-## `kt-history-elt`
+## `hx-history-elt`
-The `kt-history-elt` attribute allows you to specify the element that will be used to snapshot and
+The `hx-history-elt` attribute allows you to specify the element that will be used to snapshot and
restore page state during navigation. By default, the `body` tag is used. This is typically
good enough for most setups, but you may want to narrow it down to a child element. Just make
-sure that the element is always visible in your application, or kutty will not be able to restore
+sure that the element is always visible in your application, or htmx will not be able to restore
history navigation properly.
@@ -17,7 +17,7 @@ Here is an example:
```html
<html>
<body>
-<div id="content" kt-history-elt>
+<div id="content" hx-history-elt>
...
</div>
</body>
@@ -26,5 +26,5 @@ Here is an example:
### Notes
-* `kt-history-elt` is not inherited
+* `hx-history-elt` is not inherited
* In most cases we don't recommend narrowing the history snapshot \ No newline at end of file
diff --git a/www/attributes/kt-include.md b/www/attributes/hx-include.md
index 5b624a22..f608539e 100644
--- a/www/attributes/kt-include.md
+++ b/www/attributes/hx-include.md
@@ -1,18 +1,18 @@
---
layout: layout.njk
-title: </> kutty - kt-include
+title: </> htmx - hx-include
---
-## `kt-include`
+## `hx-include`
-The `kt-include` attribute allows you to include additional element values in an AJAX request. The value of
+The `hx-include` attribute allows you to include additional element values in an AJAX request. The value of
this attribute is a CSS query selector of the element or elements to include in the query.
Here is an example that includes a separate input value:
```html
<div>
- <button kt-post="/register" kt-include="[name='email']">
+ <button hx-post="/register" hx-include="[name='email']">
Register!
</button>
Enter email: <input name="email" type="email"/>
@@ -24,4 +24,4 @@ the value automatically, but it demonstrates the concept.
### Notes
-* `kt-include` is inherited and can be placed on a parent element
+* `hx-include` is inherited and can be placed on a parent element
diff --git a/www/attributes/kt-indicator.md b/www/attributes/hx-indicator.md
index 77992864..5a35a182 100644
--- a/www/attributes/kt-indicator.md
+++ b/www/attributes/hx-indicator.md
@@ -1,11 +1,11 @@
---
layout: layout.njk
-title: </> kutty - kt-indicator
+title: </> htmx - hx-indicator
---
-## `kt-indicator`
+## `hx-indicator`
-The `kt-indicator` attribute allows you to specify the element that will have the `kutty-request` class
+The `hx-indicator` attribute allows you to specify the element that will have the `htmx-request` class
added to it for the duration of the request. This can be used to show spinners or progress indicators
while the request is in flight.
@@ -15,26 +15,26 @@ Here is an example with a spinner adjacent to the button:
```html
<div>
- <button kt-post="/example" kt-indicator="#spinner">
+ <button hx-post="/example" hx-indicator="#spinner">
Post It!
</button>
- <img id="spinner" class="kutty-indicator" src="/img/bars.svg"/>
+ <img id="spinner" class="htmx-indicator" src="/img/bars.svg"/>
</div>
```
-When a request is in flight, this will cause the `kutty-request` class to be added to the `#spinner`
-image. The image also has the `kutty-indicator` class on it, which defines an opacity transition
+When a request is in flight, this will cause the `htmx-request` class to be added to the `#spinner`
+image. The image also has the `htmx-indicator` class on it, which defines an opacity transition
that will show the spinner:
```css
- .kutty-indicator{
+ .htmx-indicator{
opacity:0;
transition: opacity 500ms ease-in;
}
- .kutty-request .kutty-indicator{
+ .htmx-request .htmx-indicator{
opacity:1
}
- .kutty-request.kutty-indicator{
+ .htmx-request.htmx-indicator{
opacity:1
}
```
@@ -43,13 +43,13 @@ If you would prefer a different effect for showing the spinner you could define
CSS. Here is an example that uses `display` rather than opacity:
```css
- .kutty-indicator{
+ .htmx-indicator{
display:none;
}
- .kutty-request .my-indicator{
+ .htmx-request .my-indicator{
display:inline;
}
- .kutty-request.my-indicator{
+ .htmx-request.my-indicator{
display:inline;
}
```
@@ -57,14 +57,14 @@ CSS. Here is an example that uses `display` rather than opacity:
Note that the target of the `ic-indicator` selector need not be the exact element that you
want to show: it can be any element in the parent hierarchy of the indicator.
-Finally, note that the `kutty-request` class by default is added to the element causing
+Finally, note that the `htmx-request` class by default is added to the element causing
the request, so you can place an indicator inside of that element and not need to explictly
call it out with the `ic-indicator` attribute:
```html
-<button kt-post="/example">
+<button hx-post="/example">
Post It!
- <img class="kutty-indicator" src="/img/bars.svg"/>
+ <img class="htmx-indicator" src="/img/bars.svg"/>
</button>
```
@@ -72,13 +72,13 @@ call it out with the `ic-indicator` attribute:
This simulates what a spinner might look like in that situation:
-<button class="btn" kt-classes="toggle kutty-request:3s">
+<button class="btn" hx-classes="toggle htmx-request:3s">
Post It!
- <img class="kutty-indicator" src="/img/bars.svg"/>
+ <img class="htmx-indicator" src="/img/bars.svg"/>
</button>
### Notes
-* `kt-indicator` is inherited and can be placed on a parent element
-* In the absence of an explicit indicator, the `kutty-request` class will be added to the element triggering the
+* `hx-indicator` is inherited and can be placed on a parent element
+* In the absence of an explicit indicator, the `htmx-request` class will be added to the element triggering the
request \ No newline at end of file
diff --git a/www/attributes/kt-params.md b/www/attributes/hx-params.md
index b2d0f3f6..131d11a3 100644
--- a/www/attributes/kt-params.md
+++ b/www/attributes/hx-params.md
@@ -1,11 +1,11 @@
---
layout: layout.njk
-title: </> kutty - kt-params
+title: </> htmx - hx-params
---
-## `kt-params`
+## `hx-params`
-The `kt-params` attribute allows you to filter the parameters that will be submitted with an AJAX request.
+The `hx-params` attribute allows you to filter the parameters that will be submitted with an AJAX request.
The possible values of this attribute are:
@@ -15,7 +15,7 @@ The possible values of this attribute are:
* `<param-list>` - Include all the comma separated list of parameter names
```html
- <div kt-get="/example" kt-params="*">Get Some HTML, Including Params</div>
+ <div hx-get="/example" hx-params="*">Get Some HTML, Including Params</div>
```
This div will include all the parameters that a `POST` would, but they will be URL encoded
@@ -23,4 +23,4 @@ and included in the URL, as per usual with a `GET`.
### Notes
-* `kt-params` is inherited and can be placed on a parent element
+* `hx-params` is inherited and can be placed on a parent element
diff --git a/www/attributes/kt-patch.md b/www/attributes/hx-patch.md
index 7f59ddc1..6ece3541 100644
--- a/www/attributes/kt-patch.md
+++ b/www/attributes/hx-patch.md
@@ -1,15 +1,15 @@
---
layout: layout.njk
-title: </> kutty - kt-patch
+title: </> htmx - hx-patch
---
-## `kt-patch`
+## `hx-patch`
-The `kt-patch` attribute will cause an element to issue a `PATCH` to the specified URL and swap
+The `hx-patch` attribute will cause an element to issue a `PATCH` to the specified URL and swap
the HTML into the DOM using a swap strategy:
```html
-<button kt-patch="/account" kt-target="body">
+<button hx-patch="/account" hx-target="body">
Patch Your Account
</button>
```
@@ -19,9 +19,9 @@ This example will cause the `button` to issue a `PATCH` to `/account` and swap t
### Notes
-* `kt-patch` is not inherited
+* `hx-patch` is not inherited
* Since most browsers do not support issuing an actual `PATCH`, the request will actually be issued
as a `POST`, with the [`X-HTTP-Method-Override`](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields) header set to `PATCH`.
-* You can control the target of the swap using the [kt-target](/attributes/kt-target) attribute
-* You can control the swap strategy by using the [kt-swap](/attributes/kt-swap) attribute
-* You can control what event triggers the request with the [kt-trigger](/attributes/kt-trigger) attribute
+* You can control the target of the swap using the [hx-target](/attributes/hx-target) attribute
+* You can control the swap strategy by using the [hx-swap](/attributes/hx-swap) attribute
+* You can control what event triggers the request with the [hx-trigger](/attributes/hx-trigger) attribute
diff --git a/www/attributes/hx-post.md b/www/attributes/hx-post.md
new file mode 100644
index 00000000..992f13a2
--- /dev/null
+++ b/www/attributes/hx-post.md
@@ -0,0 +1,25 @@
+---
+layout: layout.njk
+title: </> htmx - hx-post
+---
+
+## `hx-post`
+
+The `hx-post` attribute will cause an element to issue a `POST` to the specified URL and swap
+the HTML into the DOM using a swap strategy:
+
+```html
+<button hx-post="/account/enable" hx-target="body">
+ Enable Your Account
+</button>
+```
+
+This example will cause the `button` to issue a `POST` to `/account/enable` and swap the returned HTML into
+ the `innerHTML` of the `body`.
+
+### Notes
+
+* `hx-post` is not inherited
+* You can control the target of the swap using the [hx-target](/attributes/hx-target) attribute
+* You can control the swap strategy by using the [hx-swap](/attributes/hx-swap) attribute
+* You can control what event triggers the request with the [hx-trigger](/attributes/hx-trigger) attribute
diff --git a/www/attributes/hx-prompt.md b/www/attributes/hx-prompt.md
new file mode 100644
index 00000000..ea2d1ff6
--- /dev/null
+++ b/www/attributes/hx-prompt.md
@@ -0,0 +1,21 @@
+---
+layout: layout.njk
+title: </> htmx - hx-prompt
+---
+
+## `hx-prompt`
+
+The `hx-prompt` attribute allows you to show a prompt before issuing a request. The value of
+the prompt will be included in the requst in the `X-HX-Prompt` header.
+
+Here is an example:
+
+```html
+<button hx-delete="/account" hx-prompt="Enter your account name to confirm deletion">
+ Delete My Account
+</button>
+```
+
+### Notes
+
+* `hx-prompt` is inherited and can be placed on a parent element
diff --git a/www/attributes/hx-push-url.md b/www/attributes/hx-push-url.md
new file mode 100644
index 00000000..674c1a62
--- /dev/null
+++ b/www/attributes/hx-push-url.md
@@ -0,0 +1,26 @@
+---
+layout: layout.njk
+title: </> htmx - hx-push-url
+---
+
+## `hx-push-url`
+
+The `hx-push-url` attribute allows you to "push" a new entry into the browser location bar, which creates
+a new history entry, allowing back-button and general history navigation. The possible values of this
+attribute are `true` and `false`.
+
+Here is an example:
+
+```html
+<div hx-get="/account" hx-push-url="true">
+ Go to My Account
+</div>
+```
+
+This will cause htmx to snapshot the current DOM to `localStorage` and push the URL `/account' into the browser
+location bar.
+
+### Notes
+
+* `hx-push-url` is inherited and can be placed on a parent element
+* see also the `X-HX-Push` response header
diff --git a/www/attributes/kt-put.md b/www/attributes/hx-put.md
index 6aa310f4..301980e3 100644
--- a/www/attributes/kt-put.md
+++ b/www/attributes/hx-put.md
@@ -1,15 +1,15 @@
---
layout: layout.njk
-title: </> kutty - kt-put
+title: </> htmx - hx-put
---
-## `kt-put`
+## `hx-put`
-The `kt-put` attribute will cause an element to issue a `PUT` to the specified URL and swap
+The `hx-put` attribute will cause an element to issue a `PUT` to the specified URL and swap
the HTML into the DOM using a swap strategy:
```html
-<button kt-put="/account" kt-target="body">
+<button hx-put="/account" hx-target="body">
Put Money In Your Account
</button>
```
@@ -19,9 +19,9 @@ This example will cause the `button` to issue a `PUT` to `/account` and swap the
### Notes
-* `kt-put` is not inherited
+* `hx-put` is not inherited
* Since most browsers do not support issuing an actual `PUT`, the request will actually be issued
as a `POST`, with the [`X-HTTP-Method-Override`](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields) header set to `PUT`.
-* You can control the target of the swap using the [kt-target](/attributes/kt-target) attribute
-* You can control the swap strategy by using the [kt-swap](/attributes/kt-swap) attribute
-* You can control what event triggers the request with the [kt-trigger](/attributes/kt-trigger) attribute
+* You can control the target of the swap using the [hx-target](/attributes/hx-target) attribute
+* You can control the swap strategy by using the [hx-swap](/attributes/hx-swap) attribute
+* You can control what event triggers the request with the [hx-trigger](/attributes/hx-trigger) attribute
diff --git a/www/attributes/kt-select.md b/www/attributes/hx-select.md
index 8a81143c..268efc5e 100644
--- a/www/attributes/kt-select.md
+++ b/www/attributes/hx-select.md
@@ -1,18 +1,18 @@
---
layout: layout.njk
-title: </> kutty - kt-select
+title: </> htmx - hx-select
---
-## `kt-select`
+## `hx-select`
-The `kt-select` attribute allows you to select the content you want swapped from a response. The value of
+The `hx-select` attribute allows you to select the content you want swapped from a response. The value of
this attribute is a CSS query selector of the element or elements to select from the response.
Here is an example that selects a subset of the response content:
```html
<div>
- <button kt-get="/info" kt-select="#info-details" kt-swap="outerHTML">
+ <button hx-get="/info" hx-select="#info-details" hx-swap="outerHTML">
Get Info!
</button>
</div>
@@ -23,4 +23,4 @@ which will replace the entire button in the DOM.
### Notes
-* `kt-select` is inherited and can be placed on a parent element
+* `hx-select` is inherited and can be placed on a parent element
diff --git a/www/attributes/kt-sse-src.md b/www/attributes/hx-sse-src.md
index 661e90b6..3f2eec5d 100644
--- a/www/attributes/kt-sse-src.md
+++ b/www/attributes/hx-sse-src.md
@@ -1,16 +1,16 @@
---
layout: layout.njk
-title: </> kutty - kt-sse-src
+title: </> htmx - hx-sse-src
---
-## `kt-sse-src`
+## `hx-sse-src`
-The `kt-sse-src` attribute establishes a [Server Sent Event](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
+The `hx-sse-src` attribute establishes a [Server Sent Event](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
`EventSource`, allowing children of the element to register for server sent event triggers.
```html
- <div kt-sse-src="/event_stream">
- <div kt-get="/chatroom" kt-trigger="sse:chatter">
+ <div hx-sse-src="/event_stream">
+ <div hx-get="/chatroom" hx-trigger="sse:chatter">
...
</div>
</div>
@@ -21,4 +21,4 @@ a `GET` to the `/chatroom` url whenever the `chatter` event is seen.
### Notes
-* `kt-sse-src` is not inherited
+* `hx-sse-src` is not inherited
diff --git a/www/attributes/kt-swap-oob.md b/www/attributes/hx-swap-oob.md
index c772a23d..f5c7e4bc 100644
--- a/www/attributes/kt-swap-oob.md
+++ b/www/attributes/hx-swap-oob.md
@@ -1,11 +1,11 @@
---
layout: layout.njk
-title: </> kutty - kt-swap-oob
+title: </> htmx - hx-swap-oob
---
-## `kt-swap-oob`
+## `hx-swap-oob`
-The `kt-swap-oob` attribute allows you specify that some content in a response should be swapped into
+The `hx-swap-oob` attribute allows you specify that some content in a response should be swapped into
the DOM somewhere other than the target, that is "Out of Band". This allows you to piggy back updates
to other element updates on a response.
@@ -15,7 +15,7 @@ Consider the following response HTML:
<div>
...
</div>
-<div id="alerts" kt-swap-oob="true">
+<div id="alerts" hx-swap-oob="true">
Saved!
</div>
@@ -26,5 +26,5 @@ as a replacement for the element with the id `alerts`, and will not end up in th
### Notes
-* `kt-swap-oob` is not inherited
-* `kt-swap-oob` is only supported on top level elements in the response, not children
+* `hx-swap-oob` is not inherited
+* `hx-swap-oob` is only supported on top level elements in the response, not children
diff --git a/www/attributes/kt-swap.md b/www/attributes/hx-swap.md
index 577742f2..42f46e5d 100644
--- a/www/attributes/kt-swap.md
+++ b/www/attributes/hx-swap.md
@@ -1,12 +1,12 @@
---
layout: layout.njk
-title: </> kutty - kt-swap
+title: </> htmx - hx-swap
---
-## `kt-swap`
+## `hx-swap`
-The `kt-swap` attribute allows you to specify how the response will be swapped in relative to the
-[target](/attributes/kt-target) of an AJAX request.
+The `hx-swap` attribute allows you to specify how the response will be swapped in relative to the
+[target](/attributes/hx-target) of an AJAX request.
The possible values of this attribute are:
@@ -24,17 +24,17 @@ specification.
So in this code:
```html
- <div kt-get="/example" kt-swap="afterend">Get Some HTML & Append It</div>
+ <div hx-get="/example" hx-swap="afterend">Get Some HTML & Append It</div>
```
The `div` will issue a request to `/example` and append the returned content after the `div`
-You can modify the amount of time that kutty will wait after receiving a response to swap the content
+You can modify the amount of time that htmx will wait after receiving a response to swap the content
by including a `swap` modifier:
```html
<!-- this will wait 1s before doing the swap after it is received -->
- <div kt-get="/example" kt-swap="innerHTML swap:1s">Get Some HTML & Append It</div>
+ <div hx-get="/example" hx-swap="innerHTML swap:1s">Get Some HTML & Append It</div>
```
Similarly, you can modify the time between the swap and the settle logic by including a `settle`
@@ -42,14 +42,14 @@ modifier:
```html
<!-- this will wait 1s before doing the swap after it is received -->
- <div kt-get="/example" kt-swap="innerHTML settle:1s">Get Some HTML & Append It</div>
+ <div hx-get="/example" hx-swap="innerHTML settle:1s">Get Some HTML & Append It</div>
```
-These attributes can be used to synchronize kutty with the timing of CSS transition effects.
+These attributes can be used to synchronize htmx with the timing of CSS transition effects.
### Notes
-* `kt-swap` is inherited and can be placed on a parent element
+* `hx-swap` is inherited and can be placed on a parent element
* The default value of this attribute is `innerHTML`
* The default swap delay is 0ms
* The default settle delay is 100ms
diff --git a/www/attributes/kt-target.md b/www/attributes/hx-target.md
index fcd83e5f..2fd409d3 100644
--- a/www/attributes/kt-target.md
+++ b/www/attributes/hx-target.md
@@ -1,11 +1,11 @@
---
layout: layout.njk
-title: </> kutty - kt-target
+title: </> htmx - hx-target
---
-## `kt-target`
+## `hx-target`
-The `kt-target` attribute allows you to target a different element for swapping than the one issuing the AJAX
+The `hx-target` attribute allows you to target a different element for swapping than the one issuing the AJAX
request. The value of this attribute can be:
* a CSS query selector of the element to target
@@ -18,7 +18,7 @@ Here is an example that targets a div:
```html
<div>
<div id="response-div"></div>
- <button kt-post="/register" kt-target="#response-div" kt-swap="beforeEnd">
+ <button hx-post="/register" hx-target="#response-div" hx-swap="beforeEnd">
Register!
</button>
</div>
@@ -28,4 +28,4 @@ The response from the `/register` url will be appended to the `div` with the id
### Notes
-* `kt-target` is inherited and can be placed on a parent element
+* `hx-target` is inherited and can be placed on a parent element
diff --git a/www/attributes/kt-trigger.md b/www/attributes/hx-trigger.md
index 4ccb3093..35c0d63e 100644
--- a/www/attributes/kt-trigger.md
+++ b/www/attributes/hx-trigger.md
@@ -1,11 +1,11 @@
---
layout: layout.njk
-title: </> kutty - kt-trigger
+title: </> htmx - hx-trigger
---
-## `kt-trigger`
+## `hx-trigger`
-The `kt-trigger` attribute allows you to specify what triggers an AJAX request. A trigger
+The `hx-trigger` attribute allows you to specify what triggers an AJAX request. A trigger
value can be one of the following:
* An event name (e.g. "click") followed by a set of event modifiers
@@ -17,7 +17,7 @@ value can be one of the following:
A standard event, such as `click` can be specified as the trigger like so:
```html
-<div kt-get="/clicked" kt-trigger="click">Click Me</div>
+<div hx-get="/clicked" hx-trigger="click">Click Me</div>
```
Standard events can also have modifiers that change how they behave. The modifiers are:
@@ -32,13 +32,13 @@ and the user hasn't typed anything new for 1 second:
```html
<input name="q"
- kt-get="/search" kt-trigger="keyup changed delay:1s"
- kt-target="#search-results"/>
+ hx-get="/search" hx-trigger="keyup changed delay:1s"
+ hx-target="#search-results"/>
```
The response from the `/register` url will be appended to the `div` with the id `response-div`.
-There are two special events that are non-standard that kutty supports:
+There are two special events that are non-standard that htmx supports:
* `load` - triggered on load (useful for lazy-loading something)
* `reveal` - triggered when an element is scrolled into the viewport (also useful for lazy-loading)
@@ -48,7 +48,7 @@ There are two special events that are non-standard that kutty supports:
By using the syntax `every <timing declaration>` you can have an element poll periodically:
```html
-<div kt-get="/latest_updates" kt-trigger="every 1s">
+<div hx-get="/latest_updates" hx-trigger="every 1s">
Nothing Yet!
</div>
```
@@ -64,8 +64,8 @@ an element can register to be triggered by a specific SSE event using the syntax
Here is an example:
```html
- <div kt-sse-src="/event_stream">
- <div kt-get="/chatroom" kt-trigger="sse:chatter">
+ <div hx-sse-src="/event_stream">
+ <div hx-get="/chatroom" hx-trigger="sse:chatter">
...
</div>
</div>
@@ -76,4 +76,4 @@ a `GET` to the `/chatroom` url whenever the `chatter` event is seen.
### Notes
-* `kt-trigger` is not inherited \ No newline at end of file
+* `hx-trigger` is not inherited \ No newline at end of file
diff --git a/www/attributes/kt-error-url.md b/www/attributes/kt-error-url.md
deleted file mode 100644
index 58f8f7d1..00000000
--- a/www/attributes/kt-error-url.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-layout: layout.njk
-title: </> kutty - kt-error-url
----
-
-## `kt-error-url`
-
-The `kt-error-url` attribute allows you to send client-side errors to a specified URL. It is typically put on the
-body tag, so all errors are caught and send to the server.
-
-```html
-<body kt-error-url="/errors">\
-
-</body>
-```
-When a client side error is caught by kutty it will be `POST`-ed to the given URL, with the following JSON format:
-
-```json
- { "elt": elt.id, "event": eventName, "detail" : detail }
-```
-
-### Notes
-
-* `kt-error-url` is inherited and can be placed on a parent element
diff --git a/www/attributes/kt-get.md b/www/attributes/kt-get.md
deleted file mode 100644
index e2f5c65c..00000000
--- a/www/attributes/kt-get.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-layout: layout.njk
-title: </> kutty - kt-get
----
-
-## `kt-get`
-
-The `kt-get` attribute will cause an element to issue a `GET` to the specified URL and swap
-the HTML into the DOM using a swap strategy:
-
-```html
- <div kt-get="/example">Get Some HTML</div>
-```
-
-This example will cause the `div` to issue a `GET` to `/example` and swap the returned HTML into
- the `innerHTML` of the `div`.
-
-### Notes
-
-* `kt-get` is not inherited
-* By default `kt-get` does not include any parameters. You can use the [kt-params](/attributes/kt-params)
- attribute to change this
-* You can control the target of the swap using the [kt-target](/attributes/kt-target) attribute
-* You can control the swap strategy by using the [kt-swap](/attributes/kt-swap) attribute
-* You can control what event triggers the request with the [kt-trigger](/attributes/kt-trigger) attribute
diff --git a/www/attributes/kt-post.md b/www/attributes/kt-post.md
deleted file mode 100644
index 6a4d06ef..00000000
--- a/www/attributes/kt-post.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-layout: layout.njk
-title: </> kutty - kt-post
----
-
-## `kt-post`
-
-The `kt-post` attribute will cause an element to issue a `POST` to the specified URL and swap
-the HTML into the DOM using a swap strategy:
-
-```html
-<button kt-post="/account/enable" kt-target="body">
- Enable Your Account
-</button>
-```
-
-This example will cause the `button` to issue a `POST` to `/account/enable` and swap the returned HTML into
- the `innerHTML` of the `body`.
-
-### Notes
-
-* `kt-post` is not inherited
-* You can control the target of the swap using the [kt-target](/attributes/kt-target) attribute
-* You can control the swap strategy by using the [kt-swap](/attributes/kt-swap) attribute
-* You can control what event triggers the request with the [kt-trigger](/attributes/kt-trigger) attribute
diff --git a/www/attributes/kt-prompt.md b/www/attributes/kt-prompt.md
deleted file mode 100644
index cce04cfd..00000000
--- a/www/attributes/kt-prompt.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-layout: layout.njk
-title: </> kutty - kt-prompt
----
-
-## `kt-prompt`
-
-The `kt-prompt` attribute allows you to show a prompt before issuing a request. The value of
-the prompt will be included in the requst in the `X-KT-Prompt` header.
-
-Here is an example:
-
-```html
-<button kt-delete="/account" kt-prompt="Enter your account name to confirm deletion">
- Delete My Account
-</button>
-```
-
-### Notes
-
-* `kt-prompt` is inherited and can be placed on a parent element
diff --git a/www/attributes/kt-push-url.md b/www/attributes/kt-push-url.md
deleted file mode 100644
index 03d3a047..00000000
--- a/www/attributes/kt-push-url.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-layout: layout.njk
-title: </> kutty - kt-push-url
----
-
-## `kt-push-url`
-
-The `kt-push-url` attribute allows you to "push" a new entry into the browser location bar, which creates
-a new history entry, allowing back-button and general history navigation. The possible values of this
-attribute are `true` and `false`.
-
-Here is an example:
-
-```html
-<div kt-get="/account" kt-push-url="true">
- Go to My Account
-</div>
-```
-
-This will cause kutty to snapshot the current DOM to `localStorage` and push the URL `/account' into the browser
-location bar.
-
-### Notes
-
-* `kt-push-url` is inherited and can be placed on a parent element
-* see also the `X-KT-Push` response header
diff --git a/www/css/prism-kutty.css b/www/css/prism-htmx.css
index fffdcf6f..ce47b054 100644
--- a/www/css/prism-kutty.css
+++ b/www/css/prism-htmx.css
@@ -1,5 +1,5 @@
/**
- * kutty theme for JavaScript, CSS and HTML
+ * htmx theme for JavaScript, CSS and HTML
* based on okaidia theme by ocodia
*/
diff --git a/www/docs.md b/www/docs.md
index 2b4758f7..22236376 100644
--- a/www/docs.md
+++ b/www/docs.md
@@ -1,6 +1,6 @@
---
layout: layout.njk
-title: </> kutty - high power tools for html
+title: </> htmx - high power tools for html
---
<div class="row">
<div class="2 col nav">
@@ -32,12 +32,12 @@ title: </> kutty - high power tools for html
</div>
<div class="10 col">
-## <a name="introduction"></a>[Kutty in a Nutshell](#introduction)
+## <a name="introduction"></a>[Htmx in a Nutshell](#introduction)
-Kutty is a library that allows you to access modern browser features directly from HTML, rather than using
+Htmx is a library that allows you to access modern browser features directly from HTML, rather than using
javascript.
-To understand kutty, first lets take a look at an anchor tag:
+To understand htmx, first lets take a look at an anchor tag:
``` html
<a href="/blog">Blog</a>
@@ -51,20 +51,20 @@ This anchor tag tells a browser:
With that in mind, consider the following bit of HTML:
``` html
- <div kt-post="/clicked"
- kt-trigger="click"
- kt-target="#parent-div"
- kt-swap="outerHTML">
+ <div hx-post="/clicked"
+ hx-trigger="click"
+ hx-target="#parent-div"
+ hx-swap="outerHTML">
Click Me!
</div>
```
-This tells kutty:
+This tells htmx:
> "When a user clicks on this div, issue an HTTP POST request to '/clicked' and use the content from the response
> to replace the element with the id `parent-div` in the DOM"
-Kutty extends and generalizes the core idea of HTML as a hypertext, opening up many more possibilities directly
+Htmx extends and generalizes the core idea of HTML as a hypertext, opening up many more possibilities directly
within the language:
* Now any element, not just anchors and forms, can issue an HTTP request
@@ -72,37 +72,37 @@ within the language:
* Now any [HTTP verb](https://en.wikipedia.org/wiki/HTTP_Verbs), not just `GET` and `POST`, can be used
* Now any element, not just the entire window, can be the target for update by the request
-Note that when you are using kutty, on the server side you respond with *HTML*, not *JSON*. This keeps you firmly
+Note that when you are using htmx, on the server side you respond with *HTML*, not *JSON*. This keeps you firmly
within the [original web programming model]((https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm)),
using [Hypertext As The Engine Of Application State](https://en.wikipedia.org/wiki/HATEOAS)
without even needing to really understand that concept.
-It's worth mentioning that, if you prefer, you can use the `data-` prefix when using kutty:
+It's worth mentioning that, if you prefer, you can use the `data-` prefix when using htmx:
``` html
- <a data-kt-post="/click">Click Me!</a>
+ <a data-hx-post="/click">Click Me!</a>
```
## <a name="installing"></a> [Installing](#installing)
-Kutty is a dependency-free javascript library.
+Htmx is a dependency-free javascript library.
-It can be used via [NPM](https://www.npmjs.com/) as "`kutty.org`" or downloaded or included from
-[unpkg](https://unpkg.com/browse/kutty.org/) or your other favorite NPM-based CDN:
+It can be used via [NPM](https://www.npmjs.com/) as "`htmx.org`" or downloaded or included from
+[unpkg](https://unpkg.com/browse/htmx.org/) or your other favorite NPM-based CDN:
``` html
- <script src="https://unpkg.com/kutty.org@0.0.2"></script>
+ <script src="https://unpkg.com/htmx.org@0.0.2"></script>
```
## <a name="ajax"></a> [AJAX](#ajax)
-The core feature of kutty is a set of attributes that allow you to issue AJAX requests directly from HTML:
+The core feature of htmx is a set of attributes that allow you to issue AJAX requests directly from HTML:
-* [kt-get](/attributes/kt-get) - Issues a `GET` request to the given URL
-* [kt-post](/attributes/kt-post) - Issues a `POST` request to the given URL
-* [kt-put](/attributes/kt-put) - Issues a `PUT` request to the given URL
-* [kt-patch](/attributes/kt-patch) - Issues a `PATCH` request to the given URL
-* [kt-delete](/attributes/kt-delete) - Issues a `DELETE` request to the given URL
+* [hx-get](/attributes/hx-get) - Issues a `GET` request to the given URL
+* [hx-post](/attributes/hx-post) - Issues a `POST` request to the given URL
+* [hx-put](/attributes/hx-put) - Issues a `PUT` request to the given URL
+* [hx-patch](/attributes/hx-patch) - Issues a `PATCH` request to the given URL
+* [hx-delete](/attributes/hx-delete) - Issues a `DELETE` request to the given URL
(Since most browsers only support issuing `GET` and `POST`, a request with one of the other three methods will
actually be issued as a `POST`, with the `X-HTTP-Method-Override` header set to the desired method.)
@@ -111,7 +111,7 @@ Each of these attributes takes a URL to issue an AJAX request to. The element w
type to the given URL when the element is [triggered](#triggers):
```html
- <div kt-put="/messages">
+ <div hx-put="/messages">
Put To Messages
</div>
```
@@ -128,13 +128,13 @@ By default, AJAX requests are triggered by the "natural" event of an element:
* `form` is triggered on the `submit` event
* everything else is triggered by the `click` event
-If you want different behavior you can use the [kt-trigger](/attributes/kt-trigger)
+If you want different behavior you can use the [hx-trigger](/attributes/hx-trigger)
attribute to specify which event will cause the request.
Here is a `div` that posts to `/mouse_entered` when a mouse enters it:
```html
- <div kt-post="/mouse_entered" kt-trigger="mouseenter">
+ <div hx-post="/mouse_entered" hx-trigger="mouseenter">
[Here Mouse, Mouse!]
</div>
```
@@ -142,7 +142,7 @@ Here is a `div` that posts to `/mouse_entered` when a mouse enters it:
If you want a request to only happen once, you can use the `once` modifier for the trigger:
```html
- <div kt-post="/mouse_entered" kt-trigger="mouseenter once"">
+ <div hx-post="/mouse_entered" hx-trigger="mouseenter once"">
[Here Mouse, Mouse!]
</div>
```
@@ -157,9 +157,9 @@ You can use these two attributes to implement a common UX pattern, [Active Searc
```html
<input type="text" name="q"
- kt-get="/trigger_delay"
- kt-trigger="keyup changed delay:500ms"
- kt-target="#search-results"
+ hx-get="/trigger_delay"
+ hx-trigger="keyup changed delay:500ms"
+ hx-target="#search-results"
placeholder="Search..."/>
<div id="search-results"></div>
```
@@ -169,7 +169,7 @@ into the `div` with the id `search-results`.
#### <a name="special-events"></a> [Special Events](#special-events)
-kutty provides a few special events for use in [kt-trigger](/attributes/kt-trigger):
+htmx provides a few special events for use in [hx-trigger](/attributes/hx-trigger):
* `load` - fires once when the element is first loaded
* `revealed` - fires once when an element first scrolls into the viewport
@@ -179,14 +179,14 @@ You can also use custom events to trigger requests if you have an advanced use c
#### <a name="polling"></a> [Polling](#polling)
If you want an element to poll the given URL rather than wait for an event, you can use the `every` syntax
-with the [`kt-trigger`](/attributes/kt-trigger/) attribute:
+with the [`hx-trigger`](/attributes/hx-trigger/) attribute:
```html
- <div kt-get="/news" trigger="every 2s">
+ <div hx-get="/news" trigger="every 2s">
</div>
```
-This tells kutty
+This tells htmx
> Every 2 seconds, issue a GET to /news and load the response into the div
@@ -195,13 +195,13 @@ and the element will cancel the polling.
#### <a name="load_polling"></a> [Load Polling](#load_polling)
-Another technique that can be used to achieve polling in kutty is "load polling", where an element specifies
+Another technique that can be used to achieve polling in htmx is "load polling", where an element specifies
an `load` trigger along with a delay, and replaces itself with the response:
```html
-<div kt-get="/messages"
- kt-trigger="load delay:1s"
- kt-swap="outerHTML">
+<div hx-get="/messages"
+ hx-trigger="load delay:1s"
+ hx-swap="outerHTML">
</div>
```
@@ -218,9 +218,9 @@ when you are showing the user a [progress bar](/examples/progress-bar).
a way for servers to send events to browsers. It provides a higher-level mechanism for communication between the
server and the browser than websockets.
-If you want an element to respond to a Server Sent Event via kutty, you need to do two things:
+If you want an element to respond to a Server Sent Event via htmx, you need to do two things:
-1. Define an SSE source. To do this, add a [kt-sse-src](/attributes/kt-sse-src) attribute on a parent element
+1. Define an SSE source. To do this, add a [hx-sse-src](/attributes/hx-sse-src) attribute on a parent element
that specifies the URL from which Server Sent Events will be received.
2. Specify the Server Sent Event that will trigger the element, with the prefix `sse:`
@@ -228,8 +228,8 @@ that specifies the URL from which Server Sent Events will be received.
Here is an example:
```html
- <body kt-sse-src="/sse_messages">
- <div trigger="sse:new_news" kt-get="/news"></div>
+ <body hx-sse-src="/sse_messages">
+ <div trigger="sse:new_news" hx-get="/news"></div>
</body>
```
@@ -239,49 +239,49 @@ notify the div if there was new news to get, rather than the steady requests tha
### <a name="indicators"></a> [Request Indicators](#indicators)
When an AJAX request is issued it is often good to let the user know that something is happening since the browser
-will not give them any feedback. You can accomplish this in kutty by using `kutty-indicator` class.
+will not give them any feedback. You can accomplish this in htmx by using `htmx-indicator` class.
-The `kutty-indicator` class is defined so that the opacity of any element with this class is 0 by default, making it invisible
+The `htmx-indicator` class is defined so that the opacity of any element with this class is 0 by default, making it invisible
but present in the DOM.
-When kutty issues a request, it will put a `kutty-request` class onto an element (either the requesting element or
-another element, if specified). The `kutty-request` class will cause a child element with the `kutty-indicator` class
+When htmx issues a request, it will put a `htmx-request` class onto an element (either the requesting element or
+another element, if specified). The `htmx-request` class will cause a child element with the `htmx-indicator` class
on it to transition to an opacity of 1, showing the indicator.
```html
- <button kt-get="/click">
+ <button hx-get="/click">
Click Me!
- <img class="kutty-indicator" src="/spinner.gif"/>
+ <img class="htmx-indicator" src="/spinner.gif"/>
</button>
```
-Here we have a button. When it is clicked the `kutty-request` class will be added to it, which will reveal the spinner
+Here we have a button. When it is clicked the `htmx-request` class will be added to it, which will reveal the spinner
gif element. (I like [SVG spinners](http://samherbert.net/svg-loaders/) these days.)
-While the `kutty-indicator` class uses opacity to hide and show the progress indicator, if you would prefer another mechanism
+While the `htmx-indicator` class uses opacity to hide and show the progress indicator, if you would prefer another mechanism
you can create your own CSS transition like so:
```css
- .kutty-indicator{
+ .htmx-indicator{
display:none;
}
- .kutty-request .my-indicator{
+ .htmx-request .my-indicator{
display:inline;
}
- .kutty-request.my-indicator{
+ .htmx-request.my-indicator{
display:inline;
}
```
-If you want the `kutty-request` class added to a different element, you can use the [kt-indicator](/attributes/kt-indicator)
+If you want the `htmx-request` class added to a different element, you can use the [hx-indicator](/attributes/hx-indicator)
attribute with a CSS selector to do so:
```html
<div>
- <button kt-get="/click" kt-indicator="#indicator">
+ <button hx-get="/click" hx-indicator="#indicator">
Click Me!
</button>
- <img id="indicator" class="kutty-indicator" src="/spinner.gif"/>
+ <img id="indicator" class="htmx-indicator" src="/spinner.gif"/>
</div>
```
@@ -291,13 +291,13 @@ and had the same effect.
### <a name="targets"></a> [Targets](#targets)
If you want the response to be loaded into a different element other than the one that made the request, you can
-use the [kt-target](/attributes/kt-target) attribute, which takes a CSS selector. Looking back at our Live Search example:
+use the [hx-target](/attributes/hx-target) attribute, which takes a CSS selector. Looking back at our Live Search example:
```html
<input type="text" name="q"
- kt-get="/trigger_delay"
- kt-trigger="keyup delay:500ms changed"
- kt-target="#search-results"
+ hx-get="/trigger_delay"
+ hx-trigger="keyup delay:500ms changed"
+ hx-target="#search-results"
placeholder="Search..."/>
<div id="search-results"></div>
```
@@ -307,8 +307,8 @@ input tag.
### <a name="swapping"></a> [Swapping](#swapping)
-kutty offers a few different ways to swap the HTML returned into the DOM. By default, the content replaces the
-`innerHTML` of the target element. You can modify this by using the [kt-swap](/attributes/kt-swap) attribute
+htmx offers a few different ways to swap the HTML returned into the DOM. By default, the content replaces the
+`innerHTML` of the target element. You can modify this by using the [hx-swap](/attributes/hx-swap) attribute
with any of the following values:
* `innerHTML` - the default, puts the content inside the target element
@@ -321,10 +321,10 @@ with any of the following values:
#### <a name="oob_swaps"></a>[Out of Band Swaps](#oob_swaps)
If you want to swap content from a response directly into the DOM by using the `id` attribute you can use the
-[kt-swap-oob](/attributes/kt-swap-oob) attribute in the *response* html:
+[hx-swap-oob](/attributes/hx-swap-oob) attribute in the *response* html:
```html
- <div id="message" kt-swap-oob="true">Swap me directly!</div>
+ <div id="message" hx-swap-oob="true">Swap me directly!</div>
Additional Content
```
@@ -337,7 +337,7 @@ Note that out of band elements must be in the top level of the response, and not
#### Selecting Content To Swap
-If you want to select a subset of the response HTML to swap into the target, you can use the [kt-select](/attributes/kt-select)
+If you want to select a subset of the response HTML to swap into the target, you can use the [hx-select](/attributes/hx-select)
attribute, which takes a CSS selector and selects the matching elements from the response.
### <a name="parameters"></a> [Parameters](#parameters)
@@ -348,153 +348,153 @@ will include the values of all inputs within it.
Additionally, if the element causes a non-`GET` request, the values of all the inputs of the nearest enclosing form
will be included.
-If you wish to include the values of other elements, you can use the [kt-include](/attributes/kt-include) attribute
+If you wish to include the values of other elements, you can use the [hx-include](/attributes/hx-include) attribute
with a CSS selector of all the elements whose values you want to include in the request.
-If you wish to filter out some parameters you can use the [kt-params](/attributes/kt-params) attribute.
+If you wish to filter out some parameters you can use the [hx-params](/attributes/hx-params) attribute.
-Finally, if you want to programatically modify the parameters, you can use the [configRequest.kutty](/events#configRequest.kutty)
+Finally, if you want to programatically modify the parameters, you can use the [configRequest.htmx](/events#configRequest.htmx)
event.
## <a name="history"></a> [History Support](#history)
-Kutty provides a simple mechanism for interacting with the [browser history API](https://developer.mozilla.org/en-US/docs/Web/API/History_API):
+Htmx provides a simple mechanism for interacting with the [browser history API](https://developer.mozilla.org/en-US/docs/Web/API/History_API):
If you want a given element to push its request URL into the browser navigation bar and add the current state of the page
-to the browser's history, include the [kt-push](/attributes/kt-push) attribute:
+to the browser's history, include the [hx-push](/attributes/hx-push) attribute:
```html
- <a kt-get="/blog" kt-push="true">Blog</a>
+ <a hx-get="/blog" hx-push="true">Blog</a>
```
-When a user clicks on this link, kutty will snapshot the current DOM and store it before it makes a request to /blog.
+When a user clicks on this link, htmx will snapshot the current DOM and store it before it makes a request to /blog.
It then does the swap and pushes a new location onto the history stack.
-When a user hits the back button, kutty will retrieve the old content from storage and swap it back into the target,
+When a user hits the back button, htmx will retrieve the old content from storage and swap it back into the target,
simulating "going back" to the previous state.
### Specifying History Snapshot Element
-By default, kutty will use the `body` to take and restore the history snapshop from. This is usually the right thing, but
-if you want to use a narrower element for snapshotting you can use the [kt-history-element](/attributes/kt-history-element)
+By default, htmx will use the `body` to take and restore the history snapshop from. This is usually the right thing, but
+if you want to use a narrower element for snapshotting you can use the [hx-history-element](/attributes/hx-history-element)
attribute to specify a different one.
Careful: this element will need to be on all pages or restoring from history won't work reliably.
## <a name="requests">[Requests &amp; Responses](#requests)
-Kutty expects responses to the AJAX requests it makes to be HTML, typically HTML fragments (although a full HTML
-document, matched with a [kt-select](/attributes/kt-select) tag can be useful too). Kutty will then swap the returned
+Htmx expects responses to the AJAX requests it makes to be HTML, typically HTML fragments (although a full HTML
+document, matched with a [hx-select](/attributes/hx-select) tag can be useful too). Htmx will then swap the returned
HTML into the document at the target specified and with the swap strategy specified.
Sometimes you might want to do nothing in the swap, but still perhaps trigger a client side event ([see below](#response-headers)).
-For this situation you can return a `204 - No Content` response code, and kutty will ignore the content of the response.
+For this situation you can return a `204 - No Content` response code, and htmx will ignore the content of the response.
-In the event of an error response from the server (e.g. a 404 or a 501), kutty will trigger the [`responseError.kutty`](/events#responseError.kutty)
+In the event of an error response from the server (e.g. a 404 or a 501), htmx will trigger the [`responseError.htmx`](/events#responseError.htmx)
event, which you can handle.
-In the event of a connection error, the `sendError.kutty` event will be triggered.
+In the event of a connection error, the `sendError.htmx` event will be triggered.
### <a name="request-header"></a> [Request Headers](#request-headers)
-kutty includes a number of useful headers in requests:
-
-* `X-KT-Request` - will be set to "true"
-* `X-KT-Trigger` - will be set to the id of the element that triggered the request
-* `X-KT-Trigger-Name` - will be set to the name of the element that triggered the request
-* `X-KT-Target` - will be set to the id of the target element
-* `X-KT-Current-URL` - will be set to the URL of the browser
-* `X-KT-Prompt` - will be set to the value entered by the user when prompted via [kt-prompt](/attributes/kt-prompt)
-* `X-KT-Event-Target` - the id of the original target of the event that triggered the request
-* `X-KT-Active-Element` - the id of the current active element
-* `X-KT-Active-Element-Name` - the name of the current active element
-* `X-KT-Active-Element-Value` - the value of the current active element
+htmx includes a number of useful headers in requests:
+
+* `X-HX-Request` - will be set to "true"
+* `X-HX-Trigger` - will be set to the id of the element that triggered the request
+* `X-HX-Trigger-Name` - will be set to the name of the element that triggered the request
+* `X-HX-Target` - will be set to the id of the target element
+* `X-HX-Current-URL` - will be set to the URL of the browser
+* `X-HX-Prompt` - will be set to the value entered by the user when prompted via [hx-prompt](/attributes/hx-prompt)
+* `X-HX-Event-Target` - the id of the original target of the event that triggered the request
+* `X-HX-Active-Element` - the id of the current active element
+* `X-HX-Active-Element-Name` - the name of the current active element
+* `X-HX-Active-Element-Value` - the value of the current active element
* `X-HTTP-Method-Override` - the HTTP verb for non-`GET` and `POST` requests
### <a name="response-header"></a> [Response Headers](#response-headers)
-kutty supports two special response headers:
+htmx supports two special response headers:
-* `X-KT-Trigger` - can be used to trigger client side events, see the [documentation](/headers/x-kt-trigger) for examples.
-* `X-KT-Push` - can be used to push a new URL into the browsers address bar
+* `X-HX-Trigger` - can be used to trigger client side events, see the [documentation](/headers/x-hx-trigger) for examples.
+* `X-HX-Push` - can be used to push a new URL into the browsers address bar
### Request Order of Operations
-The order of operations in a kutty request are:
+The order of operations in a htmx request are:
* The element is triggered and begins a request
* Values are gathered for the request
- * The `kutty-request` class is applied to the appropriate elements
+ * The `htmx-request` class is applied to the appropriate elements
* The request is then issued asynchronously via AJAX
- * Upon getting a response the target element is marked with the `kutty-swapping` class
- * An optional swap delay is applied (see the [kt-swap-delay](/attributes/kt-swap-delay) attribute)
+ * Upon getting a response the target element is marked with the `htmx-swapping` class
+ * An optional swap delay is applied (see the [hx-swap-delay](/attributes/hx-swap-delay) attribute)
* The actual content swap is done
- * the `kutty-swapping` class is removed from the target
- * the `kutty-settling` class is applied to the target
+ * the `htmx-swapping` class is removed from the target
+ * the `htmx-settling` class is applied to the target
* A settle delay is done (default: 100ms)
* The DOM is settled
- * the `kutty-settling` class is removed from the target
+ * the `htmx-settling` class is removed from the target
-You can use the `kutty-swapping` and `kutty-settling` classes to create
+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.
## Miscellaneous Attributes
-In addition to the core AJAX functionality, kutty also has a few other tricks up its sleeve that help you build
+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
-Kutty supports an attribute, [kt-classes](/attributes/kt-classes) that allows you to add, remove and toggle classes after
+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 kt-classes="add foo"/>
+<div hx-classes="add foo"/>
<!-- removes the class "bar" after 1s -->
-<div kt-classes="remove bar:1s"/>
+<div hx-classes="remove bar:1s"/>
<!-- removes the class "bar" after 1s
then adds the class "foo" 1s after that -->
-<div kt-classes="remove bar:1s, add foo:1s"/>
+<div hx-classes="remove bar:1s, add foo:1s"/>
<!-- removes the class "bar" and adds
class "foo" after 1s -->
-<div kt-classes="remove bar:1s & add foo:1s"/>
+<div hx-classes="remove bar:1s & add foo:1s"/>
<!-- toggles the class "foo" every 1s -->
-<div kt-classes="toggle foo:1s"/>
+<div hx-classes="toggle foo:1s"/>
```
-Full documentation is available [on the documentation page.](/attributes/kt-classes)
+Full documentation is available [on the documentation page.](/attributes/hx-classes)
### Boosting
-Kutty supports "boosting" regular HTML anchors and forms with the [kt-boost](/attributes/kt-boost) attribute. This
+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="events"></a> [Events & Logging](#events)
-Kutty has an extensive events mechanism, which doubles as the logging system.
+Htmx has an extensive events mechanism, which doubles as the logging system.
-If you want to register for a given kutty event you can use the following javascript:
+If you want to register for a given htmx event you can use the following javascript:
```javascript
- kutty.on("load.kutty", function(evt) {
+ htmx.on("load.htmx", function(evt) {
myJavascriptLib.init(evt.details.elt);
});
```
-This event is fired every time an element is loaded into the DOM by kutty, and is effectively the load event. In
+This event is fired every time an element is loaded into the DOM by htmx, and is effectively the load event. In
fact this is so common, you can use the helper function:
```javascript
- kutty.onLoad(function(target) {
+ htmx.onLoad(function(target) {
myJavascriptLib.init(target);
});
```
@@ -504,46 +504,46 @@ The full set of events can be seen [on the reference page](/reference#events).
### Logging
-If you set a logger at `kutty.logger`, every event will be logged. This can be very useful for troubleshooting:
+If you set a logger at `htmx.logger`, every event will be logged. This can be very useful for troubleshooting:
```javascript
- kutty.logger = function(elt, event, data) {
+ htmx.logger = function(elt, event, data) {
if(console) {
console.log(event, elt, data);
}
}
```
-Kutty can also send errors to a URL that is specified with the [kt-error-url](/attributes/kt-error-url) attributes. This can be useful for debugging client-side issues.
+Htmx can also send errors to a URL that is specified with the [hx-error-url](/attributes/hx-error-url) attributes. This can be useful for debugging client-side issues.
-Kutty includes a helper method:
+Htmx includes a helper method:
```javascript
- kutty.logAll();
+ htmx.logAll();
```
if you want to log everything while developing.
-## <a name="config"></a>[Configuring kutty](#config)
+## <a name="config"></a>[Configuring htmx](#config)
-Kutty allows you to configure a few defaults:
+Htmx allows you to configure a few defaults:
-* `kutty.config.historyEnabled` - defaults to `true`, really only useful for testing
-* `kutty.config.historyCacheSize` - defaults to 10
-* `kutty.config.defaultSwapStyle` - defaults to `innerHTML`
-* `kutty.config.defaultSwapDelay` - defaults to 0
-* `kutty.config.defaultSettleDelay` - defaults to 100
-* `kutty.config.includeIndicatorStyles` - defaults to `true` (determines if the `kutty-indicator` default styles are loaded, must be set in a `meta` tag before the kutty js is included)
+* `htmx.config.historyEnabled` - defaults to `true`, really only useful for testing
+* `htmx.config.historyCacheSize` - defaults to 10
+* `htmx.config.defaultSwapStyle` - defaults to `innerHTML`
+* `htmx.config.defaultSwapDelay` - defaults to 0
+* `htmx.config.defaultSettleDelay` - defaults to 100
+* `htmx.config.includeIndicatorStyles` - defaults to `true` (determines if the `htmx-indicator` default styles are loaded, must be set in a `meta` tag before the htmx js is included)
You can set them directly in javascript, or you can use a `meta` tag:
```html
- <meta name="kutty-config" content='{"defaultSwapStyle":"outerHTML"}'>
+ <meta name="htmx-config" content='{"defaultSwapStyle":"outerHTML"}'>
```
### Conclusion
-And that's it! Have fun with kutty: you can accomplish [quite a bit](/examples) without a lot of code.
+And that's it! Have fun with htmx: you can accomplish [quite a bit](/examples) without a lot of code.
</div>
</div>
diff --git a/www/events.md b/www/events.md
index 0af9bb54..3f3a31ef 100644
--- a/www/events.md
+++ b/www/events.md
@@ -1,14 +1,14 @@
---
layout: layout.njk
-title: </> kutty - high power tools for html
+title: </> htmx - high power tools for html
---
## Events
-Kutty provides an extensive events system that can be used to modify and enhance behavior. Events
+Htmx provides an extensive events system that can be used to modify and enhance behavior. Events
are listed below.
-### <a name="afterOnLoad.kutty"></a> Event - [`afterOnLoad.kutty`](#afterOnLoad.kutty)
+### <a name="afterOnLoad.htmx"></a> Event - [`afterOnLoad.htmx`](#afterOnLoad.htmx)
This event is triggered after an AJAX `onload` has finished. Note that this does not mean that the content
has been swapped or settled yet, only that the request has finished.
@@ -19,7 +19,7 @@ has been swapped or settled yet, only that the request has finished.
* `detail.xhr` - the `XMLHttpRequest`
* `detail.target` - the target of the request
-### <a name="afterSettle.kutty"></a> Event - [`afterSettle.kutty`](#afterSettle.kutty)
+### <a name="afterSettle.htmx"></a> Event - [`afterSettle.htmx`](#afterSettle.htmx)
This event is triggered after the DOM has [settled](/docs#settling).
@@ -29,7 +29,7 @@ This event is triggered after the DOM has [settled](/docs#settling).
* `detail.xhr` - the `XMLHttpRequest`
* `detail.target` - the target of the request
-### <a name="afterSwap.kutty"></a> Event - [`afterSwap.kutty`](#afterSwap.kutty)
+### <a name="afterSwap.htmx"></a> Event - [`afterSwap.htmx`](#afterSwap.htmx)
This event is triggered after new content has been [swapped into the DOM](/docs#swapping).
@@ -39,7 +39,7 @@ This event is triggered after new content has been [swapped into the DOM](/docs
* `detail.xhr` - the `XMLHttpRequest`
* `detail.target` - the target of the request
-### <a name="beforeOnLoad.kutty"></a> Event - [`beforeOnLoad.kutty`](#beforeOnLoad.kutty)
+### <a name="beforeOnLoad.htmx"></a> Event - [`beforeOnLoad.htmx`](#beforeOnLoad.htmx)
This event is triggered before any new content has been [swapped into the DOM](/docs#swapping). If
the event is cancelled, no swap will occur.
@@ -50,7 +50,7 @@ the event is cancelled, no swap will occur.
* `detail.xhr` - the `XMLHttpRequest`
* `detail.target` - the target of the request
-### <a name="beforeRequest.kutty"></a> Event - [`beforeRequest.kutty`](#beforeRequest.kutty)
+### <a name="beforeRequest.htmx"></a> Event - [`beforeRequest.htmx`](#beforeRequest.htmx)
This event is triggered before an AJAX request is issued. If the event is cancelled, no request will occur.
@@ -60,7 +60,7 @@ This event is triggered before an AJAX request is issued. If the event is cance
* `detail.xhr` - the `XMLHttpRequest`
* `detail.target` - the target of the request
-### <a name="historyCacheMiss.kutty"></a> Event - [`historyCacheMiss.kutty`](#historyCacheMiss.kutty)
+### <a name="historyCacheMiss.htmx"></a> Event - [`historyCacheMiss.htmx`](#historyCacheMiss.htmx)
This event is triggered when a cache miss occurs when restoring history
@@ -69,7 +69,7 @@ This event is triggered when a cache miss occurs when restoring history
* `detail.xhr` - the `XMLHttpRequest` that will retrieve the remote content for restoration
* `detail.path` - the path and query of the page being restored
-### <a name="historyCacheMissLoad.kutty"></a> Event - [`historyCacheMissLoad.kutty`](#historyCacheMissLoad.kutty)
+### <a name="historyCacheMissLoad.htmx"></a> Event - [`historyCacheMissLoad.htmx`](#historyCacheMissLoad.htmx)
This event is triggered when a cache miss occurs and a response has been retrieved succesfully from the server
for the content to restore
@@ -79,7 +79,7 @@ for the content to restore
* `detail.xhr` - the `XMLHttpRequest`
* `detail.path` - the path and query of the page being restored
-### <a name="historyCacheMissError.kutty"></a> Event - [`historyCacheMissError.kutty`](#historyCacheMissError.kutty)
+### <a name="historyCacheMissError.htmx"></a> Event - [`historyCacheMissError.htmx`](#historyCacheMissError.htmx)
This event is triggered when a cache miss occurs and a response has been retrieved from the server
for the content to restore, but the response is an error (e.g. `404`)
@@ -89,26 +89,26 @@ for the content to restore, but the response is an error (e.g. `404`)
* `detail.xhr` - the `XMLHttpRequest`
* `detail.path` - the path and query of the page being restored
-### <a name="historyRestore.kutty"></a> Event - [`historyRestore.kutty`](#historyRestore.kutty)
+### <a name="historyRestore.htmx"></a> Event - [`historyRestore.htmx`](#historyRestore.htmx)
-This event is triggered when kutty handles a history restoration action
+This event is triggered when htmx handles a history restoration action
##### Details
* `detail.path` - the path and query of the page being restored
-### <a name="beforeHistorySave.kutty"></a> Event - [`beforeHistorySave.kutty`](#beforeHistorySave.kutty)
+### <a name="beforeHistorySave.htmx"></a> Event - [`beforeHistorySave.htmx`](#beforeHistorySave.htmx)
-This event is triggered when kutty handles a history restoration action
+This event is triggered when htmx handles a history restoration action
##### Details
* `detail.path` - the path and query of the page being restored
* `detail.historyElt` - the history element being restored into
-### <a name="initSSE.kutty"></a> Event - [`initSSE.kutty`](#initSSE.kutty)
+### <a name="initSSE.htmx"></a> Event - [`initSSE.htmx`](#initSSE.htmx)
-This event is triggered when kutty initializes a new SSE source. It can be used
+This event is triggered when htmx initializes a new SSE source. It can be used
to [configure the source](https://developer.mozilla.org/en-US/docs/Web/API/EventSource/EventSource).
Note that by default `withCredentials` will be set to `true` in the configuration.
@@ -117,15 +117,15 @@ Note that by default `withCredentials` will be set to `true` in the configuratio
* `detail.config` - the config that will be passed to the `EventSource` contstructor
-### <a name="load.kutty"></a> Event - [`load.kutty`](#load.kutty)
+### <a name="load.htmx"></a> Event - [`load.htmx`](#load.htmx)
-This event is triggered when a new node is loaded into the DOM by kutty.
+This event is triggered when a new node is loaded into the DOM by htmx.
##### Details
* `detail.elt` - the newly added element
-### <a name="noSSESourceError.kutty"></a> Event - [`noSSESourceError.kutty`](#noSSESourceError.kutty)
+### <a name="noSSESourceError.htmx"></a> Event - [`noSSESourceError.htmx`](#noSSESourceError.htmx)
This event is triggered when an element refers to a SSE event in its trigger, but no parent SSE source has been defined
@@ -133,7 +133,7 @@ This event is triggered when an element refers to a SSE event in its trigger, bu
* `detail.elt` - the element with the bad SSE trigger
-### <a name="onLoadError.kutty"></a> Event - [`onLoadError.kutty`](#onLoadError.kutty)
+### <a name="onLoadError.htmx"></a> Event - [`onLoadError.htmx`](#onLoadError.htmx)
This event is triggered when an error occurs during the `load` handling of an AJAX call
@@ -144,7 +144,7 @@ This event is triggered when an error occurs during the `load` handling of an AJ
* `detail.target` - the target of the request
* `detail.exception` - the exception that occurred
-### <a name="oobErrorNoTarget.kutty"></a> Event - [`oobErrorNoTarget.kutty`](#oobErrorNoTarget.kutty)
+### <a name="oobErrorNoTarget.htmx"></a> Event - [`oobErrorNoTarget.htmx`](#oobErrorNoTarget.htmx)
This event is triggered when an [out of band swap](/docs##oob_swaps) does not have a corresponding element
in the DOM to switch with.
@@ -153,9 +153,9 @@ in the DOM to switch with.
* `detail.content` - the element with the bad oob `id`
-### <a name="prompt.kutty"></a> Event - [`prompt.kutty`](#prompt.kutty)
+### <a name="prompt.htmx"></a> Event - [`prompt.htmx`](#prompt.htmx)
-This event is triggered after a prompt has been shown to the user with the [`kt-prompt`](/attributes/kt-prompt)
+This event is triggered after a prompt has been shown to the user with the [`hx-prompt`](/attributes/hx-prompt)
attribute. If this event is cancelled, the AJAX request will not occur.
##### Details
@@ -164,7 +164,7 @@ attribute. If this event is cancelled, the AJAX request will not occur.
* `detail.target` - the target of the request
* `detail.prompt` - the user response to the prompt
-### <a name="responseError.kutty"></a> Event - [`responseError.kutty`](#responseError.kutty)
+### <a name="responseError.htmx"></a> Event - [`responseError.htmx`](#responseError.htmx)
This event is triggered when an HTTP error response occurs
@@ -174,7 +174,7 @@ This event is triggered when an HTTP error response occurs
* `detail.elt` - the element that triggered the request
* `detail.target` - the target of the request
-### <a name="sendError.kutty"></a> Event - [`sendError.kutty`](#sendError.kutty)
+### <a name="sendError.htmx"></a> Event - [`sendError.htmx`](#sendError.htmx)
This event is triggered when a network error prevents an HTTP request from occurring
@@ -184,7 +184,7 @@ This event is triggered when a network error prevents an HTTP request from occur
* `detail.elt` - the element that triggered the request
* `detail.target` - the target of the request
-### <a name="sseError.kutty"></a> Event - [`sseError.kutty`](#sseError.kutty)
+### <a name="sseError.htmx"></a> Event - [`sseError.htmx`](#sseError.htmx)
This event is triggered when an error occurs with a SSE source
@@ -194,7 +194,7 @@ This event is triggered when an error occurs with a SSE source
* `detail.error` - the error
* `detail.source` - the SSE source
-### <a name="swapError.kutty"></a> Event - [`swapError.kutty`](#swapError.kutty)
+### <a name="swapError.htmx"></a> Event - [`swapError.htmx`](#swapError.htmx)
This event is triggered when an error occurs during the swap phase
@@ -204,13 +204,13 @@ This event is triggered when an error occurs during the swap phase
* `detail.elt` - the element that triggered the request
* `detail.target` - the target of the request
-### <a name="configRequest.kutty"></a> Event - [`configRequest.kutty`](#configRequest.kutty)
+### <a name="configRequest.htmx"></a> Event - [`configRequest.htmx`](#configRequest.htmx)
-This event is triggered after kutty has collected parameters for inclusion in the request. It can be
-used to include or update the parameters that kutty will send:
+This event is triggered after htmx has collected parameters for inclusion in the request. It can be
+used to include or update the parameters that htmx will send:
```javascript
-document.body.addEventListener('configRequest.kutty', function(evt) {
+document.body.addEventListener('configRequest.htmx', function(evt) {
evt.detail.parameters['auth_token'] = getAuthToken(); // add a new parameter into the mix
});
```
@@ -227,9 +227,9 @@ than a single value.
* `detail.target` - the target of the request
* `detail.verb` - the HTTP verb in use
-### <a name="targetError.kutty"></a> Event - [`targetError.kutty`](#targetError.kutty)
+### <a name="targetError.htmx"></a> Event - [`targetError.htmx`](#targetError.htmx)
-This event is triggered when a bad selector is used for a [`kt-target`](/attributes/kt-target) attribute (e.g. an
+This event is triggered when a bad selector is used for a [`hx-target`](/attributes/hx-target) attribute (e.g. an
element id without a preceding `#`)
##### Details
diff --git a/www/examples.md b/www/examples.md
index 580b1812..0e48a897 100644
--- a/www/examples.md
+++ b/www/examples.md
@@ -1,11 +1,11 @@
---
layout: layout.njk
-title: </> kutty - UX Patterns
+title: </> htmx - UX Patterns
---
## UI Examples
-Below are a set of UX patterns implemented in kutty with minimal HTML and styling.
+Below are a set of UX patterns implemented in htmx with minimal HTML and styling.
You can copy and paste them and then adjust them for your needs.
diff --git a/www/examples/active-search.md b/www/examples/active-search.md
index fa39e541..7f2b7cbd 100644
--- a/www/examples/active-search.md
+++ b/www/examples/active-search.md
@@ -11,16 +11,16 @@ We start with a search input and an empty table:
```html
<h3>
Search Contacts
- <span class="kutty-indicator">
+ <span class="htmx-indicator">
<img src="/img/bars.svg"/> Searching...
</span>
</h3>
<input class="form-control" type="text"
name="search" placeholder="Begin Typing To Search Users..."
- kt-post="/search"
- kt-trigger="keyup changed delay:500ms"
- kt-target="#search-results"
- kt-indicator=".kutty-indicator">
+ hx-post="/search"
+ hx-trigger="keyup changed delay:500ms"
+ hx-target="#search-results"
+ hx-indicator=".htmx-indicator">
<table class="table">
<thead>
@@ -41,7 +41,7 @@ We add the `delay:500ms` modifier to the trigger to delay sending the query unti
we add the `changed` modifier to the trigger to ensure we don't send new queries when the user doesn't change the
value of the input (e.g. they hit an arrow key).
-Finally, we show an indicator when the search is in flight with the `kt-indicator` attribute.
+Finally, we show an indicator when the search is in flight with the `hx-indicator` attribute.
{% include demo_ui.html.liquid %}
@@ -67,17 +67,17 @@ Finally, we show an indicator when the search is in flight with the `kt-indicato
function searchUI() {
return ` <h3>
Search Contacts
-<span class="kutty-indicator">
+<span class="htmx-indicator">
<img src="/img/bars.svg"/> Searching...
</span>
</h3>
<input class="form-control" type="text"
name="search" placeholder="Begin Typing To Search Users..."
- kt-post="/search"
- kt-trigger="keyup changed delay:500ms"
- kt-target="#search-results"
- kt-indicator=".kutty-indicator">
+ hx-post="/search"
+ hx-trigger="keyup changed delay:500ms"
+ hx-target="#search-results"
+ hx-indicator=".htmx-indicator">
<table class="table">
<thead>
diff --git a/www/examples/bulk-update.md b/www/examples/bulk-update.md
index fb12fe09..072d157f 100644
--- a/www/examples/bulk-update.md
+++ b/www/examples/bulk-update.md
@@ -9,9 +9,9 @@ accomplished by putting a form around a table, with checkboxes in the table, and
values in `POST`'s to two different endpoints: `activate` and `deactivate`:
```html
-<div kt-include="#checked-contacts" kt-target="#tbody">
- <a class="btn" kt-put="/activate">Activate</a>
- <a class="btn" kt-put="/deactivate">Deactivate</a>
+<div hx-include="#checked-contacts" hx-target="#tbody">
+ <a class="btn" hx-put="/activate">Activate</a>
+ <a class="btn" hx-put="/deactivate">Deactivate</a>
</div>
<form id="checked-contacts">
@@ -42,10 +42,10 @@ updated rows. It will apply the class `activate` or `deactivate` to rows that h
us to use a bit of CSS to flash a color helping the user see what happened:
```css
- .kutty-settling tr.deactivate td {
+ .htmx-settling tr.deactivate td {
background: lightcoral;
}
- .kutty-settling tr.activate td {
+ .htmx-settling tr.activate td {
background: darkseagreen;
}
tr td {
@@ -56,10 +56,10 @@ us to use a bit of CSS to flash a color helping the user see what happened:
You can see a working examle of this code below.
<style scoped="">
- .kutty-settling tr.deactivate td {
+ .htmx-settling tr.deactivate td {
background: lightcoral;
}
- .kutty-settling tr.activate td {
+ .htmx-settling tr.activate td {
background: darkseagreen;
}
tr td {
@@ -127,9 +127,9 @@ You can see a working examle of this code below.
// templates
function displayUI(contacts) {
- return `<div kt-include="#checked-contacts" kt-target="#tbody">
- <a class="btn" kt-put="/activate">Activate</a>
- <a class="btn" kt-put="/deactivate">Deactivate</a>
+ return `<div hx-include="#checked-contacts" hx-target="#tbody">
+ <a class="btn" hx-put="/activate">Activate</a>
+ <a class="btn" hx-put="/deactivate">Deactivate</a>
</div>
<form id="checked-contacts">
diff --git a/www/examples/click-to-edit.md b/www/examples/click-to-edit.md
index 189a18b3..e61946c6 100644
--- a/www/examples/click-to-edit.md
+++ b/www/examples/click-to-edit.md
@@ -9,11 +9,11 @@ The click to edit pattern provides a way to offer inline editing of all or part
* This pattern starts with a UI that shows the details of a contact. The div has a button that will get the editing UI for the contact from `/contacts/1/edit`
```html
-<div kt-target="this" kt-swap="outerHTML">
+<div hx-target="this" hx-swap="outerHTML">
<div><label>First Name</label>: Joe</div>
<div><label>Last Name</label>: Blow</div>
<div><label>Email</label>: joe@blow.com</div>
- <button kt-get="/contact/1/edit" class="btn btn-primary">
+ <button hx-get="/contact/1/edit" class="btn btn-primary">
Click To Edit
</button>
</div>
@@ -22,7 +22,7 @@ The click to edit pattern provides a way to offer inline editing of all or part
* This returns a form that can be used to edit the contact
```html
-<form kt-put="/contact/1" kt-target="this" kt-swap="outerHTML">
+<form hx-put="/contact/1" hx-target="this" hx-swap="outerHTML">
<div>
<label>First Name</label>
<input type="text" name="firstName" value="Joe">
@@ -36,7 +36,7 @@ The click to edit pattern provides a way to offer inline editing of all or part
<input type="email" name="email" value="joe@blow.com">
</div>
<button class="btn">Submit</button>
- <button class="btn" kt-get="/contact/1">Cancel</button>
+ <button class="btn" hx-get="/contact/1">Cancel</button>
</form>
```
@@ -74,7 +74,7 @@ The click to edit pattern provides a way to offer inline editing of all or part
// templates
function formTemplate(contact) {
-return `<form kt-put="/contact/1" kt-target="this" kt-swap="outerHTML">
+return `<form hx-put="/contact/1" hx-target="this" hx-swap="outerHTML">
<div>
<label>First Name</label>
<input type="text" name="firstName" value="${contact.firstName}">
@@ -88,16 +88,16 @@ return `<form kt-put="/contact/1" kt-target="this" kt-swap="outerHTML">
<input type="email" name="email" value="${contact.email}">
</div>
<button class="btn">Submit</button>
- <button class="btn" kt-get="/contact/1">Cancel</button>
+ <button class="btn" hx-get="/contact/1">Cancel</button>
</form>`
}
function displayTemplate(contact) {
- return `<div kt-target="this" kt-swap="outerHTML">
+ return `<div hx-target="this" hx-swap="outerHTML">
<div><label>First Name</label>: ${contact.firstName}</div>
<div><label>Last Name</label>: ${contact.lastName}</div>
<div><label>Email</label>: ${contact.email}</div>
- <button kt-get="/contact/1/edit" class="btn btn-primary">
+ <button hx-get="/contact/1/edit" class="btn btn-primary">
Click To Edit
</button>
</div>`;
diff --git a/www/examples/click-to-load.md b/www/examples/click-to-load.md
index 19190fdf..72ff0d38 100644
--- a/www/examples/click-to-load.md
+++ b/www/examples/click-to-load.md
@@ -10,10 +10,10 @@ the final row:
```html
<tr id="replaceMe">
<td colspan="3">
- <button class='btn' kt-get="/contacts/?page=2"
- kt-target="#replaceMe"
- kt-swap="outerHTML">
- Load More Agents... <img class="kutty-indicator" src="/img/bars.svg">
+ <button class='btn' hx-get="/contacts/?page=2"
+ hx-target="#replaceMe"
+ hx-swap="outerHTML">
+ Load More Agents... <img class="htmx-indicator" src="/img/bars.svg">
</button>
</td>
</tr>
@@ -83,10 +83,10 @@ results (which will contain a button to load the *next* page of results). And s
return `<tr id="replaceMe">
<td colspan="3">
<center>
- <button class='btn' kt-get="/contacts/?page=${page + 1}"
- kt-target="#replaceMe"
- kt-swap="outerHTML">
- Load More Agents... <img class="kutty-indicator" src="/img/bars.svg">
+ <button class='btn' hx-get="/contacts/?page=${page + 1}"
+ hx-target="#replaceMe"
+ hx-swap="outerHTML">
+ Load More Agents... <img class="htmx-indicator" src="/img/bars.svg">
</button>
</center>
</td>
diff --git a/www/examples/infinite-scroll.md b/www/examples/infinite-scroll.md
index 2cdc0fb8..2b71e080 100644
--- a/www/examples/infinite-scroll.md
+++ b/www/examples/infinite-scroll.md
@@ -2,16 +2,16 @@
layout: demo_layout.njk
---
-## Kutty Pattern: Infinite scroll
+## Htmx Pattern: Infinite scroll
The infinite scroll pattern provides a way to load content dynamically on user scrolling action.
Let's focus on the final row:
```html
-<tr kt-get="/contacts/?page=2"
- kt-trigger="revealed"
- kt-swap="afterend">
+<tr hx-get="/contacts/?page=2"
+ hx-trigger="revealed"
+ hx-swap="afterend">
<td>Agent Smith</td>
<td>void29@null.org</td>
<td>55F49448C0</td>
@@ -65,9 +65,9 @@ The last element of the results will itself contain the listener to load the *ne
// templates
function tableTemplate(contacts) {
- return `<table kt-indicator=".kutty-indicator"><thead><tr><th>Name</th><th>Email</th><th>ID</th></tr></thead><tbody>
+ return `<table hx-indicator=".htmx-indicator"><thead><tr><th>Name</th><th>Email</th><th>ID</th></tr></thead><tbody>
${rowsTemplate(1, contacts)}
- </tbody></table><center><img class="kutty-indicator" width="60" src="/img/bars.svg"></center>`
+ </tbody></table><center><img class="htmx-indicator" width="60" src="/img/bars.svg"></center>`
}
function rowsTemplate(page, contacts) {
@@ -78,7 +78,7 @@ The last element of the results will itself contain the listener to load the *ne
var c = contacts[i];
if (i == (contacts.length - 1)) {
- trigger_attributes = ` kt-get="/contacts/?page=${page + 1}" kt-trigger="revealed" kt-swap="afterend"`
+ trigger_attributes = ` hx-get="/contacts/?page=${page + 1}" hx-trigger="revealed" hx-swap="afterend"`
}
txt += "<tr" + trigger_attributes +"><td>" + c.name + "</td><td>" + c.email + "</td><td>" + c.id + "</td></tr>\n";
diff --git a/www/examples/inline-validation.md b/www/examples/inline-validation.md
index 492edfa6..c303ebdd 100644
--- a/www/examples/inline-validation.md
+++ b/www/examples/inline-validation.md
@@ -12,11 +12,11 @@ We start with this form:
```html
<h3>Signup Form</h3>
-<form kt-post="/contact">
- <div kt-target="this" kt-swap="outerHTML">
+<form hx-post="/contact">
+ <div hx-target="this" hx-swap="outerHTML">
<label>Email Address</label>
- <input name="email" kt-post="/contact/email" kt-indicator="#ind">
- <img id="ind" src="/img/bars.svg" class="kutty-indicator"/>
+ <input name="email" hx-post="/contact/email" hx-indicator="#ind">
+ <img id="ind" src="/img/bars.svg" class="htmx-indicator"/>
</div>
<div class="form-group">
<label>First Name</label>
@@ -37,10 +37,10 @@ It also specifies an indicator for the request.
When a request occurs, it will return a partial to replace the outer div. It might look like this:
```html
-<div kt-target="this" kt-swap="outerHTML" class="error">
+<div hx-target="this" hx-swap="outerHTML" class="error">
<label>Email Address</label>
- <input name="email" kt-post="/contact/email" kt-indicator="#ind" value="test@foo.com">
- <img id="ind" src="/img/bars.svg" class="kutty-indicator"/>
+ <input name="email" hx-post="/contact/email" hx-indicator="#ind" value="test@foo.com">
+ <img id="ind" src="/img/bars.svg" class="htmx-indicator"/>
<div class='error-message'>That email is already taken. Please enter another email.</div>
</div>
```
@@ -108,10 +108,10 @@ Below is a working demo of this example. The only email that will be accepted i
// templates
function formTemplate(page) {
return `<h3>Signup Form</h3><form ic-post-to="/contact">
- <div kt-target="this" kt-swap="outerHTML">
+ <div hx-target="this" hx-swap="outerHTML">
<label>Email Address</label>
- <input name="email" kt-get="/contact/email" kt-indicator="#ind">
- <img id="ind" src="/img/bars.svg" class="kutty-indicator"/>
+ <input name="email" hx-get="/contact/email" hx-indicator="#ind">
+ <img id="ind" src="/img/bars.svg" class="htmx-indicator"/>
</div>
<div class="form-group">
<label>First Name</label>
@@ -126,10 +126,10 @@ Below is a working demo of this example. The only email that will be accepted i
}
function emailInputTemplate(val, errorMsg) {
- return `<div kt-target="this" kt-swap="outerHTML" class="${errorMsg ? "error" : "valid"}">
+ return `<div hx-target="this" hx-swap="outerHTML" class="${errorMsg ? "error" : "valid"}">
<label>Email Address</label>
- <input name="email" kt-get="/contact/email" kt-indicator="#ind" value="${val}">
- <img id="ind" src="/img/bars.svg" class="kutty-indicator"/>
+ <input name="email" hx-get="/contact/email" hx-indicator="#ind" value="${val}">
+ <img id="ind" src="/img/bars.svg" class="htmx-indicator"/>
${errorMsg ? ("<div class='error-message'>" + errorMsg + "</div>") : ""}
</div>`;
}
diff --git a/www/examples/lazy-load.md b/www/examples/lazy-load.md
index 0fe87202..806e414c 100644
--- a/www/examples/lazy-load.md
+++ b/www/examples/lazy-load.md
@@ -8,8 +8,8 @@ This example shows how to lazily load an element on a page. We start with an in
state that looks like this:
```html
-<div kt-get="/graph" kt-trigger="load">
- <img class="kutty-indicator" width="150" src="/img/bars.svg"/>
+<div hx-get="/graph" hx-trigger="load">
+ <img class="htmx-indicator" width="150" src="/img/bars.svg"/>
</div>
```
@@ -17,7 +17,7 @@ Which shows a progress indicator as we are loading the graph. The graph is then
loaded and faded gently into view via a settling CSS transition:
```css
-.kutty-settling img {
+.htmx-settling img {
opacity: 0;
}
img {
@@ -26,7 +26,7 @@ img {
```
<style>
-.kutty-settling img {
+.htmx-settling img {
opacity: 0;
}
img {
@@ -54,8 +54,8 @@ img {
// templates
function lazyTemplate(page) {
- return `<div kt-get="/graph" kt-trigger="load">
- <img class="kutty-indicator" width="120" src="/img/bars.svg"/>
+ return `<div hx-get="/graph" hx-trigger="load">
+ <img class="htmx-indicator" width="120" src="/img/bars.svg"/>
</div>`;
}
</script>
diff --git a/www/examples/progress-bar.md b/www/examples/progress-bar.md
index 1c195a8b..de56e84d 100644
--- a/www/examples/progress-bar.md
+++ b/www/examples/progress-bar.md
@@ -9,9 +9,9 @@ This example shows how to implement a smoothly scrolling progress bar.
We start with an intial state with a button that issues a `POST` to `/start` to begin the job:
```html
-<div kt-target="this" kt-swap="outerHTML">
+<div hx-target="this" hx-swap="outerHTML">
<h3>Start Progress</h3>
- <button class="btn" kt-post="/start">
+ <button class="btn" hx-post="/start">
Start Job
</button>
</div>
@@ -20,10 +20,10 @@ We start with an intial state with a button that issues a `POST` to `/start` to
This div is then replaced with a new div that reloads itself every 600ms:
```html
-<div kt-target="this"
- kt-get="/job"
- kt-trigger="load delay:600ms"
- kt-swap="outerHTML">
+<div hx-target="this"
+ hx-get="/job"
+ hx-trigger="load delay:600ms"
+ hx-swap="outerHTML">
<h3>Running</h3>
<div class="progress">
<div id="pb" class="progress-bar" style="width:0%">
@@ -31,23 +31,23 @@ This div is then replaced with a new div that reloads itself every 600ms:
</div>
```
This HTML is rerendered every 600 milliseconds, with the "width" style attribute on the progress bar being updated.
-Because there is an id on the progress bar div, kutty will smoothly transition between requests by settling the
+Because there is an id on the progress bar div, htmx will smoothly transition between requests by settling the
style attribute into its new value. This, when coupled with CSS transitions, make the visual transition continuous
rather than jumpy.
Finally, when the process is complete, a restart button is added to the UI:
```html
-<div kt-target="this"
- kt-get="/job"
- kt-trigger="none"
- kt-swap="outerHTML">
+<div hx-target="this"
+ hx-get="/job"
+ hx-trigger="none"
+ hx-swap="outerHTML">
<h3>Complete</h3>
<div class="progress">
<div id="pb" class="progress-bar" style="width:100%">
</div>
</div>
-<button id="restart-btn" class="btn" kt-post="/start" kt-classes="add show:600ms">
+<button id="restart-btn" class="btn" hx-post="/start" hx-classes="add show:600ms">
Restart Job
</button>
```
@@ -109,19 +109,19 @@ Finally, when the process is complete, a restart button is added to the UI:
// templates
function startButton(message) {
- return `<div kt-target="this" kt-swap="outerHTML">
+ return `<div hx-target="this" hx-swap="outerHTML">
<h3>${message}</h3>
- <button class="btn" kt-post="/start">
+ <button class="btn" hx-post="/start">
Start Job
</button>
</div>`;
}
function jobStatusTemplate(job) {
- return `<div kt-target="this"
- kt-get="/job"
- kt-trigger="${job.complete ? 'none' : 'load delay:600ms'}"
- kt-swap="outerHTML">
+ return `<div hx-target="this"
+ hx-get="/job"
+ hx-trigger="${job.complete ? 'none' : 'load delay:600ms'}"
+ hx-swap="outerHTML">
<h3>${job.complete ? "Complete" : "Running"}</h3>
<div class="progress">
<div id="pb" class="progress-bar" style="width:${job.percentComplete}%">
@@ -132,7 +132,7 @@ ${restartButton(job)}`;
function restartButton(job) {
if(job.complete){
- return `<button id="restart-btn" class="btn" kt-post="/start" kt-classes="add show:600ms">
+ return `<button id="restart-btn" class="btn" hx-post="/start" hx-classes="add show:600ms">
Restart Job
</button>`
} else {
diff --git a/www/examples/value-select.md b/www/examples/value-select.md
index 07e4205a..06a4e192 100644
--- a/www/examples/value-select.md
+++ b/www/examples/value-select.md
@@ -14,7 +14,7 @@ Here is the code:
```html
<div>
<label >Make</label>
- <select name="make" kt-get="/models" kt-target="#models" kt-indicator=".kutty-indicator">
+ <select name="make" hx-get="/models" hx-target="#models" hx-indicator=".htmx-indicator">
<option value="audi">Audi</option>
<option value="toyota">Toyota</option>
<option value="bmw">BMW</option>
@@ -63,7 +63,7 @@ And they become available in the `model` select.
<form>
<div>
<label >Make</label>
- <select name="make" kt-get="/models" kt-target="#models" kt-indicator=".kutty-indicator">
+ <select name="make" hx-get="/models" hx-target="#models" hx-indicator=".htmx-indicator">
<option value="audi">Audi</option>
<option value="toyota">Toyota</option>
<option value="bmw">BMW</option>
@@ -76,7 +76,7 @@ And they become available in the `model` select.
<option value="a3">A3</option>
<option value="a6">A6</option>
</select>
- <img class="kutty-indicator" width="20" src="/img/bars.svg">
+ <img class="htmx-indicator" width="20" src="/img/bars.svg">
</div>
</form>`;
}
diff --git a/www/headers/x-kt-trigger.md b/www/headers/x-ht-trigger.md
index 65ad2ed6..55f8b7e8 100644
--- a/www/headers/x-kt-trigger.md
+++ b/www/headers/x-ht-trigger.md
@@ -1,16 +1,16 @@
---
layout: layout.njk
-title: </> kutty - X-KT-Trigger
+title: </> htmx - X-HX-Trigger
---
-## `X-KT-Trigger` Response Header
+## `X-HX-Trigger` Response Header
-The `X-KT-Trigger` response header can be used to trigger client side actions from a response to kutty. You can
+The `X-HX-Trigger` response header can be used to trigger client side actions from a response to htmx. You can
trigger a single event or as many uniquely named events as you would like.
To trigger a single event with no additional details you can simply send the header like so:
-`X-KT-Trigger: myEvent`
+`X-HX-Trigger: myEvent`
This will trigger `myEvent` on the triggering element and will bubble up to the body. As an example you could
listen for this event like this:
@@ -23,7 +23,7 @@ document.body.addEventListener("myEvent", function(evt){
If you want to pass details along with the event, you can move to JSON for the value of the trigger:
-`X-KT-Trigger: {"showMessage":"Here Is A Message"}`
+`X-HX-Trigger: {"showMessage":"Here Is A Message"}`
To handle this event you would write the following code:
@@ -36,7 +36,7 @@ document.body.addEventListener("showMessage", function(evt){
Note that the value of the message was put into the `detail.value` slot. If you wish to pass multiple pieces of data
you can use a nested JSON object on the right hand side of the JSON object:
-`X-KT-Trigger: {"showMessage":{"level" : "info", "message" : "Here Is A Message"}}`
+`X-HX-Trigger: {"showMessage":{"level" : "info", "message" : "Here Is A Message"}}`
And handle this event like so:
@@ -53,6 +53,6 @@ Each property of the JSON object on the right hand side will be copied onto the
Finally, if you wish to invoke multiple events, you can simply add additional properties to the top level JSON
object:
-`X-KT-Trigger: {"event1":"A message", "event2":"Another message"}`
+`X-HX-Trigger: {"event1":"A message", "event2":"Another message"}`
-Using events gives you a lot of flexibility to add functionality to normal kutty responses. \ No newline at end of file
+Using events gives you a lot of flexibility to add functionality to normal htmx responses. \ No newline at end of file
diff --git a/www/img/kutty_logo.2.png b/www/img/htmx_logo.2.png
index 533a968a..533a968a 100644
--- a/www/img/kutty_logo.2.png
+++ b/www/img/htmx_logo.2.png
Binary files differ
diff --git a/www/img/kutty_placeholder.png b/www/img/kutty_placeholder.png
deleted file mode 100644
index d8d7fc5a..00000000
--- a/www/img/kutty_placeholder.png
+++ /dev/null
Binary files differ
diff --git a/www/index.md b/www/index.md
index f4cd1bd4..8552f3b2 100644
--- a/www/index.md
+++ b/www/index.md
@@ -1,37 +1,37 @@
---
layout: layout.njk
-title: </> kutty - high power tools for html
+title: </> htmx - high power tools for html
---
-<div class="dark-hero full-width" kt-classes="add appear">
- <span class="logo dark">&lt;<a>/</a>&gt; <span class="no-mobile">k<a>u</a>tty</span></span>
+<div class="dark-hero full-width" hx-classes="add appear">
+ <span class="logo dark">&lt;<a>/</a>&gt; <span class="no-mobile">htm<a>x</a></span></span>
<sub class="no-mobile"><i>high power tools for HTML</i></sub>
</div>
## Introduction
-Kutty is a set of extensions (attributes, request headers, etc.) that help you build
+Htmx is a set of extensions (attributes, request headers, etc.) that help you build
[modern UI](/examples) with the [simplicity](https://en.wikipedia.org/wiki/HATEOAS) and
[power](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) of HTML.
-Kutty is small ([~6k min.gz'd](https://unpkg.com/kutty.org/dist/)), IE11 compatible, [dependency-free](https://github.com/bigskysoftware/kutty/blob/master/package.json)
+Htmx is small ([~6k min.gz'd](https://unpkg.com/htmx.org/dist/)), IE11 compatible, [dependency-free](https://github.com/bigskysoftware/htmx/blob/master/package.json)
& you can try it out quickly, without a huge rewrite.
## Quick Start
```html
<!-- Load from unpkg -->
- <script src="https://unpkg.com/kutty.org@0.0.2"></script>
+ <script src="https://unpkg.com/htmx.org@0.0.2"></script>
<!-- have a button POST a click via AJAX -->
- <button kt-post="/clicked" kt-swap="outerHTML">
+ <button hx-post="/clicked" hx-swap="outerHTML">
Click Me
</button>
```
-The `kt-post` and `kt-swap` attributes tell kutty:
+The `hx-post` and `hx-swap` attributes tell htmx:
> "When a user clicks on this button, issue an AJAX request to /clicked, and replace the entire button with the response"
-Kutty is based on [intercooler.js](http://intercoolerjs.org) and is the successor to that project.
+Htmx is based on [intercooler.js](http://intercoolerjs.org) and is the successor to that project.
diff --git a/www/js/kutty.js b/www/js/kutty.js
deleted file mode 100644
index 35ce3150..00000000
--- a/www/js/kutty.js
+++ /dev/null
@@ -1,1306 +0,0 @@
-// noinspection JSUnusedAssignment
-var kutty = kutty || (function () {
- 'use strict';
-
- var VERBS = ['get', 'post', 'put', 'delete', 'patch']
-
- //====================================================================
- // Utilities
- //====================================================================
-
- function parseInterval(str) {
- if (str === "null" || str === "false" || str === "") {
- return null;
- } else if (str.lastIndexOf("ms") === str.length - 2) {
- return parseFloat(str.substr(0, str.length - 2));
- } else if (str.lastIndexOf("s") === str.length - 1) {
- return parseFloat(str.substr(0, str.length - 1)) * 1000;
- } else {
- return parseFloat(str);
- }
- }
-
- function getRawAttribute(elt, name) {
- return elt.getAttribute && elt.getAttribute(name);
- }
-
- // resolve with both kt and data-kt prefixes
- function getAttributeValue(elt, qualifiedName) {
- return getRawAttribute(elt, qualifiedName) || getRawAttribute(elt, "data-" + qualifiedName);
- }
-
- function parentElt(elt) {
- return elt.parentElement;
- }
-
- function getDocument() {
- return document;
- }
-
- function getClosestMatch(elt, condition) {
- if (condition(elt)) {
- return elt;
- } else if (parentElt(elt)) {
- return getClosestMatch(parentElt(elt), condition);
- } else {
- return null;
- }
- }
-
- function getClosestAttributeValue(elt, attributeName) {
- var closestAttr = null;
- getClosestMatch(elt, function (e) {
- return closestAttr = getRawAttribute(e, attributeName);
- });
- return closestAttr;
- }
-
- function matches(elt, selector) {
- // noinspection JSUnresolvedVariable
- var matchesFunction = elt.matches ||
- elt.matchesSelector || elt.msMatchesSelector || elt.mozMatchesSelector
- || elt.webkitMatchesSelector || elt.oMatchesSelector;
- return matchesFunction && matchesFunction.call(elt, selector);
- }
-
- function getStartTag(str) {
- var tagMatcher = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i
- var match = tagMatcher.exec( str );
- if (match) {
- return match[1].toLowerCase();
- } else {
- return "";
- }
- }
-
- function parseHTML(resp, depth) {
- var parser = new DOMParser();
- var responseDoc = parser.parseFromString(resp, "text/html");
- var responseNode = responseDoc.body;
- while (depth > 0) {
- depth--;
- responseNode = responseNode.firstChild;
- }
- return responseNode;
- }
-
- function makeFragment(resp) {
- var startTag = getStartTag(resp);
- switch (startTag) {
- case "thead":
- case "tbody":
- case "tfoot":
- case "colgroup":
- case "caption":
- return parseHTML("<table>" + resp + "</table>", 1);
- case "col":
- return parseHTML("<table><colgroup>" + resp + "</colgroup></table>", 2);
- case "tr":
- return parseHTML("<table><tbody>" + resp + "</tbody></table>", 2);
- case "td":
- case "th":
- return parseHTML("<table><tbody><tr>" + resp + "</tr></tbody></table>", 3);
- default:
- return parseHTML(resp, 0);
- }
- }
-
- function isType(o, type) {
- return Object.prototype.toString.call(o) === "[object " + type + "]";
- }
-
- function isFunction(o) {
- return isType(o, "Function");
- }
-
- function isRawObject(o) {
- return isType(o, "Object");
- }
-
- function getInternalData(elt) {
- var dataProp = 'kutty-internal-data';
- var data = elt[dataProp];
- if (!data) {
- data = elt[dataProp] = {};
- }
- return data;
- }
-
- function forEach(arr, func) {
- if (arr) {
- for (var i = 0; i < arr.length; i++) {
- func(arr[i]);
- }
- }
- }
-
- function isScrolledIntoView(el) {
- var rect = el.getBoundingClientRect();
- var elemTop = rect.top;
- var elemBottom = rect.bottom;
- return elemTop < window.innerHeight && elemBottom >= 0;
- }
-
- function bodyContains(elt) {
- return getDocument().body.contains(elt);
- }
-
- function concat(arr1, arr2) {
- return arr1.concat(arr2);
- }
-
- function splitOnWhitespace(trigger) {
- return trigger.split(/\s+/);
- }
-
- function addRule(rule) {
- var sheet = getDocument().styleSheets[0];
- sheet.insertRule(rule, sheet.cssRules.length);
- }
-
- function mergeObjects(obj1, obj2) {
- for (var key in obj2) {
- if (obj2.hasOwnProperty(key)) {
- obj1[key] = obj2[key];
- }
- }
- return obj1;
- }
-
- //==========================================================================================
- // public API
- //==========================================================================================
-
- function internalEval(str){
- return eval(str);
- }
-
- function onLoadHelper(callback) {
- var value = kutty.on("load.kutty", function(evt) {
- callback(evt.detail.elt);
- });
- return value;
- }
-
- function logAll(){
- kutty.logger = function(elt, event, data) {
- if(console) {
- console.log(event, elt, data);
- }
- }
- }
-
- function find(eltOrSelector, selector) {
- if (selector) {
- return eltOrSelector.querySelector(selector);
- } else {
- return getDocument().body.querySelector(eltOrSelector);
- }
- }
-
- function findAll(eltOrSelector, selector) {
- if (selector) {
- return eltOrSelector.querySelectorAll(selector);
- } else {
- return getDocument().body.querySelectorAll(eltOrSelector);
- }
- }
-
- function removeElement(elt, delay) {
- if (delay) {
- setTimeout(function(){removeElement(elt);}, delay)
- } else {
- elt.parentElement.removeChild(elt);
- }
- }
-
- function addClassToElement(elt, clazz, delay) {
- if (delay) {
- setTimeout(function(){addClassToElement(elt, clazz);}, delay)
- } else {
- elt.classList.add(clazz);
- }
- }
-
- function removeClassFromElement(elt, clazz, delay) {
- if (delay) {
- setTimeout(function(){removeClassFromElement(elt, clazz);}, delay)
- } else {
- elt.classList.remove(clazz);
- }
- }
-
- function toggleClassOnElement(elt, clazz) {
- elt.classList.toggle(clazz);
- }
-
- function takeClassForElement(elt, clazz) {
- forEach(elt.parentElement.children, function(child){
- removeClassFromElement(child, clazz);
- })
- addClassToElement(elt, clazz);
- }
-
- function closest(elt, selector) {
- do if (elt == null || matches(elt, selector)) return elt;
- while (elt = elt && parentElt(elt));
- }
-
- function processEventArgs(arg1, arg2, arg3) {
- if (isFunction(arg2)) {
- return {
- target: getDocument().body,
- event: arg1,
- listener: arg2
- }
- } else {
- return {
- target: arg1,
- event: arg2,
- listener: arg3
- }
- }
-
- }
-
- function addKuttyEventListener(arg1, arg2, arg3) {
- ready(function(){
- var eventArgs = processEventArgs(arg1, arg2, arg3);
- eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener);
- })
- var b = isFunction(arg2);
- return b ? arg2 : arg3;
- }
-
- function removeKuttyEventListener(arg1, arg2, arg3) {
- ready(function(){
- var eventArgs = processEventArgs(arg1, arg2, arg3);
- eventArgs.target.removeEventListener(eventArgs.event, eventArgs.listener);
- })
- return isFunction(arg2) ? arg2 : arg3;
- }
-
- //====================================================================
- // Node processing
- //====================================================================
-
- function getTarget(elt) {
- var explicitTarget = getClosestMatch(elt, function(e){return getRawAttribute(e,"kt-target") !== null});
- if (explicitTarget) {
- var targetStr = getRawAttribute(explicitTarget, "kt-target");
- if (targetStr === "this") {
- return explicitTarget;
- } else if (targetStr.indexOf("closest ") === 0) {
- return closest(elt, targetStr.substr(8));
- } else {
- return getDocument().querySelector(targetStr);
- }
- } else {
- var data = getInternalData(elt);
- if (data.boosted) {
- return getDocument().body;
- } else {
- return elt;
- }
- }
- }
-
- function cloneAttributes(mergeTo, mergeFrom) {
- forEach(mergeTo.attributes, function (attr) {
- if (!mergeFrom.hasAttribute(attr.name)) {
- mergeTo.removeAttribute(attr.name)
- }
- });
- forEach(mergeFrom.attributes, function (attr) {
- mergeTo.setAttribute(attr.name, attr.value);
- });
- }
-
- function handleOutOfBandSwaps(fragment) {
- var settleTasks = [];
- forEach(fragment.children, function (child) {
- if (getAttributeValue(child, "kt-swap-oob") === "true") {
- var target = getDocument().getElementById(child.id);
- if (target) {
- var fragment = getDocument().createDocumentFragment();
- fragment.appendChild(child);
- settleTasks = settleTasks.concat(swapOuterHTML(target, fragment));
- } else {
- child.parentNode.removeChild(child);
- triggerErrorEvent(getDocument().body, "oobErrorNoTarget.kutty", {content: child})
- }
- }
- });
- return settleTasks;
- }
-
- function handleAttributes(parentNode, fragment) {
- var attributeSwaps = [];
- forEach(fragment.querySelectorAll("[id]"), function (newNode) {
- var oldNode = parentNode.querySelector(newNode.tagName + "[id=" + newNode.id + "]")
- if (oldNode) {
- var newAttributes = newNode.cloneNode();
- cloneAttributes(newNode, oldNode);
- attributeSwaps.push(function () {
- cloneAttributes(newNode, newAttributes);
- });
- }
- });
- return attributeSwaps;
- }
-
- function insertNodesBefore(parentNode, insertBefore, fragment) {
- var settleTasks = handleAttributes(parentNode, fragment);
- while(fragment.childNodes.length > 0){
- var child = fragment.firstChild;
- parentNode.insertBefore(child, insertBefore);
- if (child.nodeType !== Node.TEXT_NODE) {
- triggerEvent(child, 'load.kutty', {});
- processNode(child);
- }
- }
- return settleTasks;
- }
-
- function swapOuterHTML(target, fragment) {
- if (target.tagName === "BODY") {
- return swapInnerHTML(target, fragment);
- } else {
- var settleTasks = insertNodesBefore(parentElt(target), target, fragment);
- parentElt(target).removeChild(target);
- return settleTasks;
- }
- }
-
- function swapAfterBegin(target, fragment) {
- return insertNodesBefore(target, target.firstChild, fragment);
- }
-
- function swapBeforeBegin(target, fragment) {
- return insertNodesBefore(parentElt(target), target, fragment);
- }
-
- function swapBeforeEnd(target, fragment) {
- return insertNodesBefore(target, null, fragment);
- }
-
- function swapAfterEnd(target, fragment) {
- return insertNodesBefore(parentElt(target), target.nextSibling, fragment);
- }
-
- function swapInnerHTML(target, fragment) {
- var firstChild = target.firstChild;
- var settleTasks = insertNodesBefore(target, firstChild, fragment);
- if (firstChild) {
- while (firstChild.nextSibling) {
- target.removeChild(firstChild.nextSibling);
- }
- target.removeChild(firstChild);
- }
- return settleTasks;
- }
-
- function maybeSelectFromResponse(elt, fragment) {
- var selector = getClosestAttributeValue(elt, "kt-select");
- if (selector) {
- var newFragment = getDocument().createDocumentFragment();
- forEach(fragment.querySelectorAll(selector), function (node) {
- newFragment.appendChild(node);
- });
- fragment = newFragment;
- }
- return fragment;
- }
-
- function swapResponse(swapStyle, target, elt, responseText) {
- var fragment = makeFragment(responseText);
- if (fragment) {
- var settleTasks = handleOutOfBandSwaps(fragment);
-
- fragment = maybeSelectFromResponse(elt, fragment);
-
- switch(swapStyle) {
- case "outerHTML": return concat(settleTasks, swapOuterHTML(target, fragment));
- case "afterbegin": return concat(settleTasks, swapAfterBegin(target, fragment));
- case "beforebegin": return concat(settleTasks, swapBeforeBegin(target, fragment));
- case "beforeend": return concat(settleTasks, swapBeforeEnd(target, fragment));
- case "afterend": return concat(settleTasks, swapAfterEnd(target, fragment));
- default: return concat(settleTasks, swapInnerHTML(target, fragment));
- }
- }
- }
-
- function handleTrigger(elt, trigger) {
- if (trigger) {
- if (trigger.indexOf("{") === 0) {
- var triggers = JSON.parse(trigger);
- for (var eventName in triggers) {
- if (triggers.hasOwnProperty(eventName)) {
- var detail = triggers[eventName];
- if (!isRawObject(detail)) {
- detail = {"value": detail}
- }
- triggerEvent(elt, eventName, detail);
- }
- }
- } else {
- triggerEvent(elt, trigger, []);
- }
- }
- }
-
- function getTriggerSpec(elt) {
-
- var triggerSpec = {
- "trigger" : "click"
- }
- var explicitTrigger = getAttributeValue(elt, 'kt-trigger');
- if (explicitTrigger) {
- var tokens = splitOnWhitespace(explicitTrigger);
- if (tokens.length > 0) {
- var trigger = tokens[0];
- if (trigger === "every") {
- triggerSpec.pollInterval = parseInterval(tokens[1]);
- } else if (trigger.indexOf("sse:") === 0) {
- triggerSpec.sseEvent = trigger.substr(4);
- } else {
- triggerSpec['trigger'] = trigger;
- for (var i = 1; i < tokens.length; i++) {
- var token = tokens[i].trim();
- if (token === "changed") {
- triggerSpec.changed = true;
- }
- if (token === "once") {
- triggerSpec.once = true;
- }
- if (token.indexOf("delay:") === 0) {
- triggerSpec.delay = parseInterval(token.substr(6));
- }
- }
- }
- }
- } else {
- if (matches(elt, 'form')) {
- triggerSpec['trigger'] = 'submit';
- } else if (matches(elt, 'input, textarea, select')) {
- triggerSpec['trigger'] = 'change';
- }
- }
- return triggerSpec;
- }
-
- 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;
- }
-
- function processPolling(elt, verb, path, interval) {
- var nodeData = getInternalData(elt);
- nodeData.timeout = setTimeout(function () {
- if (bodyContains(elt) && nodeData.cancelled !== true) {
- issueAjaxRequest(elt, verb, path);
- processPolling(elt, verb, getAttributeValue(elt, "kt-" + verb), interval);
- }
- }, interval);
- }
-
- function isLocalLink(elt) {
- return location.hostname === elt.hostname &&
- getRawAttribute(elt,'href') &&
- getRawAttribute(elt,'href').indexOf("#") !== 0;
- }
-
- function boostElement(elt, nodeData, triggerSpec) {
- if ((elt.tagName === "A" && isLocalLink(elt)) || elt.tagName === "FORM") {
- nodeData.boosted = true;
- var verb, path;
- if (elt.tagName === "A") {
- verb = "get";
- path = getRawAttribute(elt, 'href');
- } else {
- var rawAttribute = getRawAttribute(elt, "method");
- verb = rawAttribute ? rawAttribute.toLowerCase() : "get";
- path = getRawAttribute(elt, 'action');
- }
- addEventListener(elt, verb, path, nodeData, triggerSpec, true);
- }
- }
-
- function shouldCancel(elt) {
- return elt.tagName === "FORM" ||
- (matches(elt, 'input[type="submit"], button') && closest(elt, 'form') !== null) ||
- (elt.tagName === "A" && elt.href && elt.href.indexOf('#') !== 0);
- }
-
- function addEventListener(elt, verb, path, nodeData, triggerSpec, explicitCancel) {
- var eventListener = function (evt) {
- if(explicitCancel || shouldCancel(elt)) evt.preventDefault();
- var eventData = getInternalData(evt);
- var elementData = getInternalData(elt);
- if (!eventData.handled) {
- eventData.handled = true;
- if (triggerSpec.once) {
- if (elementData.triggeredOnce) {
- return;
- } else {
- elementData.triggeredOnce = true;
- }
- }
- if (triggerSpec.changed) {
- if (elementData.lastValue === elt.value) {
- return;
- } else {
- elementData.lastValue = elt.value;
- }
- }
- if (elementData.delayed) {
- clearTimeout(elementData.delayed);
- }
- var issueRequest = function(){
- issueAjaxRequest(elt, verb, path, evt.target);
- }
- if (triggerSpec.delay) {
- elementData.delayed = setTimeout(issueRequest, triggerSpec.delay);
- } else {
- issueRequest();
- }
- }
- };
- nodeData.trigger = triggerSpec.trigger;
- nodeData.eventListener = eventListener;
- elt.addEventListener(triggerSpec.trigger, eventListener);
- }
-
- function initScrollHandler() {
- if (!window['kuttyScrollHandler']) {
- var scrollHandler = function() {
- forEach(getDocument().querySelectorAll("[kt-trigger='revealed']"), function (elt) {
- maybeReveal(elt);
- });
- };
- window['kuttyScrollHandler'] = scrollHandler;
- window.addEventListener("scroll", scrollHandler)
- }
- }
-
- function maybeReveal(elt) {
- var nodeData = getInternalData(elt);
- if (!nodeData.revealed && isScrolledIntoView(elt)) {
- nodeData.revealed = true;
- issueAjaxRequest(elt, nodeData.verb, nodeData.path);
- }
- }
-
- function maybeCloseSSESource(elt) {
- if (!bodyContains(elt)) {
- elt.sseSource.close();
- return true;
- }
- }
-
- function initSSESource(elt, sseSrc) {
- var detail = {
- config:{withCredentials: true}
- };
- triggerEvent(elt, "initSSE.kutty", detail);
- var source = new EventSource(sseSrc, detail.config);
- source.onerror = function (e) {
- triggerErrorEvent(elt, "sseError.kutty", {error:e, source:source});
- maybeCloseSSESource(elt);
- };
- getInternalData(elt).sseSource = source;
- }
-
- function processSSETrigger(elt, verb, path, sseEventName) {
- var sseSource = getClosestMatch(elt, function (parent) {
- return parent.sseSource;
- });
- if (sseSource) {
- var sseListener = function () {
- if (!maybeCloseSSESource(sseSource)) {
- if (bodyContains(elt)) {
- issueAjaxRequest(elt, verb, path);
- } else {
- sseSource.sseSource.removeEventListener(sseEventName, sseListener);
- }
- }
- };
- sseSource.sseSource.addEventListener(sseEventName, sseListener);
- } else {
- triggerErrorEvent(elt, "noSSESourceError.kutty")
- }
- }
-
- function loadImmediately(elt, verb, path, nodeData, delay) {
- var load = function(){
- if (!nodeData.loaded) {
- nodeData.loaded = true;
- issueAjaxRequest(elt, verb, path);
- }
- }
- if (delay) {
- setTimeout(load, delay);
- } else {
- load();
- }
- }
-
- function processVerbs(elt, nodeData, triggerSpec) {
- var explicitAction = false;
- forEach(VERBS, function (verb) {
- var path = getAttributeValue(elt, 'kt-' + verb);
- if (path) {
- explicitAction = true;
- nodeData.path = path;
- nodeData.verb = verb;
- if (triggerSpec.sseEvent) {
- processSSETrigger(elt, verb, path, triggerSpec.sseEvent);
- } else if (triggerSpec.trigger === "revealed") {
- initScrollHandler();
- maybeReveal(elt);
- } else if (triggerSpec.trigger === "load") {
- loadImmediately(elt, verb, path, nodeData, triggerSpec.delay);
- } else if (triggerSpec.pollInterval) {
- nodeData.polling = true;
- processPolling(elt, verb, path, triggerSpec.pollInterval);
- } else {
- addEventListener(elt, verb, path, nodeData, triggerSpec);
- }
- }
- });
- return explicitAction;
- }
-
- function processNode(elt) {
- var nodeData = getInternalData(elt);
- if (!nodeData.processed) {
- nodeData.processed = true;
-
- var triggerSpec = getTriggerSpec(elt);
- var explicitAction = processVerbs(elt, nodeData, triggerSpec);
-
- if (!explicitAction && getClosestAttributeValue(elt, "kt-boost") === "true") {
- boostElement(elt, nodeData, triggerSpec);
- }
- var sseSrc = getAttributeValue(elt, 'kt-sse-source');
- if (sseSrc) {
- initSSESource(elt, sseSrc);
- }
- var addClass = getAttributeValue(elt, 'kt-classes');
- if (addClass) {
- processClassList(elt, addClass);
- }
- }
- if (elt.children) { // IE
- forEach(elt.children, function(child) { processNode(child) });
- }
- }
-
- //====================================================================
- // Event/Log Support
- //====================================================================
-
- function sendError(elt, eventName, detail) {
- var errorURL = getClosestAttributeValue(elt, "kt-error-url");
- if (errorURL) {
- var xhr = new XMLHttpRequest();
- xhr.open("POST", errorURL);
- xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
- xhr.send(JSON.stringify({ "elt": elt.id, "event": eventName, "detail" : detail }));
- }
- }
-
- function makeEvent(eventName, detail) {
- var evt;
- if (window.CustomEvent && typeof window.CustomEvent === 'function') {
- evt = new CustomEvent(eventName, {bubbles: true, cancelable: true, detail: detail});
- } else {
- evt = getDocument().createEvent('CustomEvent');
- evt.initCustomEvent(eventName, true, true, detail);
- }
- return evt;
- }
-
- function triggerErrorEvent(elt, eventName, detail) {
- triggerEvent(elt, eventName, mergeObjects({isError:true}, detail));
- }
-
- function triggerEvent(elt, eventName, detail) {
- detail["elt"] = elt;
- var event = makeEvent(eventName, detail);
- if (kutty.logger) {
- kutty.logger(elt, eventName, detail);
- if (detail.isError) {
- sendError(elt, eventName, detail);
- }
- }
- var eventResult = elt.dispatchEvent(event);
- return eventResult;
- }
-
- //====================================================================
- // History Support
- //====================================================================
- var currentPathForHistory = null;
-
- function getHistoryElement() {
- var historyElt = getDocument().querySelector('[kt-history-elt]');
- return historyElt || getDocument().body;
- }
-
- function saveToHistoryCache(url, content, title, scroll) {
- var historyCache = JSON.parse(localStorage.getItem("kutty-history-cache")) || [];
- for (var i = 0; i < historyCache.length; i++) {
- if (historyCache[i].url === url) {
- historyCache = historyCache.slice(i, 1);
- break;
- }
- }
- historyCache.push({url:url, content: content, title:title, scroll:scroll})
- while (historyCache.length > kutty.config.historyCacheSize) {
- historyCache.shift();
- }
- localStorage.setItem("kutty-history-cache", JSON.stringify(historyCache));
- }
-
- function getCachedHistory(url) {
- var historyCache = JSON.parse(localStorage.getItem("kutty-history-cache")) || [];
- for (var i = 0; i < historyCache.length; i++) {
- if (historyCache[i].url === url) {
- return historyCache[i];
- }
- }
- return null;
- }
-
- function saveHistory() {
- var elt = getHistoryElement();
- var path = currentPathForHistory || location.pathname+location.search;
- triggerEvent(getDocument().body, "beforeHistorySave.kutty", {path:path, historyElt:elt});
- if(kutty.config.historyEnabled) history.replaceState({}, getDocument().title, window.location.href);
- saveToHistoryCache(path, elt.innerHTML, getDocument().title, window.scrollY);
- }
-
- function pushUrlIntoHistory(path) {
- if(kutty.config.historyEnabled) history.pushState({}, "", path);
- currentPathForHistory = path;
- }
-
- function settleImmediately(settleTasks) {
- forEach(settleTasks, function (task) {
- task.call();
- });
- }
-
- function loadHistoryFromServer(path) {
- var request = new XMLHttpRequest();
- var details = {path: path, xhr:request};
- triggerEvent(getDocument().body, "historyCacheMiss.kutty", details);
- request.open('GET', path, true);
- request.onload = function () {
- if (this.status >= 200 && this.status < 400) {
- triggerEvent(getDocument().body, "historyCacheMissLoad.kutty", details);
- var fragment = makeFragment(this.response);
- fragment = fragment.querySelector('[kt-history-elt]') || fragment;
- settleImmediately(swapInnerHTML(getHistoryElement(), fragment));
- currentPathForHistory = path;
- } else {
- triggerErrorEvent(getDocument().body, "historyCacheMissLoadError.kutty", details);
- }
- };
- request.send();
- }
-
- function restoreHistory(path) {
- saveHistory(currentPathForHistory);
- path = path || location.pathname+location.search;
- triggerEvent(getDocument().body, "historyRestore.kutty", {path:path});
- var cached = getCachedHistory(path);
- if (cached) {
- settleImmediately(swapInnerHTML(getHistoryElement(), makeFragment(cached.content)));
- document.title = cached.title;
- window.scrollTo(0, cached.scroll);
- currentPathForHistory = path;
- } else {
- loadHistoryFromServer(path);
- }
- }
-
- function shouldPush(elt) {
- return getClosestAttributeValue(elt, "kt-push-url") === "true" ||
- (elt.tagName === "A" && getInternalData(elt).boosted);
- }
-
- function addRequestIndicatorClasses(elt) {
- mutateRequestIndicatorClasses(elt, "add");
- }
-
- function removeRequestIndicatorClasses(elt) {
- mutateRequestIndicatorClasses(elt, "remove");
- }
-
- function mutateRequestIndicatorClasses(elt, action) {
- var indicator = getClosestAttributeValue(elt, 'kt-indicator');
- if (indicator) {
- var indicators = getDocument().querySelectorAll(indicator);
- } else {
- indicators = [elt];
- }
- forEach(indicators, function(ic) {
- ic.classList[action].call(ic.classList, "kutty-request");
- });
- }
-
- //====================================================================
- // Input Value Processing
- //====================================================================
-
- function haveSeenNode(processed, elt) {
- for (var i = 0; i < processed.length; i++) {
- var node = processed[i];
- if (node.isSameNode(elt)) {
- return true;
- }
- }
- return false;
- }
-
- function shouldInclude(elt) {
- if(elt.name === "" || elt.name == null || elt.disabled) {
- return false;
- }
- // ignore "submitter" types (see jQuery src/serialize.js)
- if (elt.type === "button" || elt.type === "submit" || elt.tagName === "image" || elt.tagName === "reset" || elt.tagName === "file" ) {
- return false;
- }
- if (elt.type === "checkbox" || elt.type === "radio" ) {
- return elt.checked;
- }
- return true;
- }
-
- function processInputValue(processed, values, elt) {
- if (elt == null || haveSeenNode(processed, elt)) {
- return;
- } else {
- processed.push(elt);
- }
- if (shouldInclude(elt)) {
- var name = getRawAttribute(elt,"name");
- var value = elt.value;
- if (name && value) {
- var current = values[name];
- if(current) {
- if (Array.isArray(current)) {
- current.push(value);
- } else {
- values[name] = [current, value];
- }
- } else {
- values[name] = value;
- }
- }
- }
- if (matches(elt, 'form')) {
- var inputs = elt.elements;
- forEach(inputs, function(input) {
- processInputValue(processed, values, input);
- });
- }
- }
-
- function getInputValues(elt, verb) {
- var processed = [];
- var values = {};
- // include the element itself
- processInputValue(processed, values, elt);
-
- // include any explicit includes
- var includes = getClosestAttributeValue(elt, "kt-include");
- if (includes) {
- var nodes = getDocument().querySelectorAll(includes);
- forEach(nodes, function(node) {
- processInputValue(processed, values, node);
- });
- }
-
- // for a non-GET include the closest form
- if (verb !== 'get') {
- processInputValue(processed, values, closest(elt, 'form'));
- }
- return values;
- }
-
- function appendParam(returnStr, name, realValue) {
- if (returnStr !== "") {
- returnStr += "&";
- }
- returnStr += encodeURIComponent(name) + "=" + encodeURIComponent(realValue);
- return returnStr;
- }
-
- function urlEncode(values) {
- var returnStr = "";
- for (var name in values) {
- if (values.hasOwnProperty(name)) {
- var value = values[name];
- if (Array.isArray(value)) {
- forEach(value, function(v) {
- returnStr = appendParam(returnStr, name, v);
- });
- } else {
- returnStr = appendParam(returnStr, name, value);
- }
- }
- }
- return returnStr;
- }
-
- //====================================================================
- // Ajax
- //====================================================================
-
- function getHeaders(elt, target, prompt, eventTarget) {
- var headers = {
- "X-KT-Request" : "true",
- "X-KT-Trigger" : getRawAttribute(elt, "id"),
- "X-KT-Trigger-Name" : getRawAttribute(elt, "name"),
- "X-KT-Target" : getRawAttribute(target, "id"),
- "Current-URL" : getDocument().location.href,
- }
- if (prompt) {
- headers["X-KT-Prompt"] = prompt;
- }
- if (eventTarget) {
- headers["X-KT-Event-Target"] = getRawAttribute(eventTarget, "id");
- }
- if (getDocument().activeElement) {
- headers["X-KT-Active-Element"] = getRawAttribute(getDocument().activeElement, "id");
- headers["X-KT-Active-Element-Name"] = getRawAttribute(getDocument().activeElement, "name");
- if (getDocument().activeElement.value) {
- headers["X-KT-Active-Element-Value"] = getRawAttribute(getDocument().activeElement, "value");
- }
- }
- return headers;
- }
-
- function filterValues(inputValues, elt, verb) {
- var paramsValue = getClosestAttributeValue(elt, "kt-params");
- if (paramsValue) {
- if (paramsValue === "none") {
- return {};
- } else if (paramsValue === "*") {
- return inputValues;
- } else if(paramsValue.indexOf("not ") === 0) {
- forEach(paramsValue.substr(4).split(","), function (name) {
- name = name.trim();
- delete inputValues[name];
- });
- return inputValues;
- } else {
- var newValues = {}
- forEach(paramsValue.split(","), function (name) {
- name = name.trim();
- newValues[name] = inputValues[name];
- });
- return newValues;
- }
- } else {
- return inputValues;
- }
- }
-
- function getSwapSpecification(elt) {
- var swapInfo = getClosestAttributeValue(elt, "kt-swap");
- var swapSpec = {
- "swapStyle" : kutty.config.defaultSwapStyle,
- "swapDelay" : kutty.config.defaultSwapDelay,
- "settleDelay" : kutty.config.defaultSettleDelay
- }
- if (swapInfo) {
- var split = splitOnWhitespace(swapInfo);
- if (split.length > 0) {
- swapSpec["swapStyle"] = split[0];
- for (var i = 1; i < split.length; i++) {
- var modifier = split[i];
- if (modifier.indexOf("swap:") === 0) {
- swapSpec["swapDelay"] = parseInterval(modifier.substr(5));
- }
- if (modifier.indexOf("settle:") === 0) {
- swapSpec["settleDelay"] = parseInterval(modifier.substr(7));
- }
- }
- }
- }
- return swapSpec;
- }
-
- function issueAjaxRequest(elt, verb, path, eventTarget) {
- var target = getTarget(elt);
- if (target == null) {
- triggerErrorEvent(elt, 'targetError.kutty', {target: getRawAttribute(elt, "kt-target")});
- return;
- }
- var eltData = getInternalData(elt);
- if (eltData.requestInFlight) {
- return;
- } else {
- eltData.requestInFlight = true;
- }
- var endRequestLock = function(){
- eltData.requestInFlight = false
- }
- var promptQuestion = getClosestAttributeValue(elt, "kt-prompt");
- if (promptQuestion) {
- var prompt = prompt(promptQuestion);
- if(!triggerEvent(elt, 'prompt.kutty', {prompt: prompt, target:target})) return endRequestLock();
- }
-
- var confirmQuestion = getClosestAttributeValue(elt, "kt-confirm");
- if (confirmQuestion) {
- if(!confirm(confirmQuestion)) return endRequestLock();
- }
-
- var xhr = new XMLHttpRequest();
-
- var headers = getHeaders(elt, target, prompt, eventTarget);
- var rawParameters = getInputValues(elt, verb);
- var filteredParameters = filterValues(rawParameters, elt, verb);
-
- if (verb !== 'get') {
- headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
- if (verb !== 'post') {
- headers['X-HTTP-Method-Override'] = verb.toUpperCase();
- }
- }
-
- var requestConfig = {
- parameters: filteredParameters,
- unfilteredParameters:rawParameters,
- headers:headers,
- target:target,
- verb:verb
- };
- if(!triggerEvent(elt, 'configRequest.kutty', requestConfig)) return endRequestLock();
-
- // request type
- var requestURL;
- if (verb === 'get') {
- var noValues = Object.keys(filteredParameters).length === 0;
- requestURL = path + (noValues ? "" : "?" + urlEncode(filteredParameters));
- xhr.open('GET', requestURL, true);
- } else {
- requestURL = path;
- xhr.open('POST', requestURL, true);
- }
-
- xhr.overrideMimeType("text/html");
-
- // request headers
- for (var header in headers) {
- if (headers.hasOwnProperty(header)) {
- if(headers[header]) xhr.setRequestHeader(header, headers[header]);
- }
- }
-
- var eventDetail = {xhr: xhr, target: target};
- xhr.onload = function () {
- try {
- if (!triggerEvent(elt, 'beforeOnLoad.kutty', eventDetail)) return;
-
- handleTrigger(elt, this.getResponseHeader("X-KT-Trigger"));
- var pushedUrl = this.getResponseHeader("X-KT-Push");
-
- var shouldSaveHistory = shouldPush(elt) || pushedUrl;
-
- if (this.status >= 200 && this.status < 400) {
- if (this.status === 286) {
- cancelPolling(elt);
- }
- // don't process 'No Content' response
- if (this.status !== 204) {
- if (!triggerEvent(elt, 'beforeSwap.kutty', eventDetail)) return;
-
- var resp = this.response;
-
- // Save current page
- if (shouldSaveHistory) {
- saveHistory();
- }
-
- var swapSpec = getSwapSpecification(elt);
-
- target.classList.add("kutty-swapping");
- var doSwap = function () {
- try {
- var settleTasks = swapResponse(swapSpec.swapStyle, target, elt, resp);
- target.classList.remove("kutty-swapping");
- target.classList.add("kutty-settling");
- triggerEvent(elt, 'afterSwap.kutty', eventDetail);
-
- var doSettle = function(){
- forEach(settleTasks, function (settleTask) {
- settleTask.call();
- });
- target.classList.remove("kutty-settling");
- // push URL and save new page
- if (shouldSaveHistory) {
- pushUrlIntoHistory(pushedUrl || requestURL );
- }
- triggerEvent(elt, 'afterSettle.kutty', eventDetail);
- }
-
- if (swapSpec.settleDelay > 0) {
- setTimeout(doSettle, swapSpec.settleDelay)
- } else {
- doSettle();
- }
- } catch (e) {
- triggerErrorEvent(elt, 'swapError.kutty', eventDetail);
- throw e;
- }
- };
-
- if (swapSpec.swapDelay > 0) {
- setTimeout(doSwap, swapSpec.swapDelay)
- } else {
- doSwap();
- }
- }
- } else {
- triggerErrorEvent(elt, 'responseError.kutty', eventDetail);
- }
- } catch (e) {
- eventDetail['exception'] = e;
- triggerErrorEvent(elt, 'onLoadError.kutty', eventDetail);
- throw e;
- } finally {
- removeRequestIndicatorClasses(elt);
- endRequestLock();
- triggerEvent(elt, 'afterOnLoad.kutty', eventDetail);
- }
- }
- xhr.onerror = function () {
- removeRequestIndicatorClasses(elt);
- triggerErrorEvent(elt, 'sendError.kutty', eventDetail);
- endRequestLock();
- }
- if(!triggerEvent(elt, 'beforeRequest.kutty', eventDetail)) return endRequestLock();
- addRequestIndicatorClasses(elt);
- xhr.send(verb === 'get' ? null : urlEncode(filteredParameters));
- }
-
- //====================================================================
- // Initialization
- //====================================================================
-
- function ready(fn) {
- if (getDocument().readyState !== 'loading') {
- fn();
- } else {
- getDocument().addEventListener('DOMContentLoaded', fn);
- }
- }
-
- // insert kutty-indicator css rules
- addRule(".kutty-indicator{opacity:0;transition: opacity 200ms ease-in;}");
- addRule(".kutty-request .kutty-indicator{opacity:1}");
- addRule(".kutty-request.kutty-indicator{opacity:1}");
-
- function mergeMetaConfig() {
- var element = getDocument().querySelector('meta[name="kutty-config"]');
- if (element) {
- var source = JSON.parse(element.content);
- kutty.config = mergeObjects(kutty.config , source)
- }
- }
-
- // initialize the document
- ready(function () {
- mergeMetaConfig();
- var body = getDocument().body;
- processNode(body);
- triggerEvent(body, 'load.kutty', {});
- window.onpopstate = function () {
- restoreHistory();
- };
- })
-
- // Public API
- return {
- onLoad: onLoadHelper,
- process: processNode,
- on: addKuttyEventListener,
- off: removeKuttyEventListener,
- trigger : triggerEvent,
- find : find,
- findAll : findAll,
- closest : closest,
- remove : removeElement,
- addClass : addClassToElement,
- removeClass : removeClassFromElement,
- toggleClass : toggleClassOnElement,
- takeClass : takeClassForElement,
- logAll : logAll,
- logger : null,
- config : {
- historyEnabled:true,
- historyCacheSize:10,
- defaultSwapStyle:'innerHTML',
- defaultSwapDelay:0,
- defaultSettleDelay:100
- },
- version: "0.0.1",
- _:internalEval
- }
- }
-)(); \ No newline at end of file
diff --git a/www/posts/2020-5-18-kutty-er-htmx-0.0.2-is-released.md b/www/posts/2020-5-18-kutty-er-htmx-0.0.2-is-released.md
new file mode 100644
index 00000000..6b85ec54
--- /dev/null
+++ b/www/posts/2020-5-18-kutty-er-htmx-0.0.2-is-released.md
@@ -0,0 +1,38 @@
+---
+layout: layout.njk
+tags: post
+title: htmx 0.0.2 has been released!
+---
+
+## htmx 0.0.3 Release
+
+I'm pleased to announce the [0.0.2 release](https://unpkg.com/browse/htmx.org@0.0.3/) of kutty, the successor
+to [intercooler.js](http://intercoolerjs.org)!
+
+#### Why not kutty 0.0.2?
+
+One of the reasons you put a `0.0.1` release out there is to see what happens. And one of the things that
+happened was that multiple people made comments on how the word "kutty" meant different things in different languages, including
+"small", "child" and a very unfortunate meaning in dutch slang. I had originally
+[called the project `htmx`](https://github.com/bigskysoftware/kutty/commit/b003ccadf855fe49a40ca0b86ca3c9e16448d33c#diff-b9cfc7f2cdf78a7f4b91a753d10865a2)
+(html extensions) and went back and forth between the two names for a bit.
+
+It seems like, upon contact with reality, `htmx` is a better long term name for the project. It's also
+a lot easier to search twitter & reddit for that term.
+
+It's a simple fix for anyone who actually used `0.0.1`:
+
+* attributes go from `kt-` to `hx-` (their original prefix)
+* request headers go from `X-KT-` to `X-HX-`
+* `kutty` goes to `htmx` for event names, etc.
+
+#### Changes
+
+OK, so besides the big re-rename, what changed?
+
+* A bug fix for the `hx-prompt` attribute
+* A bug fix for multiple `hx-swap-oob` attributes
+* Moved the default CSS indicator injection into its own sheet to avoid breaking
+* Added the `htmx.config.includeIndicatorStyles` configuration option so people can opt out of injecting the indicator CSS
+
+Cheers! \ No newline at end of file
diff --git a/www/reference.md b/www/reference.md
index 856f5584..98b31560 100644
--- a/www/reference.md
+++ b/www/reference.md
@@ -1,42 +1,42 @@
---
layout: layout.njk
-title: </> kutty - Attributes
+title: </> htmx - Attributes
---
## <a name="attributes"></a> [Attribute Reference](#attributes)
| Attribute | Description |
|-----------|-------------|
-| [`kt-boost`](/attributes/kt-boost) | progressively enhances anchors and forms to use AJAX requests
-| [`kt-classes`](/attributes/kt-classes) | timed modification of classes on an element
-| [`kt-confirm`](/attributes/kt-confirm) | shows a confim() dialog before issuing a request
-| [`kt-delete`](/attributes/kt-delete) | issues a `DELETE` to the specified URL
-| [`kt-error-url`](/attributes/kt-error-url) | a URL to send client-side errors to
-| [`kt-get`](/attributes/kt-get) | issues a `GET` to the specified URL
-| [`kt-history-elt`](/attributes/kt-history-elt) | the element to snapshot and restore during history navigation
-| [`kt-include`](/attributes/kt-include) | includes additional data in AJAX requests
-| [`kt-indicator`](/attributes/kt-indicator) | the element to put the `kutty-request` class on during the AJAX request
-| [`kt-params`](/attributes/kt-params) | filters the parameters that will be submitted with a request
-| [`kt-patch`](/attributes/kt-patch) | issues a `PATCH` to the specified URL
-| [`kt-post`](/attributes/kt-post) | issues a `POST` to the specified URL
-| [`kt-prompt`](/attributes/kt-prompt) | shows a prompt before submitting a request
-| [`kt-push-url`](/attributes/kt-push-url) | pushes the URL into the location bar, creating a new history entry
-| [`kt-put`](/attributes/kt-put) | issues a `PUT` to the specified URL
-| [`kt-select`](/attributes/kt-select) | selects a subset of the server response to process
-| [`kt-sse-src`](/attributes/kt-sse-src) | establishes an [SSE](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) source for events
-| [`kt-swap-oob`](/attributes/kt-swap-oob) | marks content in a response as being "Out of Band", i.e. swapped somewhere other than the target
-| [`kt-swap`](/attributes/kt-swap) | controls how the response content is swapped into the DOM (e.g. 'outerHTML' or 'beforeEnd')
-| [`kt-target`](/attributes/kt-target) | specifies the target element to be swapped
-| [`kt-trigger`](/attributes/kt-trigger) | specifies the event that triggers the request
+| [`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
+| [`hx-get`](/attributes/hx-get) | issues a `GET` to the specified URL
+| [`hx-history-elt`](/attributes/hx-history-elt) | the element to snapshot and restore during history navigation
+| [`hx-include`](/attributes/hx-include) | includes additional data in AJAX requests
+| [`hx-indicator`](/attributes/hx-indicator) | the element to put the `htmx-request` class on during the AJAX request
+| [`hx-params`](/attributes/hx-params) | filters the parameters that will be submitted with a request
+| [`hx-patch`](/attributes/hx-patch) | issues a `PATCH` to the specified URL
+| [`hx-post`](/attributes/hx-post) | issues a `POST` to the specified URL
+| [`hx-prompt`](/attributes/hx-prompt) | shows a prompt before submitting a request
+| [`hx-push-url`](/attributes/hx-push-url) | pushes the URL into the location bar, creating a new history entry
+| [`hx-put`](/attributes/hx-put) | issues a `PUT` to the specified URL
+| [`hx-select`](/attributes/hx-select) | selects a subset of the server response to process
+| [`hx-sse-src`](/attributes/hx-sse-src) | establishes an [SSE](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) source for events
+| [`hx-swap-oob`](/attributes/hx-swap-oob) | marks content in a response as being "Out of Band", i.e. swapped somewhere other than the target
+| [`hx-swap`](/attributes/hx-swap) | controls how the response content is swapped into the DOM (e.g. 'outerHTML' or 'beforeEnd')
+| [`hx-target`](/attributes/hx-target) | specifies the target element to be swapped
+| [`hx-trigger`](/attributes/hx-trigger) | specifies the event that triggers the request
## <a name="classes"></a> [CSS Class Reference](#classes)
| Class | Description |
|-----------|-------------|
-| `kutty-indicator` | A dynamically generated class that will toggle visible (opacity:1) when a `kutty-request` class is present
-| `kutty-request` | Applied to either the element or the element specified with [`kt-indicator`](/attributes/kt-indicator) while a request is ongoing
-| `kutty-settling` | Applied to a target after content is swapped, removed after it is settled
-| `kutty-swapping` | Applied to a target before any content is swapped, removed after it is swapped
+| `htmx-indicator` | A dynamically generated class that will toggle visible (opacity:1) when a `htmx-request` class is present
+| `htmx-request` | Applied to either the element or the element specified with [`hx-indicator`](/attributes/hx-indicator) while a request is ongoing
+| `htmx-settling` | Applied to a target after content is swapped, removed after it is settled
+| `htmx-swapping` | Applied to a target before any content is swapped, removed after it is swapped
## <a name="headers"></a> [HTTP Header Reference](#headers)
@@ -46,48 +46,48 @@ title: </> kutty - Attributes
| Header | Description |
|-------|-------------|
| `X-HTTP-Method-Override` | the HTTP verb for non-`GET` and `POST` requests
-| `X-KT-Active-Element-Name` | the `name` of the active element if it exists
-| `X-KT-Active-Element-Value` | the `value` of the active element if it exists
-| `X-KT-Active-Element` | the `id` of the active element if it exists
-| `X-KT-Current-URL` | the current URL of the browser
-| `X-KT-Event-Target` | the `id` of the original event target
-| `X-KT-Prompt` | the user response to an [ic-prompt](/attributes/kt-prompt)
-| `X-KT-Request` | always `true`
-| `X-KT-Target` | the `id` of the target element if it exists
-| `X-KT-Trigger-Name` | the `name` of the triggered element if it exists
-| `X-KT-Trigger` | the `id` of the triggered element if it exists
+| `X-HX-Active-Element-Name` | the `name` of the active element if it exists
+| `X-HX-Active-Element-Value` | the `value` of the active element if it exists
+| `X-HX-Active-Element` | the `id` of the active element if it exists
+| `X-HX-Current-URL` | the current URL of the browser
+| `X-HX-Event-Target` | the `id` of the original event target
+| `X-HX-Prompt` | the user response to an [ic-prompt](/attributes/hx-prompt)
+| `X-HX-Request` | always `true`
+| `X-HX-Target` | the `id` of the target element if it exists
+| `X-HX-Trigger-Name` | the `name` of the triggered element if it exists
+| `X-HX-Trigger` | the `id` of the triggered element if it exists
### <a name="response_headers"></a> [Response Headers](#response_headers)
| Header | Description |
|-------|-------------|
-| `X-KT-Push` | pushes a new url into the history stack
-| [`X-KT-Trigger`](/headers/x-kt-trigger) | allows you to trigger client side events, see the [documentation](/headers/x-kt-trigger) for more info
+| `X-HX-Push` | pushes a new url into the history stack
+| [`X-HX-Trigger`](/headers/x-hx-trigger) | allows you to trigger client side events, see the [documentation](/headers/x-hx-trigger) for more info
## <a name="events"></a> [Event Reference](#events)
| Event | Description |
|-------|-------------|
-| [`afterOnLoad.kutty`](/events#afterOnLoad.kutty) | triggered after an AJAX request has finished
-| [`afterSettle.kutty`](/events#afterSettle.kutty) | triggered after the DOM has settled
-| [`afterSwap.kutty`](/events#afterSwap.kutty) | triggered after new content has been swapped in
-| [`beforeOnLoad.kutty`](/events#beforeOnLoad.kutty) | triggered before any response processing occurs
-| [`beforeRequest.kutty`](/events#beforeRequest.kutty) | triggered before an AJAX request is made
-| [`beforeSwap.kutty`](/events#beforeSwap.kutty) | triggered before a swap is done
-| [`configRequest.kutty`](/events#configRequest.kutty) | triggered before the request, allows you to customize parameters, headers
-| [`historyCacheMiss.kutty`](/events#historyCacheMiss.kutty) | triggered on a cache miss in the history subsystem
-| [`historyCacheMissError.kutty`](/events#historyCacheMissError.kutty) | triggered on a unsuccessful remote retrieval
-| [`historyCacheMissLoad.kutty`](/events#historyCacheMissLoad.kutty) | triggered on a succesful remote retrieval
-| [`historyRestore.kutty`](/events#historyRestore.kutty) | triggered when kutty handles a history restoration action
-| [`beforeHistorySave.kutty`](/events#beforeHistorySave.kutty) | triggered before content is saved to the history cache
-| [`initSSE.kutty`](/events#initSSE.kutty) | triggered when a new Server Sent Event source is created
-| [`load.kutty`](/events#load.kutty) | triggered when new content is added to the DOM
-| [`noSSESourceError.kutty`](/events#noSSESourceError.kutty) | triggered when an element refers to a SSE event in its trigger, but no parent SSE source has been defined
-| [`onLoadError.kutty`](/events#onLoadError.kutty) | triggered when an exception occurs during the onLoad handling in kutty
-| [`oobErrorNoTarget.kutty`](/events#oobErrorNoTarget.kutty) | triggered when an out of band element does not have a matching ID in the current DOM
-| [`prompt.kutty`](/events#prompt.kutty) | triggered after a prompt is shown
-| [`responseError.kutty`](/events#responseError.kutty) | triggered when an HTTP response error (non-`200` or `300` response code) occurs
-| [`sendError.kutty`](/events#sendError.kutty) | triggered when a network error prevents an HTTP request from happening
-| [`sseError.kutty`](/events#sseError.kutty) | triggered when an error occurs with a SSE source
-| [`swapError.kutty`](/events#swapError.kutty) | triggered when an error occurs during the swap phase
-| [`targetError.kutty`](/events#targetError.kutty) | triggered when an invalid target is specified
+| [`afterOnLoad.htmx`](/events#afterOnLoad.htmx) | triggered after an AJAX request has finished
+| [`afterSettle.htmx`](/events#afterSettle.htmx) | triggered after the DOM has settled
+| [`afterSwap.htmx`](/events#afterSwap.htmx) | triggered after new content has been swapped in
+| [`beforeOnLoad.htmx`](/events#beforeOnLoad.htmx) | triggered before any response processing occurs
+| [`beforeRequest.htmx`](/events#beforeRequest.htmx) | triggered before an AJAX request is made
+| [`beforeSwap.htmx`](/events#beforeSwap.htmx) | triggered before a swap is done
+| [`configRequest.htmx`](/events#configRequest.htmx) | triggered before the request, allows you to customize parameters, headers
+| [`historyCacheMiss.htmx`](/events#historyCacheMiss.htmx) | triggered on a cache miss in the history subsystem
+| [`historyCacheMissError.htmx`](/events#historyCacheMissError.htmx) | triggered on a unsuccessful remote retrieval
+| [`historyCacheMissLoad.htmx`](/events#historyCacheMissLoad.htmx) | triggered on a succesful remote retrieval
+| [`historyRestore.htmx`](/events#historyRestore.htmx) | triggered when htmx handles a history restoration action
+| [`beforeHistorySave.htmx`](/events#beforeHistorySave.htmx) | triggered before content is saved to the history cache
+| [`initSSE.htmx`](/events#initSSE.htmx) | triggered when a new Server Sent Event source is created
+| [`load.htmx`](/events#load.htmx) | triggered when new content is added to the DOM
+| [`noSSESourceError.htmx`](/events#noSSESourceError.htmx) | triggered when an element refers to a SSE event in its trigger, but no parent SSE source has been defined
+| [`onLoadError.htmx`](/events#onLoadError.htmx) | triggered when an exception occurs during the onLoad handling in htmx
+| [`oobErrorNoTarget.htmx`](/events#oobErrorNoTarget.htmx) | triggered when an out of band element does not have a matching ID in the current DOM
+| [`prompt.htmx`](/events#prompt.htmx) | triggered after a prompt is shown
+| [`responseError.htmx`](/events#responseError.htmx) | triggered when an HTTP response error (non-`200` or `300` response code) occurs
+| [`sendError.htmx`](/events#sendError.htmx) | triggered when a network error prevents an HTTP request from happening
+| [`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
diff --git a/www/talk.md b/www/talk.md
index 27a1804b..f5dc69b9 100644
--- a/www/talk.md
+++ b/www/talk.md
@@ -1,21 +1,21 @@
---
layout: layout.njk
-title: </> kutty - high power tools for html
+title: </> htmx - high power tools for html
---
-## Kutty Talk
+## Htmx Talk
-Right now the best place to talk about kutty is the [intercooler gitter room](https://gitter.im/intercooler-js/Lobby)
+Right now the best place to talk about htmx is the [intercooler gitter room](https://gitter.im/intercooler-js/Lobby)
I'll be setting up a forum and chat room at some point.
## Features & Bug Reports
-[https://github.com/bigskysoftware/kutty/issues](https://github.com/bigskysoftware/kutty/issues)
+[https://github.com/bigskysoftware/htmx/issues](https://github.com/bigskysoftware/htmx/issues)
## Twitter
-[@kutty_org](https://twitter.com/kutty_org)
+[@htmx_org](https://twitter.com/htmx_org)
## Blog & Announcements