Fixed code sample indentation

This commit is contained in:
Ben Croker 2022-05-01 13:20:40 +02:00 committed by GitHub
parent 218976c5ba
commit 9083ad86d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -53,8 +53,8 @@ javascript.
To understand htmx, first lets take a look at an anchor tag:
``` html
<a href="/blog">Blog</a>
```html
<a href="/blog">Blog</a>
```
This anchor tag tells a browser:
@ -64,13 +64,14 @@ This anchor tag tells a browser:
With that in mind, consider the following bit of HTML:
``` html
<button hx-post="/clicked"
hx-trigger="click"
hx-target="#parent-div"
hx-swap="outerHTML">
```html
<button hx-post="/clicked"
hx-trigger="click"
hx-target="#parent-div"
hx-swap="outerHTML"
>
Click Me!
</button>
</button>
```
This tells htmx:
@ -93,8 +94,8 @@ without even needing to really understand that concept.
It's worth mentioning that, if you prefer, you can use the `data-` prefix when using htmx:
``` html
<a data-hx-post="/click">Click Me!</a>
```html
<a data-hx-post="/click">Click Me!</a>
```
## <a name="installing"></a> [Installing](#installing)
@ -111,7 +112,7 @@ The simplest, recommended way to install htmx is to copy it into your project.
Download `htmx.min.js` [from unpkg.com](https://unpkg.com/browse/htmx.org/dist/) and add it to the appropriate directory in your project.
Then, include it where necessary with a `<script>` tag:
``` html
```html
<script src="/path/to/htmx.min.js" defer></script>
```
@ -121,7 +122,7 @@ You can also add extensions this way, by downloading them from the `ext/` direct
For more advanced configuration, you can install htmx with [npm](https://www.npmjs.com/):
``` sh
```sh
npm install htmx.org
```
@ -135,7 +136,7 @@ Avoid using unpkg.com or other JavaScript CDNs in production, for [many good
To use htmx from unpkg.com, use this `<script>` tag:
``` html
```html
<script src="https://unpkg.com/htmx.org@1.7.0" integrity="sha384-EzBXYPt0/T6gxNp0nuPtLkmRpmDBbjg6WmCUZRLXBBwYYmwAUxzlSGej0ARHX0Bo" crossorigin="anonymous" defer></script>
```
@ -145,21 +146,21 @@ If you are using webpack to manage your javascript:
* Install `htmx` via your favourite package manager (like npm or yarn)
* Add the import to your `index.js`
``` js
import 'htmx.org';
```js
import 'htmx.org';
```
If you want to use the global `htmx` variable (recommended), you need to inject it to the window scope:
* Create a custom JS file
* Import this file to your `index.js` (below the import from step 2)
``` js
import 'path/to/my_custom.js';
```
```js
import 'path/to/my_custom.js';
```
* Then add this code to the file:
``` js
window.htmx = require('htmx.org');
```
```js
window.htmx = require('htmx.org');
```
* Finally, rebuild your bundle
## <a name="ajax"></a> [AJAX](#ajax)
@ -179,9 +180,9 @@ 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 hx-put="/messages">
<div hx-put="/messages">
Put To Messages
</div>
</div>
```
This tells the browser:
@ -202,9 +203,9 @@ 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 hx-post="/mouse_entered" hx-trigger="mouseenter">
[Here Mouse, Mouse!]
</div>
<div hx-post="/mouse_entered" hx-trigger="mouseenter">
[Here Mouse, Mouse!]
</div>
```
#### <a name="trigger-modifiers"></a> [Trigger Modifiers](#trigger-modifiers)
@ -213,9 +214,9 @@ A trigger can also have a few additional modifiers that change its behavior. Fo
happen once, you can use the `once` modifier for the trigger:
```html
<div hx-post="/mouse_entered" hx-trigger="mouseenter once">
[Here Mouse, Mouse!]
</div>
<div hx-post="/mouse_entered" hx-trigger="mouseenter once">
[Here Mouse, Mouse!]
</div>
```
Other modifiers you can use for triggers are:
@ -231,12 +232,13 @@ so the request will trigger at the end of the time period.
You can use these attributes to implement many common UX patterns, such as [Active Search](/examples/active-search):
```html
<input type="text" name="q"
hx-get="/trigger_delay"
hx-trigger="keyup changed delay:500ms"
hx-target="#search-results"
placeholder="Search..."/>
<div id="search-results"></div>
<input type="text" name="q"
hx-get="/trigger_delay"
hx-trigger="keyup changed delay:500ms"
hx-target="#search-results"
placeholder="Search..."
>
<div id="search-results"></div>
```
This input will issue a request 500 milliseconds after a key up event if the input has been changed and inserts the results
@ -275,8 +277,8 @@ If you want an element to poll the given URL rather than wait for an event, you
with the [`hx-trigger`](/attributes/hx-trigger/) attribute:
```html
<div hx-get="/news" hx-trigger="every 2s">
</div>
<div hx-get="/news" hx-trigger="every 2s">
</div>
```
This tells htmx
@ -293,9 +295,9 @@ a `load` trigger along with a delay, and replaces itself with the response:
```html
<div hx-get="/messages"
hx-trigger="load delay:1s"
hx-swap="outerHTML">
hx-trigger="load delay:1s"
hx-swap="outerHTML"
>
</div>
```
@ -318,10 +320,10 @@ another element, if specified). The `htmx-request` class will cause a child ele
on it to transition to an opacity of 1, showing the indicator.
```html
<button hx-get="/click">
Click Me!
<img class="htmx-indicator" src="/spinner.gif"/>
</button>
<button hx-get="/click">
Click Me!
<img class="htmx-indicator" src="/spinner.gif">
</button>
```
Here we have a button. When it is clicked the `htmx-request` class will be added to it, which will reveal the spinner
@ -331,27 +333,27 @@ While the `htmx-indicator` class uses opacity to hide and show the progress indi
you can create your own CSS transition like so:
```css
.htmx-indicator{
display:none;
}
.htmx-request .my-indicator{
display:inline;
}
.htmx-request.my-indicator{
display:inline;
}
.htmx-indicator{
display:none;
}
.htmx-request .my-indicator{
display:inline;
}
.htmx-request.my-indicator{
display:inline;
}
```
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 hx-get="/click" hx-indicator="#indicator">
<div>
<button hx-get="/click" hx-indicator="#indicator">
Click Me!
</button>
<img id="indicator" class="htmx-indicator" src="/spinner.gif"/>
</div>
</button>
<img id="indicator" class="htmx-indicator" src="/spinner.gif"/>
</div>
```
Here we call out the indicator explicitly by id. Note that we could have placed the class on the parent `div` as well
@ -363,12 +365,13 @@ If you want the response to be loaded into a different element other than the on
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"
hx-get="/trigger_delay"
hx-trigger="keyup delay:500ms changed"
hx-target="#search-results"
placeholder="Search..."/>
<div id="search-results"></div>
<input type="text" name="q"
hx-get="/trigger_delay"
hx-trigger="keyup delay:500ms changed"
hx-target="#search-results"
placeholder="Search..."
>
<div id="search-results"></div>
```
You can see that the results from the search are going to be loaded into `div#search-results`, rather than into the
@ -403,7 +406,8 @@ Consider a race condition between a form submission and an individual input's va
<form hx-post="/store">
<input id="title" name="title" type="text"
hx-post="/validate"
hx-trigger="change">
hx-trigger="change"
>
<button type="submit">Submit</button>
</form>
```
@ -419,7 +423,8 @@ a form request is present or starts while the input request is in flight:
<input id="title" name="title" type="text"
hx-post="/validate"
hx-trigger="change"
hx-sync="closest form:abort">
hx-sync="closest form:abort"
>
<button type="submit">Submit</button>
</form>
```
@ -442,13 +447,13 @@ htmx makes it easy to use [CSS Transitions](https://developer.mozilla.org/en-US/
javascript. Consider this HTML content:
```html
<div id="div1">Original Content</div>
<div id="div1">Original Content</div>
```
Imagine this content is replaced by htmx via an ajax request with this new content:
```html
<div id="div1" class="red">New Content</div>
<div id="div1" class="red">New Content</div>
```
Note two things:
@ -460,8 +465,8 @@ Given this situation, we can write a CSS transition from the old state to the ne
```css
.red {
color: red;
transition: all ease-in 1s ;
color: red;
transition: all ease-in 1s ;
}
```
@ -490,8 +495,8 @@ If you want to swap content from a response directly into the DOM by using the `
[hx-swap-oob](/attributes/hx-swap-oob) attribute in the *response* html:
```html
<div id="message" hx-swap-oob="true">Swap me directly!</div>
Additional Content
<div id="message" hx-swap-oob="true">Swap me directly!</div>
Additional Content
```
In this response, `div#message` would be swapped directly into the matching DOM element, while the additional content
@ -552,7 +557,7 @@ attribute, which allows you to confirm an action using a simple javascript dialo
```html
<button hx-delete="/account" hx-confirm="Are you sure you wish to delete your account?">
Delete My Account
Delete My Account
</button>
```
@ -566,10 +571,10 @@ allows you to "hoist" attributes up the DOM to avoid code duplication. Consider
```html
<button hx-delete="/account" hx-confirm="Are you sure?">
Delete My Account
Delete My Account
</button>
<button hx-put="/account" hx-confirm="Are you sure?">
Update My Account
Update My Account
</button>
```
@ -578,10 +583,10 @@ Here we have a duplicate `hx-confirm` attribute. We can hoist this attribute to
```html
<div hx-confirm="Are you sure?">
<button hx-delete="/account">
Delete My Account
Delete My Account
</button>
<button hx-put="/account">
Update My Account
Update My Account
</button>
</div>
```
@ -594,13 +599,13 @@ be confirmed. We could add an `unset` directive on it like so:
```html
<div hx-confirm="Are you sure?">
<button hx-delete="/account">
Delete My Account
Delete My Account
</button>
<button hx-put="/account">
Update My Account
Update My Account
</button>
<button hx-confirm="unset" hx-get="/">
Cancel
Cancel
</button>
</div>
```
@ -643,11 +648,12 @@ However, you could wrap the htmx-enhanced input in a form element:
```html
<form action="/search" method="POST">
<input class="form-control" type="search"
name="search" placeholder="Begin Typing To Search Users..."
hx-post="/search"
hx-trigger="keyup changed delay:500ms, search"
hx-target="#search-results"
hx-indicator=".htmx-indicator">
name="search" placeholder="Begin Typing To Search Users..."
hx-post="/search"
hx-trigger="keyup changed delay:500ms, search"
hx-target="#search-results"
hx-indicator=".htmx-indicator"
>
</form>
```
@ -699,25 +705,23 @@ pages to learn more about the new extensions.
If you wish to establish a `WebSocket` connection in htmx, you use the [hx-ws](/attributes/hx-ws) attribute:
```html
<div hx-ws="connect:wss:/chatroom">
<div hx-ws="connect:wss:/chatroom">
<div id="chat_room">
...
...
</div>
<form hx-ws="send:submit">
<input name="chat_message">
</form>
</div>
</div>
```
The `connect` declaration established the connection, and the `send` declaration tells the form to submit values to the
socket on `submit`.
The `connect` declaration established the connection, and the `send` declaration tells the form to submit values to the socket on `submit`.
More details can be found on the [hx-ws attribute page](/attributes/hx-ws)
### <a name="sse"></a> [Server Sent Events](#sse)
[Server Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) are
a way for servers to send events to browsers. It provides a higher-level mechanism for communication between the
[Server Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) are 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 htmx, you need to do two things:
@ -731,9 +735,9 @@ a `connect <url>` declaration that specifies the URL from which Server Sent Even
Here is an example:
```html
<body hx-sse="connect:/news_updates">
<div hx-trigger="sse:new_news" hx-get="/news"></div>
</body>
<body hx-sse="connect:/news_updates">
<div hx-trigger="sse:new_news" hx-get="/news"></div>
</body>
```
Depending on your implementation, this may be more efficient than the polling example above since the server would
@ -747,7 +751,7 @@ If you want a given element to push its request URL into the browser navigation
to the browser's history, include the [hx-push-url](/attributes/hx-push-url) attribute:
```html
<a hx-get="/blog" hx-push-url="true">Blog</a>
<a hx-get="/blog" hx-push-url="true">Blog</a>
```
When a user clicks on this link, htmx will snapshot the current DOM and store it before it makes a request to /blog.
@ -867,12 +871,13 @@ Here is an example of an input that uses the `htmx:validation:validate` event to
```html
<form hx-post="/test">
<input _="on htmx:validation:validate
if my.value != 'foo'
call me.setCustomValidity('Please enter the value foo')
else
call me.setCustomValidity('')"
name="example">
<input _="on htmx:validation:validate
if my.value != 'foo'
call me.setCustomValidity('Please enter the value foo')
else
call me.setCustomValidity('')"
name="example"
>
</form>
```
@ -892,8 +897,8 @@ defined in javascript](/extensions#defining) and then used via the [`hx-ext`](/a
```html
<div hx-ext="debug">
<button hx-post="/example">This button used the debug extension</button>
<button hx-post="/example" hx-ext="ignore:debug">This button does not</button>
<button hx-post="/example">This button used the debug extension</button>
<button hx-post="/example" hx-ext="ignore:debug">This button does not</button>
</div>
```
@ -921,17 +926,17 @@ Htmx has an extensive [events mechanism](https://htmx.org/reference/#events), wh
If you want to register for a given htmx event you can use
```js
document.body.addEventListener('htmx:load', function(evt) {
myJavascriptLib.init(evt.details.elt);
});
document.body.addEventListener('htmx:load', function(evt) {
myJavascriptLib.init(evt.details.elt);
});
```
or, if you would prefer, you can use the following htmx helper:
```javascript
htmx.on("htmx:load", function(evt) {
myJavascriptLib.init(evt.details.elt);
});
htmx.on("htmx:load", function(evt) {
myJavascriptLib.init(evt.details.elt);
});
```
The `htmx:load` event is fired every time an element is loaded into the DOM by htmx, and is effectively the equivalent
@ -944,9 +949,9 @@ Some common uses for htmx events are:
Using the `htmx:load` event to initialize content is so common that htmx provides a helper function:
```javascript
htmx.onLoad(function(target) {
myJavascriptLib.init(target);
});
htmx.onLoad(function(target) {
myJavascriptLib.init(target);
});
```
This does the same thing as the first example, but is a little cleaner.
@ -1007,11 +1012,11 @@ with other libraries. [Alpine.js](https://github.com/alpinejs/alpine/), for exa
If you set a logger at `htmx.logger`, every event will be logged. This can be very useful for troubleshooting:
```javascript
htmx.logger = function(elt, event, data) {
if(console) {
console.log(event, elt, data);
}
htmx.logger = function(elt, event, data) {
if(console) {
console.log(event, elt, data);
}
}
```
## <a name="debugging"></a> [Debugging](#debugging)
@ -1027,7 +1032,7 @@ The first debugging tool you can use is the `htmx.logAll()` method. This will l
will allow you to see exactly what the library is doing.
```javascript
htmx.logAll();
htmx.logAll();
```
Of course, that won't tell you why htmx *isn't* doing something. You might also not know *what* events a DOM
@ -1036,7 +1041,7 @@ element is firing to use as a trigger. To address this, you can use the
browser console:
```javascript
monitorEvents(htmx.find("#theElement"));
monitorEvents(htmx.find("#theElement"));
```
This will spit out all events that are occuring on the element with the id `theElement` to the console, and allow you
@ -1086,7 +1091,7 @@ Here is an example of the code in action:
<!-- post to /foo -->
<button hx-post="/foo" hx-target="#result">
Count Up
Count Up
</button>
<output id="result"></output>
@ -1131,7 +1136,7 @@ on a DOM element, using the `on` syntax:
```html
<div _="on htmx:afterSettle log 'Settled!'">
...
...
</div>
```
@ -1150,7 +1155,7 @@ In hyperscript you can implement this, as well as fade effect, like so:
```html
<div _="on load wait 5s then transition opacity to 0 then remove me">
Here is a temporary message!
Here is a temporary message!
</div>
```
@ -1163,7 +1168,7 @@ In hyperscript similar functionality is implemented like so:
```html
<body _="on htmx:error(errorInfo) fetch /errors {method:'POST', body:{errorInfo:errorInfo} as JSON} ">
...
...
</body>
```
@ -1192,10 +1197,10 @@ A good example of this is the [SortableJS demo](/examples/sortable/):
```html
<form class="sortable" hx-post="/items" hx-trigger="end">
<div class="htmx-indicator">Updating...</div>
<div><input type='hidden' name='item' value='1'/>Item 1</div>
<div><input type='hidden' name='item' value='2'/>Item 2</div>
<div><input type='hidden' name='item' value='2'/>Item 3</div>
<div class="htmx-indicator">Updating...</div>
<div><input type='hidden' name='item' value='1'/>Item 1</div>
<div><input type='hidden' name='item' value='2'/>Item 2</div>
<div><input type='hidden' name='item' value='2'/>Item 3</div>
</form>
```
@ -1207,11 +1212,11 @@ In jquery you might do this like so:
$(document).ready(function() {
var sortables = document.body.querySelectorAll(".sortable");
for (var i = 0; i < sortables.length; i++) {
var sortable = sortables[i];
new Sortable(sortable, {
animation: 150,
ghostClass: 'blue-background-class'
});
var sortable = sortables[i];
new Sortable(sortable, {
animation: 150,
ghostClass: 'blue-background-class'
});
}
});
```
@ -1223,11 +1228,11 @@ rather than the entire document:
htmx.onLoad(function(content) {
var sortables = content.querySelectorAll(".sortable");
for (var i = 0; i < sortables.length; i++) {
var sortable = sortables[i];
new Sortable(sortable, {
animation: 150,
ghostClass: 'blue-background-class'
});
var sortable = sortables[i];
new Sortable(sortable, {
animation: 150,
ghostClass: 'blue-background-class'
});
}
})
```
@ -1240,9 +1245,9 @@ is initialized with the `htmx.process()` function.
For example, if you were to fetch some data and put it into a div using the `fetch` API, and that HTML had
htmx attributes in it, you would need to add a call to `htmx.process()` like this:
```ecmascript 6
let myDiv = document.getElementById('my-div')
fetch('http://example.com/movies.json')
```js
let myDiv = document.getElementById('my-div')
fetch('http://example.com/movies.json')
.then(response => response.text())
.then(data => { myDiv.innerHTML = data; htmx.process(myDiv); } );
```
@ -1253,19 +1258,19 @@ if they contain htmx attributes, will need a call to `htmx.process()` after they
example uses Alpine's `$watch` function to look for a change of value that would trigger conditional content:
```html
<div x-data="{show_new: false}"
x-init="$watch('show_new', value => {
if (show_new) {
htmx.process(document.querySelector('#new_content'))
}
})">
<div x-data="{show_new: false}"
x-init="$watch('show_new', value => {
if (show_new) {
htmx.process(document.querySelector('#new_content'))
}
})">
<button @click = "show_new = !show_new">Toggle New Content</button>
<template x-if="show_new">
<div id="new_content">
<a hx-get="/server/newstuff" href="#">New Clickable</a>
</div>
<div id="new_content">
<a hx-get="/server/newstuff" href="#">New Clickable</a>
</div>
</template>
</div>
</div>
```
## <a name="security"></a>[Security](#security)
@ -1287,9 +1292,9 @@ To address this, if you don't want a particular part of the DOM to allow for htm
This will prevent htmx from executing within that area in the DOM:
```html
<div hx-disable>
<div hx-disable>
<%= user_content %>
</div>
</div>
```
This approach allows you to enjoy the benefits of [Locality of Behavior](https://htmx.org/essays/locality-of-behaviour/)
@ -1329,7 +1334,7 @@ listed below:
You can set them directly in javascript, or you can use a `meta` tag:
```html
<meta name="htmx-config" content='{"defaultSwapStyle":"outerHTML"}'>
<meta name="htmx-config" content='{"defaultSwapStyle":"outerHTML"}'>
```
## Conclusion