mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-09-27 04:50:43 +00:00
Dark mode fixes (#2634)
Co-authored-by: 1cg <469183+1cg@users.noreply.github.com>
This commit is contained in:
parent
5847fbf393
commit
f27e3495bd
@ -91,19 +91,19 @@ if(window.location.search=="?ads=true") {
|
||||
</div>
|
||||
|
||||
<div class="alert">
|
||||
<b>NEWS:</b> htmx 2.0 has been released! It is not currently marked as <a href="https://docs.npmjs.com/cli/v10/commands/npm-dist-tag#purpose"><code>latest</code></a>
|
||||
in NPM so that people using the <a href="https://v1.htmx.org">1.x line</a> are not accidentally upgraded. We will mark
|
||||
<b>NEWS:</b> htmx 2.0 has been released! It is not currently marked as <a href="https://docs.npmjs.com/cli/v10/commands/npm-dist-tag#purpose"><code>latest</code></a>
|
||||
in NPM so that people using the <a href="https://v1.htmx.org">1.x line</a> are not accidentally upgraded. We will mark
|
||||
2.0 as <code>latest</code> at some point in 2025.
|
||||
</div>
|
||||
|
||||
<h2>introduction</h2>
|
||||
|
||||
htmx gives you access to [AJAX](@/docs.md#ajax), [CSS Transitions](@/docs.md#css_transitions), [WebSockets](@/docs.md#websockets-and-sse) and [Server Sent Events](@/docs.md#websockets-and-sse)
|
||||
directly in HTML, using [attributes](@/reference.md#attributes), so you can build
|
||||
[modern user interfaces](@/examples/_index.md) with the [simplicity](https://en.wikipedia.org/wiki/HATEOAS) and
|
||||
htmx gives you access to [AJAX](@/docs.md#ajax), [CSS Transitions](@/docs.md#css_transitions), [WebSockets](@/docs.md#websockets-and-sse) and [Server Sent Events](@/docs.md#websockets-and-sse)
|
||||
directly in HTML, using [attributes](@/reference.md#attributes), so you can build
|
||||
[modern user interfaces](@/examples/_index.md) with the [simplicity](https://en.wikipedia.org/wiki/HATEOAS) and
|
||||
[power](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) of hypertext
|
||||
|
||||
htmx is small ([~14k min.gz'd](https://unpkg.com/htmx.org/dist/)),
|
||||
htmx is small ([~14k min.gz'd](https://unpkg.com/htmx.org/dist/)),
|
||||
[dependency-free](https://github.com/bigskysoftware/htmx/blob/master/package.json),
|
||||
[extendable](https://extensions.htmx.org) & has **reduced** code base sizes by [67% when compared with react](@/essays/a-real-world-react-to-htmx-port.md)
|
||||
|
||||
|
@ -134,6 +134,7 @@ class.
|
||||
}
|
||||
</style>
|
||||
<button id="fade-me-in"
|
||||
class="btn primary"
|
||||
hx-post="/fade_in_demo"
|
||||
hx-swap="outerHTML settle:1s">
|
||||
Fade Me In
|
||||
@ -153,6 +154,7 @@ class.
|
||||
</style>
|
||||
|
||||
<button id="fade-me-in"
|
||||
class="btn primary"
|
||||
hx-post="/fade_me_in"
|
||||
hx-swap="outerHTML settle:1s">
|
||||
Fade Me In
|
||||
@ -160,6 +162,7 @@ class.
|
||||
|
||||
<script>
|
||||
onPost("/fade_me_in", function () {return "<button id=\"fade-me-in\"\n"+
|
||||
" class=\"btn primary\"\n"+
|
||||
" hx-post=\"/fade_me_in\"\n"+
|
||||
" hx-swap=\"outerHTML settle:1s\">\n"+
|
||||
" Fade Me In\n"+
|
||||
@ -180,7 +183,7 @@ is a form that on submit will change its look to indicate that a request is bein
|
||||
</style>
|
||||
<form hx-post="/name" hx-swap="outerHTML">
|
||||
<label>Name:</label><input name="name"><br/>
|
||||
<button>Submit</button>
|
||||
<button class="btn primary">Submit</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
@ -196,7 +199,7 @@ is a form that on submit will change its look to indicate that a request is bein
|
||||
<div aria-live="polite">
|
||||
<form hx-post="/name" hx-swap="outerHTML">
|
||||
<label>Name:</label><input name="name"><br/>
|
||||
<button>Submit</button>
|
||||
<button class="btn primary">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -287,7 +290,7 @@ implement this feature in the near future.
|
||||
|
||||
<div class="slide-it">
|
||||
<h1>Initial Content</h1>
|
||||
<button hx-get="/new-content" hx-swap="innerHTML transition:true" hx-target="closest div">
|
||||
<button class="btn primary" hx-get="/new-content" hx-swap="innerHTML transition:true" hx-target="closest div">
|
||||
Swap It!
|
||||
</button>
|
||||
</div>
|
||||
@ -328,7 +331,7 @@ implement this feature in the near future.
|
||||
|
||||
<div class="slide-it">
|
||||
<h1>Initial Content</h1>
|
||||
<button hx-get="/new-content" hx-swap="innerHTML transition:true" hx-target="closest div">
|
||||
<button class="btn primary" hx-get="/new-content" hx-swap="innerHTML transition:true" hx-target="closest div">
|
||||
Swap It!
|
||||
</button>
|
||||
</div>
|
||||
@ -337,7 +340,7 @@ implement this feature in the near future.
|
||||
var originalContent = htmx.find(".slide-it").innerHTML;
|
||||
|
||||
this.server.respondWith("GET", "/new-content", function(xhr){
|
||||
xhr.respond(200, {}, "<h1>New Content</h1> <button hx-get='/original-content' hx-swap='innerHTML transition:true' hx-target='closest div'>Restore It! </button>")
|
||||
xhr.respond(200, {}, "<h1>New Content</h1> <button class='btn danger' hx-get='/original-content' hx-swap='innerHTML transition:true' hx-target='closest div'>Restore It! </button>")
|
||||
});
|
||||
|
||||
this.server.respondWith("GET", "/original-content", function(xhr){
|
||||
|
@ -29,7 +29,7 @@ values in the form submission (`POST` request):
|
||||
...
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="submit" value="Bulk Update">
|
||||
<input type="submit" value="Bulk Update" class="btn primary">
|
||||
<span id="toast"></span>
|
||||
</form>
|
||||
```
|
||||
@ -163,7 +163,7 @@ You can see a working example of this code below.
|
||||
${displayTable(contacts)}
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="submit" value="Bulk Update">
|
||||
<input type="submit" value="Bulk Update" class="btn primary">
|
||||
<span id="toast"></span>
|
||||
</form>
|
||||
<br>`;
|
||||
|
@ -12,7 +12,7 @@ The click to edit pattern provides a way to offer inline editing of all or part
|
||||
<div><label>First Name</label>: Joe</div>
|
||||
<div><label>Last Name</label>: Blow</div>
|
||||
<div><label>Email</label>: joe@blow.com</div>
|
||||
<button hx-get="/contact/1/edit" class="btn btn-primary">
|
||||
<button hx-get="/contact/1/edit" class="btn primary">
|
||||
Click To Edit
|
||||
</button>
|
||||
</div>
|
||||
@ -96,7 +96,7 @@ return `<form hx-put="/contact/1" 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 Address</label>: ${contact.email}</div>
|
||||
<button hx-get="/contact/1/edit" class="btn btn-primary">
|
||||
<button hx-get="/contact/1/edit" class="btn primary">
|
||||
Click To Edit
|
||||
</button>
|
||||
</div>`;
|
||||
|
@ -9,7 +9,7 @@ the final row:
|
||||
```html
|
||||
<tr id="replaceMe">
|
||||
<td colspan="3">
|
||||
<button class='btn' hx-get="/contacts/?page=2"
|
||||
<button class='btn primary' hx-get="/contacts/?page=2"
|
||||
hx-target="#replaceMe"
|
||||
hx-swap="outerHTML">
|
||||
Load More Agents... <img class="htmx-indicator" src="/img/bars.svg">
|
||||
@ -82,7 +82,7 @@ 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' hx-get="/contacts/?page=${page + 1}"
|
||||
<button class='btn primary' hx-get="/contacts/?page=${page + 1}"
|
||||
hx-target="#replaceMe"
|
||||
hx-swap="outerHTML">
|
||||
Load More Agents... <img class="htmx-indicator" src="/img/bars.svg">
|
||||
|
@ -47,7 +47,7 @@ row should be replaced with nothing.
|
||||
<td>angie@macdowell.org</td>
|
||||
<td>Active</td>
|
||||
<td>
|
||||
<button class="btn btn-danger" hx-delete="/contact/1">
|
||||
<button class="btn danger" hx-delete="/contact/1">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
@ -108,7 +108,7 @@ tr.htmx-swapping td {
|
||||
<td>${contact["email"]}</td>
|
||||
<td>${contact["status"]}</td>
|
||||
<td>
|
||||
<button class="btn btn-danger" hx-delete="/contact/${i}">
|
||||
<button class="btn danger" hx-delete="/contact/${i}">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
|
@ -7,7 +7,7 @@ Dialogs can be triggered with the [`hx-prompt`](@/attributes/hx-prompt.md) and [
|
||||
|
||||
```html
|
||||
<div>
|
||||
<button class="btn"
|
||||
<button class="btn primary"
|
||||
hx-post="/submit"
|
||||
hx-prompt="Enter a string"
|
||||
hx-confirm="Are you sure?"
|
||||
@ -45,7 +45,7 @@ User entered <i>${response}</i>
|
||||
// templates
|
||||
function submitButton() {
|
||||
return `<div>
|
||||
<button class="btn"
|
||||
<button class="btn primary"
|
||||
hx-post="/submit"
|
||||
hx-prompt="Enter a string"
|
||||
hx-confirm="Are you sure?"
|
||||
|
@ -30,7 +30,7 @@ Here is the HTML for a row:
|
||||
<td>${contact.name}</td>
|
||||
<td>${contact.email}</td>
|
||||
<td>
|
||||
<button class="btn btn-danger"
|
||||
<button class="btn danger"
|
||||
hx-get="/contact/${contact.id}/edit"
|
||||
hx-trigger="edit"
|
||||
onClick="let editing = document.querySelector('.editing')
|
||||
@ -74,10 +74,10 @@ Finally, here is what the row looks like when the data is being edited:
|
||||
<td><input name='name' value='${contact.name}'></td>
|
||||
<td><input name='email' value='${contact.email}'></td>
|
||||
<td>
|
||||
<button class="btn btn-danger" hx-get="/contact/${contact.id}">
|
||||
<button class="btn danger" hx-get="/contact/${contact.id}">
|
||||
Cancel
|
||||
</button>
|
||||
<button class="btn btn-danger" hx-put="/contact/${contact.id}" hx-include="closest tr">
|
||||
<button class="btn danger" hx-put="/contact/${contact.id}" hx-include="closest tr">
|
||||
Save
|
||||
</button>
|
||||
</td>
|
||||
@ -157,7 +157,7 @@ this makes things a bit nicer to deal with.
|
||||
<td>${contact.name}</td>
|
||||
<td>${contact.email}</td>
|
||||
<td>
|
||||
<button class="btn btn-danger"
|
||||
<button class="btn danger"
|
||||
hx-get="/contact/${contact.id}/edit"
|
||||
hx-trigger="edit"
|
||||
onClick="let editing = document.querySelector('.editing')
|
||||
@ -186,10 +186,10 @@ this makes things a bit nicer to deal with.
|
||||
<td><input name='name' value='${contact.name}'</td>
|
||||
<td><input name='email' value='${contact.email}'</td>
|
||||
<td>
|
||||
<button class="btn btn-danger" hx-get="/contact/${contact.id}">
|
||||
<button class="btn danger" hx-get="/contact/${contact.id}">
|
||||
Cancel
|
||||
</button>
|
||||
<button class="btn btn-danger" hx-put="/contact/${contact.id}" hx-include="closest tr">
|
||||
<button class="btn danger" hx-put="/contact/${contact.id}" hx-include="closest tr">
|
||||
Save
|
||||
</button>
|
||||
</td>
|
||||
|
@ -25,7 +25,7 @@ We start with this form:
|
||||
<label>Last Name</label>
|
||||
<input type="text" class="form-control" name="lastName">
|
||||
</div>
|
||||
<button class="btn btn-default">Submit</button>
|
||||
<button class="btn primary">Submit</button>
|
||||
</form>
|
||||
```
|
||||
Note that the first div in the form has set itself as the target of the request and specified the `outerHTML`
|
||||
@ -125,7 +125,7 @@ Below is a working demo of this example. The only email that will be accepted i
|
||||
<label for="lastName">Last Name</label>
|
||||
<input type="text" class="form-control" name="lastName" id="lastName">
|
||||
</div>
|
||||
<button type='submit' class="btn btn-default" disabled>Submit</button>
|
||||
<button type='submit' class="btn primary" disabled>Submit</button>
|
||||
</form>`;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ In this example we show how to create a keyboard shortcut for an action.
|
||||
We start with a simple button that loads some content from the server:
|
||||
|
||||
```html
|
||||
<button hx-trigger="click, keyup[altKey&&shiftKey&&key=='D'] from:body"
|
||||
<button class="btn primary" hx-trigger="click, keyup[altKey&&shiftKey&&key=='D'] from:body"
|
||||
hx-post="/doit">Do It! (alt-shift-D)</button>
|
||||
```
|
||||
|
||||
@ -32,10 +32,10 @@ You can find out the conditions needed for a given keyboard shortcut here:
|
||||
|
||||
// routes
|
||||
init("/init", function(request, params){
|
||||
return "<button style='font-size:20pt' hx-trigger='click, keyup[altKey&&shiftKey&&key==\"D\"] from:body'" +
|
||||
return "<button class='btn primary' style='font-size:20pt' hx-trigger='click, keyup[altKey&&shiftKey&&key==\"D\"] from:body'" +
|
||||
" hx-post='/doit'>Do It! (alt-shift-D) </button>";
|
||||
});
|
||||
|
||||
|
||||
onPost("/doit", function (request, params) {
|
||||
return "Did it!";
|
||||
});
|
||||
|
@ -3,20 +3,20 @@ title = "Modal Dialogs in Bootstrap"
|
||||
template = "demo.html"
|
||||
+++
|
||||
|
||||
Many CSS toolkits include styles (and Javascript) for creating modal dialog boxes.
|
||||
Many CSS toolkits include styles (and Javascript) for creating modal dialog boxes.
|
||||
This example shows how to use HTMX alongside original JavaScript provided by Bootstrap.
|
||||
|
||||
We start with a button that triggers the dialog, along with a DIV at the bottom of your
|
||||
We start with a button that triggers the dialog, along with a DIV at the bottom of your
|
||||
markup where the dialog will be loaded:
|
||||
|
||||
```html
|
||||
<button
|
||||
hx-get="/modal"
|
||||
hx-target="#modals-here"
|
||||
hx-trigger="click"
|
||||
data-bs-toggle="modal"
|
||||
<button
|
||||
hx-get="/modal"
|
||||
hx-target="#modals-here"
|
||||
hx-trigger="click"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#modals-here"
|
||||
class="btn btn-primary">Open Modal</button>
|
||||
class="btn primary">Open Modal</button>
|
||||
|
||||
<div id="modals-here"
|
||||
class="modal modal-blur fade"
|
||||
@ -74,15 +74,15 @@ tabindex="-1">
|
||||
|
||||
// routes
|
||||
init("/demo", function(request, params) {
|
||||
return `<button
|
||||
hx-get="/modal"
|
||||
hx-target="#modals-here"
|
||||
return `<button
|
||||
hx-get="/modal"
|
||||
hx-target="#modals-here"
|
||||
hx-trigger="click"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#modals-here"
|
||||
class="btn btn-primary">Open Modal</button>
|
||||
class="btn primary">Open Modal</button>
|
||||
`})
|
||||
|
||||
|
||||
onGet("/modal", function(request, params){
|
||||
return `<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
|
@ -3,19 +3,19 @@ title = "Custom Modal Dialogs"
|
||||
template = "demo.html"
|
||||
+++
|
||||
|
||||
While htmx works great with dialogs built into CSS frameworks (like [Bootstrap](@/examples/modal-bootstrap.md) and [UIKit](@/examples/modal-uikit.md)), htmx also makes
|
||||
While htmx works great with dialogs built into CSS frameworks (like [Bootstrap](@/examples/modal-bootstrap.md) and [UIKit](@/examples/modal-uikit.md)), htmx also makes
|
||||
it easy to build modal dialogs from scratch. Here is a quick example of one way to build them.
|
||||
|
||||
Click here to see a demo of the final result:
|
||||
|
||||
<button hx-get="/modal" hx-target="body" hx-swap="beforeend">Open a Modal</button>
|
||||
<button class="btn primary" hx-get="/modal" hx-target="body" hx-swap="beforeend">Open a Modal</button>
|
||||
|
||||
## High Level Plan
|
||||
|
||||
We're going to make a button that loads remote content from the server, then displays it in a modal dialog. The modal
|
||||
content will be added to the end of the `<body>` element, in a div named `#modal`.
|
||||
We're going to make a button that loads remote content from the server, then displays it in a modal dialog. The modal
|
||||
content will be added to the end of the `<body>` element, in a div named `#modal`.
|
||||
|
||||
In this demo we'll define some nice animations in CSS, and then use some [Hyperscript](https://hyperscript.org) to remove the
|
||||
In this demo we'll define some nice animations in CSS, and then use some [Hyperscript](https://hyperscript.org) to remove the
|
||||
modals from the DOM when the user is done. Hyperscript is *not* required with htmx, but the two were designed to be used
|
||||
together and it is much nicer for writing async & event oriented code than JavaScript, which is why we chose it for this
|
||||
example.
|
||||
@ -23,7 +23,7 @@ example.
|
||||
## Main Page HTML
|
||||
|
||||
```html
|
||||
<button hx-get="/modal" hx-target="body" hx-swap="beforeend">Open a Modal</button>
|
||||
<button class="btn primary" hx-get="/modal" hx-target="body" hx-swap="beforeend">Open a Modal</button>
|
||||
```
|
||||
|
||||
## Modal HTML Fragment
|
||||
@ -36,7 +36,7 @@ example.
|
||||
You can put anything here, like text, or a form, or an image.
|
||||
<br>
|
||||
<br>
|
||||
<button _="on click trigger closeModal">Close</button>
|
||||
<button class="btn danger" _="on click trigger closeModal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
@ -114,28 +114,28 @@ example.
|
||||
@keyframes fadeIn {
|
||||
0% {opacity: 0;}
|
||||
100% {opacity: 1;}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeOut {
|
||||
0% {opacity: 1;}
|
||||
100% {opacity: 0;}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zoomIn {
|
||||
0% {transform: scale(0.9);}
|
||||
100% {transform: scale(1);}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zoomOut {
|
||||
0% {transform: scale(1);}
|
||||
100% {transform: scale(0.9);}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<script src="https://unpkg.com/htmx.org"></script>
|
||||
<script src="https://unpkg.com/hyperscript.org"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// Fake Server Side Code
|
||||
//=========================================================================
|
||||
@ -151,7 +151,7 @@ example.
|
||||
You can put anything here, like text, or a form, or an image.
|
||||
<br>
|
||||
<br>
|
||||
<button _="on click trigger closeModal">Close</button>
|
||||
<button class="btn danger" _="on click trigger closeModal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
@ -231,17 +231,17 @@ example.
|
||||
@keyframes fadeIn {
|
||||
0% {opacity: 0;}
|
||||
100% {opacity: 1;}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeOut {
|
||||
0% {opacity: 1;}
|
||||
100% {opacity: 0;}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zoomIn {
|
||||
0% {transform: scale(0.9);}
|
||||
100% {transform: scale(1);}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zoomOut {
|
||||
0% {transform: scale(1);}
|
||||
|
@ -10,7 +10,7 @@ We start with an initial state with a button that issues a `POST` to `/start` to
|
||||
```html
|
||||
<div hx-target="this" hx-swap="outerHTML">
|
||||
<h3>Start Progress</h3>
|
||||
<button class="btn" hx-post="/start">
|
||||
<button class="btn primary" hx-post="/start">
|
||||
Start Job
|
||||
</button>
|
||||
</div>
|
||||
@ -58,7 +58,7 @@ with a restart button added to the UI (we are using the [`class-tools`](https://
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="restart-btn" class="btn" hx-post="/start" classes="add show:600ms">
|
||||
<button id="restart-btn" class="btn primary" hx-post="/start" classes="add show:600ms">
|
||||
Restart Job
|
||||
</button>
|
||||
</div>
|
||||
@ -160,7 +160,7 @@ This example uses styling cribbed from the bootstrap progress bar:
|
||||
function startButton(message) {
|
||||
return `<div hx-target="this" hx-swap="outerHTML">
|
||||
<h3>${message}</h3>
|
||||
<button class="btn" hx-post="/start">
|
||||
<button class="btn primary" hx-post="/start">
|
||||
Start Job
|
||||
</button>
|
||||
</div>`;
|
||||
@ -190,7 +190,7 @@ This example uses styling cribbed from the bootstrap progress bar:
|
||||
function restartButton(job) {
|
||||
if(job.complete){
|
||||
return `
|
||||
<button id="restart-btn" class="btn" hx-post="/start" classes="add show:600ms">
|
||||
<button id="restart-btn" class="btn primary" hx-post="/start" classes="add show:600ms">
|
||||
Restart Job
|
||||
</button>`
|
||||
} else {
|
||||
|
@ -111,16 +111,15 @@ Subsequent tab pages display all tabs and highlight the selected one accordingly
|
||||
display:none;
|
||||
}
|
||||
|
||||
#tabs > .tab-list {
|
||||
border-bottom: solid 3px #eee;
|
||||
}
|
||||
|
||||
#tabs > .tab-list button {
|
||||
border: none;
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
cursor:pointer;
|
||||
background-color: transparent;
|
||||
color: var(--textColor);
|
||||
border: solid 3px rgba(0,0,0,0);
|
||||
border-bottom: solid 3px #eee;
|
||||
}
|
||||
|
||||
#tabs > .tab-list button:hover {
|
||||
@ -128,7 +127,7 @@ Subsequent tab pages display all tabs and highlight the selected one accordingly
|
||||
}
|
||||
|
||||
#tabs > .tab-list button.selected {
|
||||
background-color: #eee;
|
||||
border: solid 3px var(--midBlue);
|
||||
}
|
||||
|
||||
#tabs > .tab-content {
|
||||
|
@ -3,16 +3,16 @@ title = "Tabs (Using JavaScript)"
|
||||
template = "demo.html"
|
||||
+++
|
||||
|
||||
This example shows how to load tab contents using htmx, and to select the "active" tab using Javascript. This reduces
|
||||
some duplication by offloading some of the work of re-rendering the tab HTML from your application server to your
|
||||
This example shows how to load tab contents using htmx, and to select the "active" tab using Javascript. This reduces
|
||||
some duplication by offloading some of the work of re-rendering the tab HTML from your application server to your
|
||||
clients' browsers.
|
||||
|
||||
You may also consider [a more idiomatic approach](@/examples/tabs-hateoas.md) that follows the principle of [Hypertext As The Engine Of Application State](https://en.wikipedia.org/wiki/HATEOAS).
|
||||
|
||||
## Example Code
|
||||
|
||||
The HTML below displays a list of tabs, with added HTMX to dynamically load each tab pane from the server. A simple
|
||||
JavaScript event handler uses the [`take` function](https://hyperscript.org/commands/take/) to switch the selected tab
|
||||
The HTML below displays a list of tabs, with added HTMX to dynamically load each tab pane from the server. A simple
|
||||
JavaScript event handler uses the [`take` function](https://hyperscript.org/commands/take/) to switch the selected tab
|
||||
when the content is swapped into the DOM.
|
||||
|
||||
```html
|
||||
@ -34,7 +34,7 @@ when the content is swapped into the DOM.
|
||||
|
||||
{{ demoenv() }}
|
||||
|
||||
<div id="tabs" hx-target="#tab-contents" role="tablist"
|
||||
<div id="tabs" hx-target="#tab-contents" role="tablist"
|
||||
hx-on:htmx-after-on-load="console.log(event)
|
||||
let currentTab = document.querySelector('[aria-selected=true]');
|
||||
currentTab.setAttribute('aria-selected', 'false')
|
||||
@ -89,7 +89,6 @@ when the content is swapped into the DOM.
|
||||
}
|
||||
|
||||
#tabs {
|
||||
border-bottom: solid 3px #eee;
|
||||
}
|
||||
|
||||
#tabs > button {
|
||||
@ -98,6 +97,8 @@ when the content is swapped into the DOM.
|
||||
padding: 5px 10px;
|
||||
cursor:pointer;
|
||||
background-color: transparent;
|
||||
border: solid 3px rgba(0,0,0,0);
|
||||
border-bottom: solid 3px #eee;
|
||||
}
|
||||
|
||||
#tabs > button:hover {
|
||||
@ -105,7 +106,7 @@ when the content is swapped into the DOM.
|
||||
}
|
||||
|
||||
#tabs > button.selected {
|
||||
background-color: #eee;
|
||||
border: solid 3px var(--midBlue);
|
||||
}
|
||||
|
||||
#tab-contents {
|
||||
|
@ -35,6 +35,11 @@
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
#demo-server-info {
|
||||
background-color: var(--footerBackground);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function toggleRequestInfo() {
|
||||
|
@ -345,6 +345,12 @@ a[href]:hover, .btn:hover {
|
||||
border: solid var(--midBlue);
|
||||
}
|
||||
|
||||
.btn.danger {
|
||||
color: white;
|
||||
background: #d9534f;
|
||||
border: solid #d9534f;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.2em 0.2em 0.2em 0;
|
||||
text-align: left;
|
||||
|
Loading…
x
Reference in New Issue
Block a user