Skip to content

abe-101/django-htmx-modal-forms

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

24 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Django Htmx Modal Forms

CI Status Documentation Status Test coverage percentage

uv Ruff pre-commit

PyPI Version Supported Python versions License


Documentation: https://django-htmx-modal-forms.readthedocs.io

Source Code: https://github.com/abe-101/django-htmx-modal-forms


A Django package that provides class-based views for handling forms in Bootstrap modals using HTMX. This package makes it easy to add create and update functionality to your Django models with a clean modal interface.

Features

  • πŸš€ Easy-to-use class-based views for modal forms
  • ⚑ HTMX-powered for dynamic updates without page reloads
  • 🎨 Bootstrap modal integration with customizable sizes
  • ✨ Automatic form validation with error handling
  • πŸ› Debug mode for development

Requirements

  • Python 3.8+
  • Django 4.2+
  • django-htmx
  • Bootstrap 5
  • django-crispy-forms

Installation

  1. Install via pip:
pip install django-htmx-modal-forms
  1. Add to your INSTALLED_APPS:
INSTALLED_APPS = [
    ...
    "crispy_forms",
    "crispy_bootstrap5",
    "django-htmx"
    "django_htmx_modal_forms",
]
  1. Load and include the JavaScript in your base template:
{% load htmx_modal_forms %}

<!doctype html>
<html>
  <head>
    <!-- Required dependencies -->
    <script src="{% static 'js/bootstrap.bundle.min.js' %}"></script>
    <script src="{% static 'js/htmx.min.js' %}"></script>

    <!-- Modal handlers -->
    {% htmx_modal_script %}
  </head>
  <body>
    <!-- Your content -->
  </body>
</html>

Quick Start

  1. Create your view:
from django_htmx_modal_forms import HtmxModalUpdateView

class PersonUpdateView(HtmxModalUpdateView):
    model = Person
    form_class = PersonForm
    detail_template_name = "persons/_person_card.html"
    modal_size = "lg"  # Optional: sm, lg, or xl
  1. Add the URL pattern:
path("persons/<int:pk>/edit/", PersonUpdateView.as_view(), name="person_update"),
  1. Create your detail template (_person_card.html):
<div id="person-{{ person.id }}" class="card">
  <div class="card-body">
    <h5 class="card-title">{{ person.name }}</h5>
    <p class="card-text">{{ person.email }}</p>
  </div>
</div>

Important: The wrapper element must have an ID that matches your model instance (e.g., id="person-{{ person.id }}")! This ID is used by the view to locate and replace the content after a successful form submission.

  1. Add a button to trigger the modal:
<button
  hx-get="{% url 'person_update' pk=person.pk %}"
  hx-target="body"
  hx-swap="beforeend"
  class="btn btn-primary"
>
  Edit Person
</button>

That's it! When you click the edit button, a modal will appear with your form. On successful submission, the person's card will automatically update with the new information.

Advanced Usage

Custom Modal Titles

class PersonCreateView(HtmxModalCreateView):
    model = Person
    form_class = PersonForm
    modal_title = "Add New Team Member"  # Custom title

Different Modal Sizes

class PersonUpdateView(HtmxModalUpdateView):
    model = Person
    form_class = PersonForm
    modal_size = "xl"  # Available: sm, lg, xl

Debug Mode

Debug mode is automatically enabled when settings.DEBUG = True. It provides helpful console logging for:

  • Modal initialization
  • Event triggers
  • Bootstrap/HTMX availability
  • Error conditions

How It Works Behind the Scenes

The package orchestrates a series of interactions between Django, HTMX, and Bootstrap:

  1. When you click an edit button, HTMX makes a GET request to your view
  2. The view returns a Bootstrap modal containing your form and triggers the modal:show event
  3. The included JavaScript initializes and displays the modal
  4. When submitting the form:
    • If there are validation errors, the view replaces the form content with the errors
    • On success:
      1. The view updates your model
      2. Renders the new content using your detail template
      3. Uses HTMX's out-of-band swap to replace the content using the ID you provided
      4. Triggers the modal to close

This approach provides a smooth user experience with minimal JavaScript while maintaining Django's server-side validation and template rendering.

[Previous content remains the same until Contributing section]

Credits

This package was inspired by Josh Karamuth's blog posts on Django + HTMX modals:

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. To develop locally:

  1. Clone the repository
  2. Install dependencies: uv sync
  3. Run tests: uv run pytest

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Abe Hanoka
Abe Hanoka

πŸ’» πŸ€” πŸ“–

This project follows the all-contributors specification. Contributions of any kind welcome!

Credits

This package was created with Copier and the browniebroke/pypackage-template project template.

About

Django class-based views for HTMX-powered Bootstrap modals

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Sponsor this project

 

Packages

 
 
 

Contributors