Source code for wildewidgets.widgets.modals
from __future__ import annotations
from typing import TYPE_CHECKING, Any
from django.core.exceptions import ImproperlyConfigured
from .base import Block
from .forms import CrispyFormWidget
if TYPE_CHECKING:
from django.forms import Form
[docs]class ModalWidget(Block):
"""
Renders a Bootstrap 5 Modal dialog.
This widget creates a Bootstrap modal dialog with a header, body, and footer.
The modal can be triggered by a button or link with a data-target attribute
matching the modal's ID.
Example:
.. code-block:: python
from wildewidgets import ModalWidget, Block
# Create a simple modal
modal = ModalWidget(
modal_id="example-modal",
modal_title="Important Information",
modal_body=Block("This is the modal content"),
modal_size="lg"
)
Attributes:
template_name: Path to the template for rendering the modal
modal_id: Unique identifier for the modal (used in triggering elements)
modal_title: Text to display in the modal header
modal_body: Content to display in the modal body (typically a Block)
modal_size: Size of the modal dialog (None, 'sm', 'lg', or 'xl')
Keyword Args:
modal_id: The CSS ID of the modal
modal_title: The title of the modal
modal_body: The body of the modal, any Block
modal_size: The size of the modal (None, 'sm', 'lg', or 'xl')
**kwargs: Additional attributes passed to the parent Block class
"""
template_name: str = "wildewidgets/modal.html"
modal_id: str | None = None
modal_title: str | None = None
modal_body: str | None = None
modal_size: str | None = None
def __init__(
self,
modal_id: str | None = None,
modal_title: str | None = None,
modal_body: str | None = None,
modal_size: str | None = None,
**kwargs: Any,
):
self.modal_id = modal_id or self.modal_id
self.modal_title = modal_title or self.modal_title
self.modal_body = modal_body or self.modal_body
self.modal_size = modal_size or self.modal_size
super().__init__(**kwargs)
[docs] def get_context_data(self, *args: Any, **kwargs: Any) -> dict[str, Any]:
"""
Prepare the context data for the modal template.
This method adds the modal-specific attributes to the template context
to be used in rendering the modal dialog.
Args:
*args: Variable length argument list
**kwargs: Arbitrary keyword arguments
Returns:
dict: The updated context dictionary with modal attributes
"""
kwargs = super().get_context_data(*args, **kwargs)
kwargs["modal_id"] = self.modal_id
kwargs["modal_title"] = self.modal_title
kwargs["modal_body"] = self.modal_body
kwargs["modal_size"] = self.modal_size
return kwargs
[docs]class CrispyFormModalWidget(ModalWidget):
"""
A modal dialog containing a Django form rendered with django-crispy-forms.
This specialized modal automatically places a form in the modal body,
making it easy to create form dialogs for user input. It handles the
rendering of the form using the CrispyFormWidget.
Example:
.. code-block:: python
from django import forms
from wildewidgets import CrispyFormModalWidget
class ContactForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
# Create a modal with the form
modal = CrispyFormModalWidget(
modal_id="contact-modal",
modal_title="Contact Us",
form_class=ContactForm
)
Attributes:
form_class: The form class to instantiate and render in the modal
form: An already instantiated form to render in the modal
Args:
form: An instantiated form to render in the modal
form_class: A form class to instantiate and render in the modal
**kwargs: Additional arguments passed to the parent ModalWidget class
(modal_id, modal_title, modal_size)
Raises:
ImproperlyConfigured: If neither form nor form_class is provided
"""
form_class: type[Form] | None = None
form: Form | None = None
def __init__(
self,
form: Form | None = None,
form_class: type[Form] | None = None,
**kwargs: Any,
):
if not form:
form = self.form
if not form_class:
form_class = self.form_class
if form_class:
modal_form = form_class()
elif form:
modal_form = form
else:
msg = "Either 'form_class' or 'form' must be set"
raise ImproperlyConfigured(msg)
modal_body = CrispyFormWidget(form=modal_form)
kwargs["modal_body"] = modal_body
super().__init__(**kwargs)