Search code examples
cssdjangohtmx

How to make htmx colour animations work with Django?


I have a simple Django project. I'm trying to get this example HTMX colour changing element working. https://htmx.org/examples/animations/

I have copied and pasted the exact code they use into my Django index.html file:

<style>
.smooth {
  transition: all 1s ease-in;
}
</style>
<div id="color-demo" class="smooth" style="color:red"
      hx-get="/colors" hx-swap="outerHTML" hx-trigger="every 1s">
  Color Swap Demo
</div>
<script>
    var colors = ['blue', 'green', 'orange', 'red'];
    onGet("/colors", function () {
      var color = colors.shift();
      colors.push(color);
      return '<div id="color-demo" hx-get="/colors" hx-swap="outerHTML" class="smooth" hx-trigger="every 1s" style="color:' + color + '">\n'+
             '  Color Swap Demo\n'+
             '</div>\n'
    });
</script>

This prints out the following: But unlike what is shown in the demo, it doesn't change colours every 1 second.

My command line for the Django server keeps throwing this error every 1 second:

Why is this happening and how can I fix this?


Solution

  • You are getting an error, because the url is invalid. You need to use the correct path in the hx-get to an exisiting view (something like hx-get="{% url 'colorapp:color_swap' %}"). Also, your view function needs to return a div with a color, where the color changes every second. You could use a loop, or simply change the color based on the current time in seconds.

    You could do something like this:

    urls.py:

    from django.urls import path
    from .views import views
    
    app_name = "colorapp"
    urlpatterns = [
        path("", views.index, name="index"),
        path("color_swap/", views.color_swap, name="color_swap"),
        ]
    

    views.py:

    from django.shortcuts import render
    import time
    
    def color_swap(request):
        now = round(time.time()/2,0)
        print(now)
        if (now % 2) == 0:
            color_name = "red"
        else:
            color_name = "blue"
        return render(
            request=request,
            template_name="colorapp/color_swap.html",
            context={"color_name": color_name}
        )
    

    swap_colors.html:

    {% extends "base.html" %}
    {% block content %}
    <style>
      .smooth {
        transition: all 1s ease-in;
      }
    </style>
    <div id="color-demo" 
         class="smooth" 
         style="color:{{color_name}}"
         hx-get="{% url 'colorapp:color_swap' %}" 
         hx-swap="outerHTML" 
         hx-trigger="every 1s">
        Color Swap Demo
    </div>
    {% endblock %}
    

    base.html

    <!doctype html>
    <html lang="en">
      <body>
        {% block content %}{% endblock content %}
        <script src="https://unpkg.com/htmx.org@1.8.6"></script>
        <script>
          document.body.addEventListener('htmx:configRequest', (event) => {
            event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
          })
        </script>
      </body>
    </html>
    

    Depending on your use case, it could be easier to implement this without the server requests using a local javascript.