Comments (16)
@CapnKernel Follow this great tutorial with Toasts and Django https://blog.benoitblanchon.fr/django-htmx-toasts/
from django-htmx.
I did that in my code. First I added a HtmxResponseMixin and included that line into the dispatch method:
if messages.get_messages(request):
response.headers["HX-Trigger"] = "messagesAvailable" # or another name...
But this should be generic available, not only in some HTMX views. So I decided to put that into a middleware. But the only purpose for that middleware is adding that trigger - which is a bit overkill.
I second the idea to add this line in django-htmx' middleware, as it is a general purpose solution (if the messages framework is used in your project).
The problem with the oob solution is definitively: you can swap messages into a tag by hx-swap-oob
, but this only works as you don't use e.g. bootstrap toasts, they are hidden by default, and just shown by using Js in the frontend. Having a trigger in the header you can rely on when using HTMX calls makes everything a bit easier, and more django-ish
// e.g. in base.html / script tag
const messagesToastElement = document.getElementById("messages-toast")
const messagesToast = new bootstrap.Toast(messagesToastElement, { delay: 2000 })
htmx.on("messagesAvailable", () => {
messagesToast.show()
})
You don't have to use the Hx-Trigger
, but if it's there, it's a big help.
from django-htmx.
I'm not sure we'd want the library to insert messages into every response though
What I suggested was not to include the messages, but just send an event if messages were available. The client may or may not have a handler for that event, and that's ok. That way, messages stay stored until they're consumed (either by a full page load or an htmx request).
from django-htmx.
Btw toast messages are pretty tricky accessibility-wise, for example see this post that summarizes how to meet a11y criteria when using them. They suggest a minimum delay of 6 seconds, based on message length. Personally I've decided to stick to messages the user has to deliberately close, or navigate away from, rather than using a timer.
from django-htmx.
This idea was discussed on the django-htmx channel of the htmx discord server, and one user (@gone) wrote this:
So the way I do messages is with a middleware:
https://github.com/gone/animelister/blob/master/animelister/util/middleware.pyand then I generate the slot for it in the base template
https://github.com/gone/animelister/blob/master/animelister/templates/base.html#L31
and then the messages themselves are a partial
https://github.com/gone/animelister/blob/master/animelister/templates/messages.html
because the messages are tagged with oob, they're inserted directly into the messages div
regardless of what other kind of content is coming throughI just jam a bunch of them on the end of the html fragment
It seems that oob can be used to piggy-back certain content onto other responses (but as I said, htmx newb here)
https://htmx.org/attributes/hx-swap-oob/
https://htmx.org/examples/update-other-content/
from django-htmx.
@CapnKernel have you managed to make it work with gone's solution?
from django-htmx.
gone's solution with hx-swap-oob seems like a generally useful. But I'm not sure we'd want the library to insert messages into every response though - it won't work if you only use htmx on some parts of your site (I doubt most users . It really depends on how you use htmx.
from django-htmx.
It works well, yeah. The only case it doesn't handle is a boosted link will clear out messages on the page already vs keeping them and merging potential new ones.
from django-htmx.
@CapnKernel have you managed to make it work with gone's solution?
I haven't tried yet. My coding hasn't started, and this will be my first htmx-using project. Messages was one of two questions I had about practical use of htmx (the other being auto-complete fields such as select2)
from django-htmx.
That approach sounds like one line of code, not worth adding to the package. Have you tried it?
from django-htmx.
I didn't submit this myself because I didn't feel like this was a one-size-fits-all case.
Would you be open to a PR expanding the documentation to have a "common problem/setup tasks" section that could show this + and setting up a CSRF token?
from django-htmx.
Yes it would be nice to expand the documentation. I'd like to set it up with Sphinx so there can be clear sections and nicer styling (using Furo).
from django-htmx.
any solution for this?
from django-htmx.
I'd rather not set up the middleware to always inject the header. It will add response overhead for apps that don't use it. As you point out, it's two lines of code - I wouldn't say it's "overkill" to write your own middleware for that, middleware classes are cheap :)
I am leaning towards only writing a section in the "tips" page on messages. I think we could document the two techniques: a middlweare to trigger an event (using django_htmx.http.trigger_client_event()
) with on-page handler, and OOB.
from django-htmx.
@adamchainz definitely. Usability-wise there are differences we (in medical software) suffer all the time, because most of that software is Bad™. Lots of alert fatique. Therefore you need >=3 kinds of messages:
- Non-disturbing ("successfully saved file") - this does not need a closing X and can be auto-closing after 6s.
- Important ones that should be noticed. ("Error: there is no file to save to." e.g.). MUST be closed manually.
- Blockers. Users can't get further without clicking on a button.
Many of the messages in medical (EMR) software are 3, but should be 2 or even 1.
If you use messages without toasts, just in a <div>
, they use space, and if you click them away, the content below jumps up, which is very unconvenient IMHO. But if you make the div floating, we arrived at toasts again...
What has that to do with Django/HTMX? There should be a possibility to implement 1.-3. with HTMX.
And what I didn't know, is that Middlewares are cheap. Easy to built, yes, but I (until now) tried to avoid having too much different middlewares, as they are called at each request and seemed to add an unnecessary overhead to the processing.
But if you assure that that's not the case, I'm perfectly fine with adding that line into my own middleware (as I did ATM).
+1 for adding some docs for both methods. Both have dis/advantages. OOB urges you to add the OOB div with queued messages to EACH request (so you need another middleware to inject that? Or a mixin/helper for your view? Or a htmx.html
base template you extend each and every template that is sent via HTMX over the wire?
all these approaches sound weird to me, tried them all a bit, won't do them again.
I would suggest to add messages using a header/Hx-Trigger with a custom event and show them using htmx.on()
in the frontend. You can decide then if you want toasts or other divs anyway.
This also should cover async responses (be it channels or the upcoming Django async features?) when pushed events from the server include that messages.
@bblanchon told me he'd work on such a middleware ATM - I'm keen to see that soon.
from django-htmx.
That works perfectly. IMHO there is no need to implement that in django-htmx, as it's one level upwards.
from django-htmx.
Related Issues (20)
- I am working on a awesome-python-htmx, seeking your feedback HOT 2
- @htmx_only decorator HOT 3
- Add a section for testing in the docs HOT 4
- Script tag generated by `django_htmx_script` shouldn't contain `type="text/javascript"` HOT 2
- Add reselect http method HOT 1
- The hx-headers="{'X-CSRFToken': '{{ csrf_token }}'}" Not Working, Forbidden (CSRF token missing.): HOT 3
- Relative Path Shortcut HOT 3
- Load script via htmx and execute HOT 1
- variation on django_htmx_script - load error into target, instead of replacing whole page HOT 1
- HX-Reselect response header not implemeted HOT 1
- The middleware doesn't work properly in asgi mode HOT 2
- Support more than just "true" as value for boolean request headers HOT 2
- Template tag? HOT 1
- Redirect after login HOT 4
- example app doesn't run HOT 1
- Add support for hx-replace-url HOT 2
- hx-put, hx-delete HOT 1
- Detection of partial htmx request in the presence of hx-history HOT 7
- MyPy error with "show" argument to reswap: incompatible type "str" HOT 3
- Request: Add short description to the readme or documentation that explains why to use this package. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-htmx.