Django Crispy Forms inside Bootstrap Modals
Project description
django-crisp-modals
django-crisp-modals is a Django app which provides support for ajax Django Crispy Forms inside Bootstrap 5 modal dialogs. The app provides various views, form classes, templates and javascript. A demo site showcasing an example configuration various features, is available in the repository.
Quick start
-
Add "crisp_modals", and "crispy_forms" to your INSTALLED_APPS setting like this::
INSTALLED_APPS = [ ..., "crispy_forms", "crispy_bootstrap5", "crisp_modals", ]
-
Add the following to your settings.py file::
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" CRISPY_TEMPLATE_PACK = "bootstrap5"
-
Include the
crisp_modals/modals.min.jswithin your base template after jQuery and add a blank modal div to the bottom of the body tag. The modal div should have the id:modal-target. Then initialize the modal target. For example:{% load static %} ... <div id="modal-target"></div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/jquery-form@4.3.0/dist/jquery.form.min.js"></script> <script src="{% static 'crisp_modals/modals.min.js' %}"></script> <script> $(document).ready(function() { $('#modal-target').initModal({ setup: function (element) { // This function is called for each modal that is opened. // You can add any additional setup code here. ... } }); }); </script> -
Create forms as follows. The main crispy-forms helper is available as
self.bodywithin the forms. A footer helper is also available asself.footer, with 'submit' and 'reset' buttons already included. To override the footer buttons, you can use theself.footer.clear()method to remove the default buttons and then add your own.from crisp_modals.forms import ModalModelForm, Row, FullWidth class PollForm(ModalModelForm): class Meta: model = Poll fields = ['question', 'pub_date'] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.body.append( Row( FullWidth('question', placeholder='Enter your question'), ), Row( FullWidth('pub_date', placeholder='Enter the publication date'), ) )
-
In your views, use the ModalCreateView, ModalUpdateView, ModalConfirmView, and ModalDeleteView classes as follows. Include
delete_urlin the form kwargs for the ModalUpdateView class to show the delete button within the form. By default, the form will be submitted to the same URL as the view, but you can override this by adding aform_actionvariable to the form keyword arguments.from crisp_modals.views import ModalCreateView, ModalUpdateView, ModalDeleteView class PollCreateView(ModalCreateView): model = Poll form_class = PollForm class PollEditView(ModalUpdateView): model = Poll form_class = PollForm def get_form_kwargs(self): kwargs = super().get_form_kwargs() # If you want the form submitted to a different url, override the `form_action` variable. kwargs['form_action'] = ... # e.g., reverse('polls:poll-update', kwargs={'pk': self.object.pk}) return kwargs def get_delete_url(self): # If you want to show a delete button in the form, you can return the URL for the delete confirmation view. return reverse('polls:poll-delete', kwargs={'pk': self.object.pk}) class PollConfirView(ModalConfirmView): model = Poll def get_context_data(self): context = super().get_context_data() context['title'] = 'Close Poll' context['message'] = 'Are you sure you want to close this poll?' return context def confirmed(self, *args, **kwargs): # Logic to close the poll self.object.close() # Assuming the Poll model has a close method return super().confirmed() class PollDeleteView(ModalDeleteView): model = Poll
-
To distinguish regular links from links that target modals, use the 'data-modal-url' attribute instead of href. For example:
<a href="#0" data-modal-url="{% url 'polls:poll-create' %}" class="modal-link">Create Poll</a> <a href="#0" data-modal-url="{% url 'polls:poll-update' pk=poll.pk %}">Update Poll</a>
Note:
The
data-modal-urlattribute should contain the url of the view that will render the modal. It doesn't have to return a form. Non-form modal content can be rendered by overriding themodal_contentblock in the modal templatecrisp_modals/modal.html. The following blocks are available for overriding:modal_header,modal_body,modal_footer,modal_scripts. Themodal_scriptsblock should be used to include any additional JavaScript required for the modal content per-instance. Any code needed for all modals should go in theinitModalsetup option.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_crisp_modals-2026.1.0.tar.gz.
File metadata
- Download URL: django_crisp_modals-2026.1.0.tar.gz
- Upload date:
- Size: 13.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.1 CPython/3.13.11 Linux/6.17.12-300.fc43.x86_64
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da2cabe7b79be338ee30583f49933485447d10c7e7aaf7172719d4d73a23a80d
|
|
| MD5 |
139d406acf690bb6763d0836d51166ca
|
|
| BLAKE2b-256 |
684ecae53b127367703a39e7b9f407e268ae22c939b88f13f28f6e270077d26b
|
File details
Details for the file django_crisp_modals-2026.1.0-py3-none-any.whl.
File metadata
- Download URL: django_crisp_modals-2026.1.0-py3-none-any.whl
- Upload date:
- Size: 17.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.1 CPython/3.13.11 Linux/6.17.12-300.fc43.x86_64
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3867a6d9880a18377869807188c1fe264ebe842f6b696a63f2c80f547b3434d1
|
|
| MD5 |
f35dfd67bec079705db0e0ea2236b9de
|
|
| BLAKE2b-256 |
2f209b3c261f4a419c06de960c4397b8500efdc6191f8df875d88e15e150f491
|