Vincent A Saulys' Blog
HTMX Cheat Sheet
Tags: javascript cheat-sheet
July 15, 2021

I like using HTMX in personal projects because its tiny and works without needing a full framework like ReactJS. Figured I'd make this public for anybody else that cares.

Attributes

These attributes can all be prefixed with data-hx-<method>

<div
    hx-<request>=""
    hx-trigger=""
    hx-target=""
    hx-swap="">
  Click Me
</div>

Standard Event Modifiers for hx-trigger

These can be chained to have multiple (e.g. "keyup changed delay:1s")

Exposes a javascript function called htmx.trigger().

Request Payloads

CSS Transitions

<div id="parent"></div>

<div>
  <button
      hx-get="/clicked"
      hx-trigger="click"
      hx-target="#parent"
      hx-swap="innerHTML settle:1s"
  >
    Click Me To Replace Above
  </button>
</div>

In the above section, htmx-settling class will be appended to the #parent tag. You could set CSS to create a transition. An example is below (though this example will look a bit ugly).

.htmx-settling {
  opacity: 0;
}

#parent {
  opacity: 1;
  transition: opacity 1s ease-out;
}

Django CBV Snippets

To help with processing requests taht go back and forth

From templates

<form>
  {{ csrf_token }}
  {{ form.as_p }}
  <input type="submit">
</form>

Below is an example using CBVs in Django. When a POST request is made to "PostForm", it will perform validation against LoginForm and issue either a success_reponse_template (on success) or error_response_template on failure. On a GET request, it returns the page with the form embedded.

class LoginForm(forms.Form):
    username = forms.CharField(required=True)
    password = forms.CharField(
        max_length=32, widget=forms.PasswordInput, required=True, min_length=6
    )

class HtmxFormMixin(object):
    def form_valid(self, form):
        assert hasattr(self, "success_response_template") and hasattr(
            self, "error_response_template"
        ), "No success_response_template and error_response_template configured"
        if not form.is_valid():
            return TemplateResponse(
                request=self.request,
                template=self.error_response_template,
                context={"form_errors": form.errors},  # think this is correct...
                using=None,
            )
        context = {**form.cleaned_data}
        return TemplateResponse(
            request=self.request,
            template=self.success_response_template,
            context=context,
            using=None,  # template_engine
        )


class PostForm(HtmxFormMixin, FormView):
    # these are standard for FormView
    template_name = "playground/login_form.html"
    form_class = LoginForm

    # these are specific to the HtmxFormMixin
    success_response_template = "playground/login_reply.html"
    error_response_template = "playground/login_failure.html"
<form hx-post="/post_form" hx-swap="outerHTML settle:1s" hx-target="this">
  {% csrf_token %}
  {{ form }}
  <input type="submit" value="Submit"/>
</form>
Share on...