3 ms·
The thing about HTMX is that the mental model about state should tend towards "the server is aware of everything". With the added benefit that you can achieve b
by polyrand 5y ago
The thing about HTMX is that the mental model about state should tend towards "the server is aware of everything". With the added benefit that you can achieve better RESTful URLs that respect the navigation actions. Without having tried this (but having used HTMX quite a lot), I would try the following (let me know if I didn't understand the problem correctly):
Checkout has the following URLs, one for each step:
* page.com/checkout (optionally with ?step=0)
* page.com/checkout?step=1
* page.com/checkout?step=2
* page.com/checkout?step=3
Now you need 2 things:
1) Making sure the server knows how to render all those pages independently (like if the user does a hard-refresh or if they open that URL directly, without navigating to it through a link). Note: I believe this should be the default in any website if you respect the concept of a URL (whether client or server-side rendered).
2) If there's a form input at each step, the server needs to store that info and be aware that the user has an incomplete checkout.
Now the user is at step=2 and presses the back button, or clicks on the step=1 link. In that case, the server should know the information stored in the point no. 2 above, and return an HTML form with the data pre-filled based on the last state. E.g:
<input type="text" id="name" name="name" value="Foobar">
I think there are 3 main keys:
1. You need different URLs for each step.
2. Each URL should work both with HTMX (maybe using hx-push-url or the HX-Push header) and *without*. That is, any navigation to that page should also render the same HTML.
3. The server needs to be aware of the state. When a user requests page.com/checkout?step=2, the server should know if the HTML form requires pre-filled values.
This increases a bit the complexity on the server, but I believe it reduces the client-side complexity a lot more.
- ledgerdev 5y ago> 2) If there's a form input at each step, the server needs to store that info and be aware that the user has an incomplete checkout. Now the user is at step=2 and presses the back button, or clicks on the step=1 link. In that case, the server should know the information stored in the point no. 2 above, and return an HTML form with the data pre-filled based on the last state. The problem is that when you press back button in the browser, it doesn't make another request to the server. It reloads the page from browser memory. A link back can be made to work, but that's not what I was speaking to. I tested the most trivial case, when you return a response, and push navigate to next step, then press browser back button, form state is not retained. Both chrome and firefox do not restore the form state on navigation back after a url push navigation. I don't think that without some client side JS that saves/reloads prior form state this is a solvable problem because of browser behavior. Either that, or perhaps use different divs for each step then have js hide/show them which is what I will try next but involves writing js to do so. EDIT: tried multiple divs on same page, same behavior so that will not work. It's pretty clear that htmx hasn't considered back button much at all, it also clobbers the page titles in history as well (https://github.com/bigskysoftware/htmx/issues/746 https://github.com/bigskysoftware/htmx/issues/746), but that's a fixable problem.
- polyrand 5y agoI see... What about using hx-trigger="load" for the form? Maybe that makes the browser reload it even after hitting the back button? (Sorry I can't check this right now, just a random idea). Edit: I quickly tried it (mixing hx-from="#some-other-element" and hx-trigger="revealed", and it seems to be doing the request, but I haven't looked a lot.
- ledgerdev 5y agoOk, so turns out default chrome/firefox on windows/android were not issuing the history refresh request on back button click. Turns out you need to add some additional config to make that happen. It's now working, and it's excellent. Set htmx to not cache prior pages by setting `htmx.config.historyCacheSize = 0` in window.onload. Also set the http caching header `cache-control: no-cache`