hi folks.
I’ve been using django-htmx of late, and it’s a really, realy lovely package to add to working project, but I’ve bumped up against a problem I can’t seem to google the fix to, or solve through trial and error.
How do you send along GET params in a htmx request with django ?
I have an app I’m working on, which is designed to work like a sort of shared address book fo events and communities (you might use it at a conference, to help with networking for example), and a key part of the app is a filtered search view, that currently uses PostgresSQL’s full text search and tags to provide a nice way to filter a group of people by shared interests, or matching text in their profile.
I’m using django filter for this, and I’ve figured out how to get it to search through text, as well as a bunch of tags on a profile too. It looks a bit like this - any change to search text, or updating the chosen tags triggers a ‘submit’ event on the main filter form, sending along the GET params, and then storing them in the HTML history.
The hx-target=".sidebar"
bit tells htmx to update my sidebar with an updated list of profiles, a bit like how search works in an native address book on a mac, for example. The tags are visually hidden, but on a profile, the profiles tags for someone’s interests and skills are listed like clickable buttons, which updates the filtering on the site.
<form id="filter-form"
method="get"
hx-get="/"
hx-trigger="submit, htmx:confirm from:#id_tags, htmx:confirm from:#id_bio, toggle-tag from:body"
hx-target=".sidebar"
hx-push-url="true">
<p>
<label class="inline-block w-100 mr-8 text-xl"
for="{{ profile_filter.form.bio.id_for_label }}">Showing profile results matching:</label>
</p>
<p>
{% render_field profile_filter.form.bio hx-get="/" hx-trigger="keyup changed delay:0.2s," hx-target=".sidebar" class="text-xl min-w-[50%]" hx-sync="closest form:abort" %}
</p>
<p class="hidden">{% render_field profile_filter.form.tags %}</p>
<button class="btn mt-4 ml-4" type="submit">Search</button>
</form>
So, when the django filter is updated, you end up with a path like so (this shows a search filtered to full text for the word something, and add two tags
/?bio=something?tags=3&tags=6
You can see the home page showing this code at this link in the repo
In the sidebar
In the sidebar, I have a list of profiles, listing photos and names, and each profile is made to act like a button with some code like below (I’ve edited it for brevity):
<div class="hover:cursor-pointer"
hx-get="{% url 'profile-detail' profile.short_id %}"
hx-target="#profile-slot"
hx-push-url="true">
<!-- snip -->
</div>
You can also see the paginated list of profiles too if the context helps.
This request fetches profile information and loads it into the page (or more preciselty, loads the HTMX response into #profile-slot
div on the page.
You can see the full view code on github too, where we either serve a full page, or a smaller htmx response.
HTTP as the engine of state (I think)
I’m trying to use HTML as the engine of state, hence the reliance on GET params to represent the state of the search. So when a user clicks on a profile in the sidebar, I’d like to store the state of filtered search in the url. this would make it possible to easily share urls with a filtered view of a search and a detail view of a specific profile .
To make this concrete, I want to be able send a URL like this to the browse history, when a user clicks on a profile:
/profile/SOME_ID/?bio=something?tags=3&tags=6
This would return the info, but leave me with a nice, sharable URL.
With this in mind, I’m using hx-push-url
here too, which is adding /profile/SOME_ID/
to the URL history.
I can’t seem to add the GET params tto send along the state of the filtered search view though.
How can I dynamically add these to the URLs being sent as GET requests with htmx?
I’ve tried:
- hx-vals (which appears to be designed to let you send along other values in the URL), but nothing is sent.
- hx-include, which is also designed to add addiitonal values in a Ajax request, and finally
- hx-params, which is designed to filter the params send along (I looked at this in case the values were not being sent).
None of them seem to send along the GET params I want to send, so I’m now scratching my head on this one.
Elsewhere in the app, I’ve found a workaround from HTMX’s default to let me alter HTMX behaviour before, by using events, and having HTMX respond to them. This seems to be one recommended approach in many cases
The link below shows me dropping the use of HTMX to trigger HTMX events using vanilla javascript, by emitting events that HTMX listens for elsehwere, but what i’m doing doesn’t seem to be particularly exotic, so before I go down that route, I figured I should ask here.
Am I missing something really obvious here?
Thanks in advance.