This post is part of a series comparing different ways to implement asynchronous requests on the client to augment the latter. So far, I described the process with Vue.js and Alpine.js. Both are similar from the developers' point of view: they involve JavaScript.
\ In this post, I'll focus on HTMX, whose approach is quite different.
Laying out the workI'll follow the same structure as in the previous posts of the series. Here's the setup, server- and client-side.
Server-sideHere is how I integrate Thymeleaf and HTMX in the POM:
\
The code on the HTML side is straightforward:
\
We want to implement the same features as previously.
\ HTMX implements a radical approach that is different from traditional AJAX frameworks. They force you to develop an HTTP API that accepts and returns JSON. With HTMX, you return HTML fragments instead. HTMX uses it to replace the DOM elements that you configured. Hence, you need to write neither JavaScript nor deal with JSON and serialization of entities.
Designing the fragmentsHTMX nicely complements Thymeleaf because both work with page fragments. We can align Thymeleaf's fragments to HTMX's responses. It requires thinking ahead, which differs from the previous AJAX/API/JSON standard, but it's worth it.
\ Let's list interactions and what fragment we replace for each of them:
\
Here's the conceptual fragments design for our app:
\
-------------------- APP -------------------- | index.html | | | | ---------------- TABLE ---------------- | | | table.html | | | | | | | | ------------- LINES ------------- | | | | | lines.html | | | | | | | | | | | --------------------------------- | | | --------------------------------------- | ---------------------------------------------\ I'll split the HTML page into these fragments. Because we render them via Thymeleaf, we can split each into their dedicated file for a cleaner separation. At initial load time, we use Thymeleaf's replace directive; we use HTMX for asynchronous client-side interactions.
Our first interactionWe will start with the cleanup feature, as it's the easiest one with HTMX.
\ Here's the HTML code:
\
...\ Note that there's no explicit JavaScript involved, not a single line of code. HTMX takes care of it.
On the server side, the code is the following:
\
fun htmx(todos: MutableList\ That's the heart of HTMX: bind an HTTP call to a client-side event, and replace the configured DOM element with the server response.
Adding a new todo follows the same principle, but the DOM element is the whole table to reset the label value. If interested in the complete, look at the code.
Marking a todo completeWhile I mentioned that we will not return anything from the check request, it presents an exciting challenge. That's the reason why I am only addressing it now.
\ We have two challenges when clicking on the checkbox:
\
\ HTMX offers the hx-vals for the JSON payload. However, the URL is different for each row as we want to include the ID in the path. We must generate it server-side with Thymeleaf. TIL: Thymeleaf can manage any HTML attribute prefixed with th:: it will process the value as usual and write the attribute's name unprefixed.
\
hx-trigger="click" th:hx-patch="'/htmx/todo/' + ${todo.id}" hx-vals='js:{"checked": event.target.checked}' />\ Note that, as explained above, I ignored the response. In a real-world scenario, you should check/uncheck the checkbox depending on the value returned to avoid keeping the server state and the UI in synch.
ConclusionIn the two previous posts, I described Vue and Alpine. We configured Spring Boot to return JSON. With HTMX, we configured it to return HTML. Additionally, we didn't need any JavaScript code to send the requests from the client.
\ Icing on the cake, there's a great synergy between Thymeleaf and HTMX: we can split the page into fragments and reuse them on both sides.
\ The complete source code for this post can be found on GitHub:
https://github.com/ajavageek/compare-frontends?embedable=true
\ To go further:
\
\
All Rights Reserved. Copyright , Central Coast Communications, Inc.