Home > Back-end >  Using HTMX/Javascript in Django Template : not defined
Using HTMX/Javascript in Django Template : not defined

Time:10-15

I decided to try HTMX with Django and implementing a Django form in a modal box. I found this tutorial and was following it.

I got to the part where it uses an HTMX function htmx:afterSwap to open the modal but when I put that in a script tag in the template, I run into an error. It is Step 4 where the error occurs.

My template looks (mostly) like this. I've tried to trim it down to the essentials.

{% for thing in things %}
    {% if forloop.first %}
    <ul id="myThingList" >
    {% endif %}
    <button id="thing{{ thing.id }}Button" type="button"  hx-get="{% url 'myapp:things-create' %}" hx-target="#thingSection"> Upload Thing</button>
    <li id="thingItem"  hx-target="this" hx-swap="outerHTML">
        {{ thing.name }}
    </li>
    <div id="thingModal"  role="dialog" tabindex="-1" aria-labelledby="thingModal" aria-hidden="true">
        <div id="thingSection"  hx-target="this" role="document"></div>
    </div>
    {% if forloop.last %}
    </ul>
    {% endif  %}
{% empty %}
    <p >No things have been added yet.</p>
{% endfor %}


<script>
const modal = new bootstrap.Modal(document.getElementById("thingModal"))

htmx.on("htmx:afterSwap", (e) => {
  // Response targeting #thingSection => show the modal
  if (e.detail.target.id == "thingSection") {
    modal.show()
  }
})

</script>

I am getting Uncaught ReferenceError: bootstrap is not defined

Additional information:

HTMX works (I use it in other parts of the template without issue) and Bootstrap is loaded because all the CSS works on the page/templates, too.

I use webpack to vendor in all my JS files (combined/minimized) them into one vendors.h3117haj3.js file. The numbers are a random hash that is linked to in a base template that I extend in other templates.

Is there a way to get it to recognize bootstrap and htmx in that script tag?

The index.js file looks like this:

import "../scss/myapp.scss";
import "../css/style.css";
import 'htmx.org';
import "bootstrap";

CodePudding user response:

Using a bundler you have the option to include all Boostrap components under a namespace like bootstrap, or you can include only individual components to keep the bundle size small. The referenced tutorial used the script include method that by default includes all BS components under the bootstrap namespace. To replicate it with a bundler, you have to modify your index.js:

import "../scss/myapp.scss"
import "../css/style.css"
import 'htmx.org'

// Import all of Bootstrap's JS
import * as bootstrap from 'bootstrap'

Then bootstrap.Modal() will be a valid function.

If you want to import only the modal component, you can use:

import { Modal } from 'bootstrap'

Then you have the Modal() method available, so you need to modify this line in your template as well:

const modal = new Modal(document.getElementById("thingModal"))
  • Related