Search code examples
djangohtmx

How htmx can access data from an event?


I have a view

def tag_delete(request):
    if request.method == 'POST':
        tag_name = request.POST.get("tag")
        tag = Tag.objects.get(name=tag_name)
        tag.delete()

        response = HttpResponse(status=204, headers={'HX-Trigger': json.dumps({
                "taglistchangeddelete": {"tag": tag_name}
            })})
                  
        return response

When the user clicks a button to delete a tag, this view is called. This view works fine. But the problem start because i have a session variable that contains a list of selected tags. If the tag that has been deleted is in this list, it should be removed from there. So, I created another view to handle this deletion:

def process_tags_deleted(request, tag):   

    selected_tags = request.session['selected_tags']    
    if tag in selected_tags:
        selected_tags.remove(tag)

    request.session['selected_tags'] = selected_tags
    
    #The rendered template will show the user their selected tags 
    response = render(request, 'espace/tags_selected.html', {
             'selected_tags': selected_tags,
          })  

    return response

To call the process_tag_deleted function, I created an HTMX get request within a random div in the template:

<div hx-get={% url 'process_tags_deleted' %}
         hx-vals='{"tag": evt.detail.tag}'
         hx-target="#tags_selected"
         hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
         hx-trigger="taglistchangeddelete">
    </div>

I'm pretty sure that the problem lies in the hx-vals. I can't retrieve the 'tag' value that comes from the event "taglistchangeddelete". It gives a syntax HTMX error in the console:

htmx:syntax:error
b @ htmx.min.js:1
function b(e) {
      if (console.error) {
        console.error(e) #ERROR
      } else if (console.log) {
        console.log("ERROR: ", e)
      }
    }

What does this error mean? And how to handle my task? Thanks a lot!!!


Solution

  • Restructure the HttpResponse in tag_delete:

    def tag_delete(request):
        ... 
        response = HttpResponse(status=204)
        response["Hx-Trigger"] = json.dumps({"taglistchangeddelete": tag_name})
        return response
    
    

    Then to access the response:

    <div hx-get="{% url 'process_tags_deleted' %}" 
         hx-vals='js:{"tag": event.detail.value}'
         hx-target="#tags_selected"
         hx-trigger="taglistchangeddelete from:body">
    </div>
    

    Note

    GET requests don't need csrf_token.