Build template-based form rendering with bootstrap attrs
This commit is contained in:
parent
eb91f59e09
commit
78119dc6b3
5 changed files with 79 additions and 1 deletions
28
src/servala/frontend/forms/renderers.py
Normal file
28
src/servala/frontend/forms/renderers.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
from django.forms.renderers import TemplatesSetting
|
||||
|
||||
|
||||
def inject_class(f, class_name):
|
||||
def inner(*args, **kwargs):
|
||||
result = f(*args, **kwargs)
|
||||
class_list = result.get("class", "")
|
||||
class_list = f"{class_list} {class_name}".strip()
|
||||
result["class"] = class_list
|
||||
return result
|
||||
|
||||
return inner
|
||||
|
||||
|
||||
class VerticalFormRenderer(TemplatesSetting):
|
||||
form_template_name = "frontend/forms/form.html"
|
||||
field_template_name = "frontend/forms/vertical_field.html"
|
||||
|
||||
def render(self, template_name, context, request=None):
|
||||
if field := context.get("field"):
|
||||
if field.field.widget.input_type == "checkbox":
|
||||
class_name = "form-check-input"
|
||||
else:
|
||||
class_name = "form-control"
|
||||
field.build_widget_attrs = inject_class(
|
||||
field.build_widget_attrs, class_name
|
||||
)
|
||||
return super().render(template_name, context, request)
|
|
@ -37,7 +37,10 @@
|
|||
<i class="bi bi-chevron-right me-2 ms-1 mb-2 collapse-icon"></i>
|
||||
{% translate "Log in with email and password instead" %}
|
||||
</a>
|
||||
<div class="collapse mt-3" id="login-form">
|
||||
<div class="collapse mt-3 ms-3"
|
||||
id="login-form"
|
||||
class="form form-vertical"
|
||||
style="max-width: 400px">
|
||||
<form method="post" action="{% url 'account_login' %}">
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
|
|
19
src/servala/frontend/templates/frontend/forms/form.html
Normal file
19
src/servala/frontend/templates/frontend/forms/form.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
{% if errors %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<div>
|
||||
{% if errors|length > 1 %}
|
||||
<ul>
|
||||
{% for error in errors %}<li>{{ error }}</li>{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
{{ errors.0 }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="form-body">
|
||||
<div class="row">
|
||||
{% for field, errors in fields %}{{ field.as_field_group }}{% endfor %}
|
||||
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,26 @@
|
|||
{% load i18n %}
|
||||
<div class="col-12">
|
||||
<div class="form-group{% with classes=field.css_classes %}{% if classes %} {{ classes }}{% endif %}{% endwith %}">
|
||||
{% if field.field.widget.input_type != "checkbox" or field.field.widget.allow_multiple_selected %}
|
||||
<label for="{{ field.auto_id }}" class="{{ label_class }}">
|
||||
{{ field.label }}
|
||||
{% if not field.field.required %}
|
||||
<span class="optional">{% translate "Optional" %}</span>
|
||||
{% endif %}
|
||||
</label>
|
||||
{% endif %}
|
||||
{% if field.use_fieldset %}
|
||||
<fieldset {% if field.help_text and field.auto_id and "aria-describedby" not in field.field.widget.attrs %} aria-describedby="{{ field.auto_id }}_helptext"{% endif %}>
|
||||
{% endif %}
|
||||
{{ field }}
|
||||
{% if field.field.widget.input_type == "checkbox" and not field.field.widget.allow_multiple_selected %}
|
||||
<label for="{{ field.auto_id }}">{{ field.label }}</label>
|
||||
{% endif %}
|
||||
{% if field.use_fieldset %}</fieldset>{% endif %}
|
||||
{% for text in field.errors %}<div class="invalid-feedback">{{ text }}</div>{% endfor %}
|
||||
{% if field.help_text %}
|
||||
<small class="form-text text-muted"
|
||||
{% if field.auto_id %}id="{{ field.auto_id }}_helptext"{% endif %}>{{ field.help_text|safe }}</small>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
|
@ -95,6 +95,7 @@ INSTALLED_APPS = [
|
|||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"django.forms",
|
||||
"servala.frontend",
|
||||
"allauth",
|
||||
"allauth.account",
|
||||
|
@ -151,6 +152,7 @@ TEMPLATES = [
|
|||
},
|
||||
]
|
||||
|
||||
FORM_RENDERER = "servala.frontend.forms.renderers.VerticalFormRenderer"
|
||||
MESSAGE_TAGS = {
|
||||
messages.ERROR: "danger",
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue