Creating a form with HTMX, Django

Step 1: Activate htmx (link) for django: Render a csrf token somewhere

HTML
  <body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>

Step 2: Create the form with hx-post

Python
<form hx-post="{% url 'posts:create' %}">
  <label for="post">post</label>
  <br />
  <textarea id="post" name="post" class="w-100 rounded" rows="20">{{ body }}</textarea>
  <br />
  <input type="submit" value="Submit" class="mt-1" />
</form>

Case: Targeting a container div

  • Sometimes your form is within a div you want to replace
HTML
<div id="targetDiv">
  <h1> Create a Post </h1>
  <form hx-post="{% url 'posts:create' %}" hx-target="targetDiv" hx-swap="innerHTML">
    <label for="post">post</label>
    <br />
    <textarea id="post" name="post" class="w-100 rounded" rows="20">
      {{ body }}
    </textarea>
    <br />
    <input type="submit" value="Submit" class="mt-1" />
  </form>
</div>

Case: Loading states extension (docs)

Setup: import script, set style to avoid flash, add header

HTML
<script src="https://unpkg.com/htmx.org/dist/ext/loading-states.js"></script>
...
<style>
  [data-loading] {
    display: none;
  }
  
</style>
...
<body hx-ext="loading-states">

Disable submit, add a loading indicator

HTML
<div id="targetDiv">
  <h1> Create a Post </h1>
  <form hx-post="{% url 'posts:create' %}" hx-target="targetDiv">
    <label for="post">post</label>
    <br />
    <textarea id="post" name="post" class="w-100 rounded" rows="20">{{ body }}</textarea>
    <br />
    <input type="submit" value="Submit" class="mt-1" data-loading-disable/>
  </form>
  <div data-loading>LOADING</div>
</div>