djangohtmx

HTMX tags not activating when using locally-stored copy of source code in Django project


I have a Django project where I'm using HTMX to set up "cascading" SELECT widgets (i.e. the options listed in SELECT #2 are modified based on the user option from SELECT #1). I've confirmed that the HTMX tags in SELECT #1 are triggering as expected when I put this line in the HTML template header to pull in the HTMX code from their web site:

<script src="https://unpkg.com/htmx.org@1.9.2" integrity="sha384-L6OqL9pRWyyFU3+/bjdSri+iIphTN/bvYyM37tICVyOJkWZLpP2vGn6VUEXgzg6h" crossorigin="anonymous"></script>

Specifically, I can confirm the event is triggering because at this point the corresponding view for the target (create_itemid_2) is just a stub, and I see the printed message in my Powershell console.

def create_itemid_2(request):
    print('HTMX event fired')
    context = {}
    return render(request,'create_itemid_2.html',context)

So now I want to pull down the code, and use it locally in my Django project, so I'm not dependent on the external resource. The problem is, after I've done that, the event never triggers. I can even see the js file being successfully retrieved in my console (HTTP status 200, then 304 after that), but still the event never triggers.

[14/Jun/2023 08:05:05] "GET /newitemid/ HTTP/1.1" 200 1652
[14/Jun/2023 08:05:05] "GET /static/htmx/htmx.min.js HTTP/1.1" 200 361101
[14/Jun/2023 08:09:50] "GET / HTTP/1.1" 200 515
[14/Jun/2023 08:09:52] "GET /newitemid/ HTTP/1.1" 200 1652
[14/Jun/2023 08:09:52] "GET /static/htmx/htmx.min.js HTTP/1.1" 304 0
[14/Jun/2023 08:10:10] "GET / HTTP/1.1" 200 515

Here are the steps I took to bring in that local copy and get it set up:

First, I downloaded the source file and copied it into the project path /static/htmx/htmx.min.js.

Then I added these lines to settings.py:

STATIC_ROOT = BASE_DIR
STATIC_URL = '/static/'
STATICFILES_DIRS = ('static',)

Then in my virtual environment I ran the command python manage.py collectstatic. And finally, I removed the <script>foo</script> line from the header block of my HTML template, replacing it with:

{% load static %}
<script src="{% static '/htmx/htmx.min.js' %}"></script>

In case it matters or helps, I'm attaching the complete templates below. But the key question is this: The triggers activate when I access the js file remotely with the HTTP call. But they do not activate when I access the js file locally from the project. Why not? What am I missing?

<!-- templates/create_itemid.html -->
{% extends "base.html" %}
{% block head %}
{% load static %}
<script src="{% static '/htmx/htmx.min.js' %}"></script>
{% endblock %}
{% block content %}
<h3>Create New Item ID</h3>
<form action="" method="POST">{% csrf_token %}
    <p><select name="dd_item_type"
        hx-get="{% url 'create_itemid_2' %}"
        hx-trigger="change"
        hx-target="#create_itemid_2">
        <option selected>--- choose item type ---</option>
        {% for itemtype in item_types %}
            <option value="{{itemtype.pk}}">{{ itemtype.item_type }}</option>
        {% endfor %}
    </select></p>
    <div id="create_itemid_2">
        {% include "create_itemid_2.html" %}
    </div>
    <input type="submit" value="Create"/>
</form>
<a href="{% url 'home' %}">Nevermind</a>
{% endblock %}
<!-- templates/create_itemid_2.html -->
<p><select name="dd_item_desc">
    <option selected>--- choose description ---</option>
    {% for itemdesc in item_descs %}
        <option value="{{itemdesc.pk}}">{{ itemdesc.item_desc }}</option>
    {% endfor %}
</select></p>

Solution

  • What I was missing:

    There was an issue with the downloaded file, htmx.min.js.

    Instead of pulling down the actual JavaScript code (42,819 bytes), I pulled down the JavaScript with all its associated HTML formatting (361,101 bytes).

    Chalk that up to having zero knowledge of JS... but in my defense, it would be nice if there were some kind of console feedback for all that invalid code.