Giter Club home page Giter Club logo

django-htmx-modal-form's Introduction

Django+HTMX modal form

This project demonstrates how to show a Django Form in a modal dialog box using HTMX.

A video of the site

This branch contains the Bootstrap 5 version.
See also the Bootstrap 4 version in this repository, or a Tailwind + Alpine.js version in @geoffbeier's fork.

There are two additionnal branches that show how to use this technique with the Django messages framework: with the HX-Trigger technique and with the "OOB swap" technique

Learn more about this technique here:

To run the demo locally:

pipenv install
pipenv run migrate
pipenv run server

django-htmx-modal-form's People

Contributors

bblanchon avatar dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

django-htmx-modal-form's Issues

Uncaught ReferenceError: bootstrap is not defined

Hi,

I am relatively new to django and javascript so this will likely be a relatively straightforward issue for you no doubt. I am receiving the error above when the dialog.js and toast.js is invoked. I am using the Hyper Bootstrap5 theme, loading the themes components through static rather than via CDN. I suspect that there is no access to the bootstrap components when trying to create an instance of modal, but I am unsure how to resolve this specifically.

Any advice you can provide is greatly appreciated.

Thanks,
Mitch

showMessage event more generic

Hi again, I have another question/idea.
You basically use an Hx-Trigger attr to create a custom event, with a payload, and show that payload with htmx.on().

This way, you always have to create the Hx-Trigger attr in your view, which is a bit non-djangoish and, despite working, feels like a hack to me. I really want to use Django's messaging framework for that, and I recently had an idea, but can't get forther with that. Maybe you know how to.

  • First, I would create <div class="toast"><div id="messages">...</div></div> tags which contains a typical Django message {% for ... %} loop and displays the messages.
  • I would create then, as you did, a Hx-Trigger attr, just with an empty "showMessage" content
  • using CBV, I override the dispatch() method (you can do that with a decorator etc in FBV to), so that if any messages are in line, the frontend gets notified:
if messages.get_messages(request):
    response.headers["HX-Trigger"] = "showMessage"
  • When swapping per HTMX, this triggers your Js part which shows e.g. the .toast classes
  • the HTMX/HTMX content contains a
<div id="messages">{% for message in messages %}</div>

wouldn't this be cleaner?

It should work in theory, but I can't get it to work... Any ideas?

movieListChanged scalable

H Benoit,
thanks for this great article, it freed my mind ;-)

A question rose up: You use the movieListChanged custom event and included it into the header. Do you add custom events per page, just for the things that are needed? Or do you recommend to create "generic" events (listUpdated) with attributes - to keep their list a little bit smaller?

I am considering this pattern in a larger (open source) application and just want to make the "right" decision.
Thanks again for your great code.

Tailwind CSS and Alpine.js version of this example

Hi,

Thank you very much for your articles and videos. They've been helpful as I've been learning how I like to add HTMX to my toolbox.

I think I've decided that I like the flexibility I get with Tailwind CSS and Alpine.js, and I forked your project to use that stack instead of bootstrap.

I did my work on the "tailwind" branch of my fork. I thought about offering it back as a PR, but the UI for that on github made it look like accepting the PR would apply it to your bootstrap5 branch.

It would probably be more useful if you wanted to just pull the tailwind branch into your repository. Please feel free to do that if you'd like to have a tailwind version next to the others.

Please also feel free to add another part to your articles or videos talking about this stack if you think it's worthwhile. (I have some ambitions of posting about it on my blog, but I've got a bit of a backlog there and may not get to it.)

Thanks again for putting together this demo and the two articles. They've really helped me understand the stack.

modal.hide & oob content

This code is great and versions have helped with lots of modals, but I found one flaw/issue. The if statement below fails to trigger if there is any content in the response, however if you have non-modal content included (ie an oob swap used for toasts or something) causes it not to fire (since there is a response). Any ideas on how to detect if there is no core swap response (ignoring oob content or otherwise)?

  htmx.on("htmx:beforeSwap", (e) => {
    // Empty response targeting #dialog => hide the modal
    if (e.detail.target.id == "dialog" && !e.detail.xhr.response) {
      modal.hide()
      e.detail.shouldSwap = false
    }
  })

Edit Button not firing up the modal

 <td>
        <button class="btn btn-primary btn-sm" hx-get="{% url 'edit_branch' branch.id %}" hx-target="#dialog">Edit
      <li class="fa fa-edit"></li>
    </button>

        <a href="" class="btn btn-warning btn-sm">
            <li class="fa fa-eye"></li>

        </a>
    </td>


;
(function() {
    const modal = new bootstrap.Modal(document.getElementById("modal"))

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

    htmx.on("htmx:beforeSwap", (e) => {
        // Empty response targeting #dialog => hide the modal
        if (e.detail.target.id == "dialog" && !e.detail.xhr.response) {
            modal.hide()
            e.detail.shouldSwap = false
        }
    })

    // Remove dialog content after hiding
    htmx.on("hidden.bs.modal", () => {
        document.getElementById("dialog").innerHTML = ""
    })
})()

Form validation error

Hello,
if I have <form method="POST">, form is submited fine, but if I have <form hx-post="{{ request.path }}"> form validation fails even I fill required form field (drop down)?
If I set all field optional, form is submited with defaul values even I filled all fields manually.

What could be the issue here?

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.