'HTMX, Django - update part of page
I've started with HTMX and I want to use it to refresh part o page after pressing button on pop-up page. The button is adding clicking user as participant in an event. I going true tutorials and example which mostly present cases with forms and I don't know how to approach this update with it.
I'm pretty sure I should use hx-ws, but it is just completely unclear for me how.
chall-interface.html (here is a part which I want to update)
{% load static %}
{% load tagz %}
<div id='chall-interface' class="card-bottom mb-2">
<button onclick="call('challFollows',{'id':'{{chall.id}}'}, this)" class='icon icon-s rounded-sm float-end background-transparent mb-2 me-1 color-white'><i class="font-12 fa fa-heart {% followedChall user chall %}"></i></button>
<button href="#" data-menu="comment-section" class="icon icon-s rounded-sm float-end background-transparent mx-1 mb-2">
<i class="font-12 fa fa-comments color-white"></i>
</button>
{% if chall.dealine_is_over %}
<button href="#" data-menu="rules" class="icon icon-s rounded-sm float-end background-transparent mx-1 mb-2">
<i class="font-12 fa color-white {% changeJoinButton user chall %}""></i>
</button>
<!-- Here is a code I'm asking about -->
{% if user == userParticipationStatus.user %}
<a href="/addResponse/{{chall.id}}" class="icon icon-s rounded-sm float-end background-transparent mx-1 mb-2">
<i class="font-12 fa fa-plus-square color-white"></i>
</a>
{% else %}
{% endif %}
<!-- Here is a code I'm asking about -->
{% if chall.user == user %}
<button class="icon icon-s rounded-sm float-end background-transparent mx-1 mb-2">
<i class="font-12 fa fa-pen color-white"></i>
</button>
{% else %}
{% endif %}
{% else %}
{% endif %}
<div class="card-bottom mb-1 w-25">
{% if chall.profile.id == None %}
<a href='#'><img src="{% static 'images/avatars/5s.png' %}" class="float-start border border-white bg-yellow-light rounded-circle ms-3" width="35"></a>
{% elif chall.user == user %}
<a href='/profile/'><img src="{% static 'images/avatars/5s.png' %}" class="float-start border border-white bg-yellow-light rounded-circle ms-3" width="35"></a>
{% else %}
<a href='/userProfile/{{chall.profile.id}}'><img src="{% static 'images/avatars/5s.png' %}" class="float-start border border-white bg-yellow-light rounded-circle ms-3" width="35"></a>
{% endif %}
<span class="float-start mx-3"><i>{{chall.profile.nickname}}</i></span>
</div>
</div>
It is added as {% include "include/chall-interface.html" %} in main html file from which a pop-up is activated
Here is a pop-up
{% load tagz %}
<div id="rules" class="menu menu-box-modal rounded-m" data-menu-width="350">
<div class="card card-style" style="margin: 0px !important">
<div class="content">
<strong class="font-12 mx-1">Rules</strong>
<span class="color-theme font-14 d-block mx-1">{{chall.rules}}</span>
<!-- This is the button -->
<button onclick="call('challParticipates',{'id':'{{chall.id}}'}, this)" class="close-menu btn btn-m float-end rounded-xl shadow-xl text-uppercase font-800 bg-highlight mx-1 my-2"><i>{% changeJoinButton2 user chall %}</i></button>
<!-- This is the button -->
<button data-bs-dismiss="modal" class="close-menu btn btn-m float-end rounded-xl shadow-xl text-uppercase font-800 bg-highlight mx-1 my-2"><i>Exit</i></button>
</div>
</div>
</div>
Here is a call function activated by the button:
function call(url, info, element) {
eventStatus = false
fetch("/"+url+"/", {
method: 'POST',
headers: {'X-CSRFToken': getCookie('csrftoken')},
body: JSON.stringify(info)
}).then(response => response.text())
.then(responseData => {
dataParsed = JSON.parse(responseData);
console.log(dataParsed)
if (dataParsed.eventStatus) {
element.firstElementChild.classList.add("color-gold");
element.firstElementChild.classList.remove("color-white");
}
else {
element.firstElementChild.classList.remove("color-gold");
element.firstElementChild.classList.add("color-white");
}
})
.catch(err => {
// if any error occured, then catch it here
console.error(err);
});
}
View.py
class ChallView(LoginRequiredMixin, TemplateView):
login_url = '/chalth/login'
redirect_field_name = ''
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
chall = Chall.objects.get(id=kwargs.get("id"))
context['chall'] = chall
currentUser = self.request.user
context['userParticipationStatus'] = Participates.objects.filter(user = currentUser, chall = chall).first()
return context
@login_required(login_url = '/chalth/login')
def ChallParticipatesView(request):
data = json.loads(request.body)
id = data.get("id", False)
if id:
challParticipate = Participates.objects.filter(chall_id=id, user=request.user).first()
eventStatus = False
if challParticipate:
challParticipate.delete()
eventStatus = False
else:
challParticipate=Participates()
chall = Chall.objects.get(id=id)
eventStatus = True
if chall:
challParticipate.chall = chall
challParticipate.user = request.user
challParticipate.save()
else:
return HttpResponse(status = 400)
else:
return HttpResponse(status = 400)
return HttpResponse(json.dumps({"eventStatus": eventStatus, "id": id}), status = 200)
Solution 1:[1]
As far as I can understand from your code, I can't see htmx
in action.
I suggest you first try using the inline way, for example:
<button hx-post="/clicked"
hx-trigger="click"
hx-target="#parent-div"
hx-swap="outerHTML"
>
Click Me!
</button>
to see if your problem is about:
- the server that doesn't return valid HTML
- the server that returns an error (that will stop the swap)
- the wrong usage of
htmx
APIs
Also make sure to know what the properties:
hx-trigger
hx-target
hx-swap
do.
I hope I have helped ?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Luca Fedrizzi |