login page

This commit is contained in:
Alicja Cięciwa
2020-10-27 12:57:58 +01:00
commit cb8886666c
8545 changed files with 1082463 additions and 0 deletions

View File

@@ -0,0 +1 @@
__version__ = "1.9.2"

View File

@@ -0,0 +1,22 @@
class KeepContext:
"""
Context manager that receives a `django.template.Context` instance and a list of keys
Once the context manager is exited, it removes `keys` from the context, to avoid
side effects in later layout objects that may use the same context variables.
Layout objects should use `extra_context` to introduce context variables, never
touch context object themselves, that could introduce side effects.
"""
def __init__(self, context, keys):
self.context = context
self.keys = keys
def __enter__(self):
pass
def __exit__(self, type, value, traceback):
for key in list(self.keys):
if key in self.context:
del self.context[key]

View File

@@ -0,0 +1,409 @@
from random import randint
from django.template import Template
from django.template.defaultfilters import slugify
from django.template.loader import render_to_string
from .layout import Div, Field, LayoutObject, TemplateNameMixin
from .utils import TEMPLATE_PACK, flatatt, render_field
class PrependedAppendedText(Field):
template = "%s/layout/prepended_appended_text.html"
def __init__(self, field, prepended_text=None, appended_text=None, *args, **kwargs):
self.field = field
self.appended_text = appended_text
self.prepended_text = prepended_text
if "active" in kwargs:
self.active = kwargs.pop("active")
self.input_size = None
css_class = kwargs.get("css_class", "")
if "input-lg" in css_class:
self.input_size = "input-lg"
if "input-sm" in css_class:
self.input_size = "input-sm"
super().__init__(field, *args, **kwargs)
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, extra_context=None, **kwargs):
extra_context = extra_context.copy() if extra_context is not None else {}
extra_context.update(
{
"crispy_appended_text": self.appended_text,
"crispy_prepended_text": self.prepended_text,
"input_size": self.input_size,
"active": getattr(self, "active", False),
}
)
if hasattr(self, "wrapper_class"):
extra_context["wrapper_class"] = self.wrapper_class
template = self.get_template_name(template_pack)
return render_field(
self.field,
form,
form_style,
context,
template=template,
attrs=self.attrs,
template_pack=template_pack,
extra_context=extra_context,
**kwargs,
)
class AppendedText(PrependedAppendedText):
def __init__(self, field, text, *args, **kwargs):
kwargs.pop("appended_text", None)
kwargs.pop("prepended_text", None)
self.text = text
super().__init__(field, appended_text=text, **kwargs)
class PrependedText(PrependedAppendedText):
def __init__(self, field, text, *args, **kwargs):
kwargs.pop("appended_text", None)
kwargs.pop("prepended_text", None)
self.text = text
super().__init__(field, prepended_text=text, **kwargs)
class FormActions(LayoutObject):
"""
Bootstrap layout object. It wraps fields in a <div class="form-actions">
Example::
FormActions(
HTML(<span style="display: hidden;">Information Saved</span>),
Submit('Save', 'Save', css_class='btn-primary')
)
"""
template = "%s/layout/formactions.html"
def __init__(self, *fields, **kwargs):
self.fields = list(fields)
self.template = kwargs.pop("template", self.template)
self.attrs = kwargs
if "css_class" in self.attrs:
self.attrs["class"] = self.attrs.pop("css_class")
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
html = self.get_rendered_fields(form, form_style, context, template_pack, **kwargs)
template = self.get_template_name(template_pack)
context.update({"formactions": self, "fields_output": html})
return render_to_string(template, context.flatten())
def flat_attrs(self):
return flatatt(self.attrs)
class InlineCheckboxes(Field):
"""
Layout object for rendering checkboxes inline::
InlineCheckboxes('field_name')
"""
template = "%s/layout/checkboxselectmultiple_inline.html"
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
return super().render(
form, form_style, context, template_pack=template_pack, extra_context={"inline_class": "inline"}
)
class InlineRadios(Field):
"""
Layout object for rendering radiobuttons inline::
InlineRadios('field_name')
"""
template = "%s/layout/radioselect_inline.html"
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
return super().render(
form, form_style, context, template_pack=template_pack, extra_context={"inline_class": "inline"}
)
class FieldWithButtons(Div):
template = "%s/layout/field_with_buttons.html"
field_template = "%s/field.html"
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, extra_context=None, **kwargs):
# We first render the buttons
field_template = self.field_template % template_pack
buttons = "".join(
render_field(
field,
form,
form_style,
context,
field_template,
layout_object=self,
template_pack=template_pack,
**kwargs,
)
for field in self.fields[1:]
)
extra_context = {"div": self, "buttons": buttons}
template = self.get_template_name(template_pack)
if isinstance(self.fields[0], Field):
# FieldWithButtons(Field('field_name'), StrictButton("go"))
# We render the field passing its name and attributes
return render_field(
self.fields[0][0],
form,
form_style,
context,
template,
attrs=self.fields[0].attrs,
template_pack=template_pack,
extra_context=extra_context,
**kwargs,
)
else:
return render_field(
self.fields[0], form, form_style, context, template, extra_context=extra_context, **kwargs
)
class StrictButton(TemplateNameMixin):
"""
Layout object for rendering an HTML button::
Button("button content", css_class="extra")
"""
template = "%s/layout/button.html"
field_classes = "btn"
def __init__(self, content, **kwargs):
self.content = content
self.template = kwargs.pop("template", self.template)
kwargs.setdefault("type", "button")
# We turn css_id and css_class into id and class
if "css_id" in kwargs:
kwargs["id"] = kwargs.pop("css_id")
kwargs["class"] = self.field_classes
if "css_class" in kwargs:
kwargs["class"] += " %s" % kwargs.pop("css_class")
self.flat_attrs = flatatt(kwargs)
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
self.content = Template(str(self.content)).render(context)
template = self.get_template_name(template_pack)
context.update({"button": self})
return render_to_string(template, context.flatten())
class Container(Div):
"""
Base class used for `Tab` and `AccordionGroup`, represents a basic container concept
"""
css_class = ""
def __init__(self, name, *fields, **kwargs):
super().__init__(*fields, **kwargs)
self.template = kwargs.pop("template", self.template)
self.name = name
self._active_originally_included = "active" in kwargs
self.active = kwargs.pop("active", False)
if not self.css_id:
self.css_id = slugify(self.name)
def __contains__(self, field_name):
"""
check if field_name is contained within tab.
"""
return field_name in map(lambda pointer: pointer[1], self.get_field_names())
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
if self.active:
if "active" not in self.css_class:
self.css_class += " active"
else:
self.css_class = self.css_class.replace("active", "")
return super().render(form, form_style, context, template_pack)
class ContainerHolder(Div):
"""
Base class used for `TabHolder` and `Accordion`, groups containers
"""
def first_container_with_errors(self, errors):
"""
Returns the first container with errors, otherwise returns None.
"""
for tab in self.fields:
errors_here = any(error in tab for error in errors)
if errors_here:
return tab
return None
def open_target_group_for_form(self, form):
"""
Makes sure that the first group that should be open is open.
This is either the first group with errors or the first group
in the container, unless that first group was originally set to
active=False.
"""
target = self.first_container_with_errors(form.errors.keys())
if target is None:
target = self.fields[0]
if not getattr(target, "_active_originally_included", None):
target.active = True
return target
target.active = True
return target
class Tab(Container):
"""
Tab object. It wraps fields in a div whose default class is "tab-pane" and
takes a name as first argument. Example::
Tab('tab_name', 'form_field_1', 'form_field_2', 'form_field_3')
"""
css_class = "tab-pane"
link_template = "%s/layout/tab-link.html"
def render_link(self, template_pack=TEMPLATE_PACK, **kwargs):
"""
Render the link for the tab-pane. It must be called after render so css_class is updated
with active if needed.
"""
link_template = self.link_template % template_pack
return render_to_string(link_template, {"link": self})
class TabHolder(ContainerHolder):
"""
TabHolder object. It wraps Tab objects in a container. Requires bootstrap-tab.js::
TabHolder(
Tab('form_field_1', 'form_field_2'),
Tab('form_field_3')
)
"""
template = "%s/layout/tab.html"
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
for tab in self.fields:
tab.active = False
# Open the group that should be open.
self.open_target_group_for_form(form)
content = self.get_rendered_fields(form, form_style, context, template_pack)
links = "".join(tab.render_link(template_pack) for tab in self.fields)
context.update({"tabs": self, "links": links, "content": content})
template = self.get_template_name(template_pack)
return render_to_string(template, context.flatten())
class AccordionGroup(Container):
"""
Accordion Group (pane) object. It wraps given fields inside an accordion
tab. It takes accordion tab name as first argument::
AccordionGroup("group name", "form_field_1", "form_field_2")
"""
template = "%s/accordion-group.html"
data_parent = "" # accordion parent div id.
class Accordion(ContainerHolder):
"""
Accordion menu object. It wraps `AccordionGroup` objects in a container::
Accordion(
AccordionGroup("group name", "form_field_1", "form_field_2"),
AccordionGroup("another group name", "form_field")
)
"""
template = "%s/accordion.html"
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
content = ""
# accordion group needs the parent div id to set `data-parent` (I don't
# know why). This needs to be a unique id
if not self.css_id:
self.css_id = "-".join(["accordion", str(randint(1000, 9999))])
# Open the group that should be open.
self.open_target_group_for_form(form)
for group in self.fields:
group.data_parent = self.css_id
content += render_field(group, form, form_style, context, template_pack=template_pack, **kwargs)
template = self.get_template_name(template_pack)
context.update({"accordion": self, "content": content})
return render_to_string(template, context.flatten())
class Alert(Div):
"""
`Alert` generates markup in the form of an alert dialog
Alert(content='<strong>Warning!</strong> Best check yo self, you're not looking too good.')
"""
template = "%s/layout/alert.html"
css_class = "alert"
def __init__(self, content, dismiss=True, block=False, **kwargs):
fields = []
if block:
self.css_class += " alert-block"
Div.__init__(self, *fields, **kwargs)
self.template = kwargs.pop("template", self.template)
self.content = content
self.dismiss = dismiss
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
template = self.get_template_name(template_pack)
context.update({"alert": self, "content": self.content, "dismiss": self.dismiss})
return render_to_string(template, context.flatten())
class UneditableField(Field):
"""
Layout object for rendering fields as uneditable in bootstrap
Example::
UneditableField('field_name', css_class="input-xlarge")
"""
template = "%s/layout/uneditable_input.html"
def __init__(self, field, *args, **kwargs):
self.attrs = {"class": "uneditable-input"}
super().__init__(field, *args, **kwargs)
class InlineField(Field):
template = "%s/layout/inline_field.html"

View File

@@ -0,0 +1,6 @@
import django
if django.VERSION < (3, 0):
from django.utils.lru_cache import lru_cache # noqa: F401
else:
from functools import lru_cache # noqa: F401

View File

@@ -0,0 +1,16 @@
class CrispyError(Exception):
pass
class FormHelpersException(CrispyError):
"""
This is raised when building a form via helpers throws an error.
We want to catch form helper errors as soon as possible because
debugging templatetags is never fun.
"""
pass
class DynamicError(CrispyError):
pass

View File

@@ -0,0 +1,388 @@
import re
from django.urls import NoReverseMatch, reverse
from django.utils.safestring import mark_safe
from crispy_forms.exceptions import FormHelpersException
from crispy_forms.layout import Layout
from crispy_forms.layout_slice import LayoutSlice
from crispy_forms.utils import TEMPLATE_PACK, flatatt, list_difference, render_field
class DynamicLayoutHandler:
def _check_layout(self):
if self.layout is None:
raise FormHelpersException("You need to set a layout in your FormHelper")
def _check_layout_and_form(self):
self._check_layout()
if self.form is None:
raise FormHelpersException("You need to pass a form instance to your FormHelper")
def all(self):
"""
Returns all layout objects of first level of depth
"""
self._check_layout()
return LayoutSlice(self.layout, slice(0, len(self.layout.fields), 1))
def filter(self, *LayoutClasses, **kwargs):
"""
Returns a LayoutSlice pointing to layout objects of type `LayoutClass`
"""
self._check_layout()
max_level = kwargs.pop("max_level", 0)
greedy = kwargs.pop("greedy", False)
filtered_layout_objects = self.layout.get_layout_objects(LayoutClasses, max_level=max_level, greedy=greedy)
return LayoutSlice(self.layout, filtered_layout_objects)
def filter_by_widget(self, widget_type):
"""
Returns a LayoutSlice pointing to fields with widgets of `widget_type`
"""
self._check_layout_and_form()
layout_field_names = self.layout.get_field_names()
# Let's filter all fields with widgets like widget_type
filtered_fields = []
for pointer in layout_field_names:
if isinstance(self.form.fields[pointer[1]].widget, widget_type):
filtered_fields.append(pointer)
return LayoutSlice(self.layout, filtered_fields)
def exclude_by_widget(self, widget_type):
"""
Returns a LayoutSlice pointing to fields with widgets NOT matching `widget_type`
"""
self._check_layout_and_form()
layout_field_names = self.layout.get_field_names()
# Let's exclude all fields with widgets like widget_type
filtered_fields = []
for pointer in layout_field_names:
if not isinstance(self.form.fields[pointer[1]].widget, widget_type):
filtered_fields.append(pointer)
return LayoutSlice(self.layout, filtered_fields)
def __getitem__(self, key):
"""
Return a LayoutSlice that makes changes affect the current instance of the layout
and not a copy.
"""
# when key is a string containing the field name
if isinstance(key, str):
# Django templates access FormHelper attributes using dictionary [] operator
# This could be a helper['form_id'] access, not looking for a field
if hasattr(self, key):
return getattr(self, key)
self._check_layout()
layout_field_names = self.layout.get_field_names()
filtered_field = []
for pointer in layout_field_names:
# There can be an empty pointer
if len(pointer) == 2 and pointer[1] == key:
filtered_field.append(pointer)
return LayoutSlice(self.layout, filtered_field)
return LayoutSlice(self.layout, key)
def __setitem__(self, key, value):
self.layout[key] = value
def __delitem__(self, key):
del self.layout.fields[key]
def __len__(self):
if self.layout is not None:
return len(self.layout.fields)
else:
return 0
class FormHelper(DynamicLayoutHandler):
"""
This class controls the form rendering behavior of the form passed to
the `{% crispy %}` tag. For doing so you will need to set its attributes
and pass the corresponding helper object to the tag::
{% crispy form form.helper %}
Let's see what attributes you can set and what form behaviors they apply to:
**form_method**: Specifies form method attribute.
You can set it to 'POST' or 'GET'. Defaults to 'POST'
**form_action**: Applied to the form action attribute:
- Can be a named url in your URLconf that can be executed via the `{% url %}` template tag. \
Example: 'show_my_profile'. In your URLconf you could have something like::
url(r'^show/profile/$', 'show_my_profile_view', name = 'show_my_profile')
- It can simply point to a URL '/whatever/blabla/'.
**form_id**: Generates a form id for dom identification.
If no id provided then no id attribute is created on the form.
**form_class**: String containing separated CSS classes to be applied
to form class attribute. The form will always have by default
'uniForm' class.
**form_group_wrapper_class**: String containing separated CSS classes to be applied
to each row of inputs.
**form_tag**: It specifies if <form></form> tags should be rendered when using a Layout.
If set to False it renders the form without the <form></form> tags. Defaults to True.
**form_error_title**: If a form has `non_field_errors` to display, they
are rendered in a div. You can set title's div with this attribute.
Example: "Oooops!" or "Form Errors"
**formset_error_title**: If a formset has `non_form_errors` to display, they
are rendered in a div. You can set title's div with this attribute.
**form_style**: Uni-form has two built in different form styles. You can choose
your favorite. This can be set to "default" or "inline". Defaults to "default".
**include_media**: Whether to automatically include form media. Set to False if
you want to manually include form media outside the form. Defaults to True.
Public Methods:
**add_input(input)**: You can add input buttons using this method. Inputs
added using this method will be rendered at the end of the form/formset.
**add_layout(layout)**: You can add a `Layout` object to `FormHelper`. The Layout
specifies in a simple, clean and DRY way how the form fields should be rendered.
You can wrap fields, order them, customize pretty much anything in the form.
Best way to add a helper to a form is adding a property named helper to the form
that returns customized `FormHelper` object::
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
class MyForm(forms.Form):
title = forms.CharField(_("Title"))
@property
def helper(self):
helper = FormHelper()
helper.form_id = 'this-form-rocks'
helper.form_class = 'search'
helper.add_input(Submit('save', 'save'))
[...]
return helper
You can use it in a template doing::
{% load crispy_forms_tags %}
{% crispy form %}
"""
_form_method = "post"
_form_action = ""
_form_style = "default"
form = None
form_id = ""
form_class = ""
form_group_wrapper_class = ""
layout = None
form_tag = True
form_error_title = None
formset_error_title = None
form_show_errors = True
render_unmentioned_fields = False
render_hidden_fields = False
render_required_fields = False
_help_text_inline = False
_error_text_inline = True
html5_required = False
form_show_labels = True
template = None
field_template = None
disable_csrf = False
use_custom_control = True
label_class = ""
field_class = ""
include_media = True
def __init__(self, form=None):
self.attrs = {}
self.inputs = []
if form is not None:
self.form = form
self.layout = self.build_default_layout(form)
def build_default_layout(self, form):
return Layout(*form.fields.keys())
@property
def form_method(self):
return self._form_method
@form_method.setter
def form_method(self, method):
if method.lower() not in ("get", "post"):
raise FormHelpersException(
"Only GET and POST are valid in the \
form_method helper attribute"
)
self._form_method = method.lower()
@property
def form_action(self):
try:
return reverse(self._form_action)
except NoReverseMatch:
return self._form_action
@form_action.setter
def form_action(self, action):
self._form_action = action
@property
def form_style(self):
if self._form_style == "default":
return ""
if self._form_style == "inline":
return "inlineLabels"
@form_style.setter
def form_style(self, style):
if style.lower() not in ("default", "inline"):
raise FormHelpersException(
"Only default and inline are valid in the \
form_style helper attribute"
)
self._form_style = style.lower()
@property
def help_text_inline(self):
return self._help_text_inline
@help_text_inline.setter
def help_text_inline(self, flag):
self._help_text_inline = flag
self._error_text_inline = not flag
@property
def error_text_inline(self):
return self._error_text_inline
@error_text_inline.setter
def error_text_inline(self, flag):
self._error_text_inline = flag
self._help_text_inline = not flag
def add_input(self, input_object):
self.inputs.append(input_object)
def add_layout(self, layout):
self.layout = layout
def render_layout(self, form, context, template_pack=TEMPLATE_PACK):
"""
Returns safe html of the rendering of the layout
"""
form.rendered_fields = set()
form.crispy_field_template = self.field_template
# This renders the specified Layout strictly
html = self.layout.render(form, self.form_style, context, template_pack=template_pack)
# Rendering some extra fields if specified
if self.render_unmentioned_fields or self.render_hidden_fields or self.render_required_fields:
fields = tuple(form.fields.keys())
left_fields_to_render = list_difference(fields, form.rendered_fields)
for field in left_fields_to_render:
if (
self.render_unmentioned_fields
or (self.render_hidden_fields and form.fields[field].widget.is_hidden)
or (self.render_required_fields and form.fields[field].widget.is_required)
):
html += render_field(field, form, self.form_style, context, template_pack=template_pack)
return mark_safe(html)
def get_attributes(self, template_pack=TEMPLATE_PACK): # noqa: C901
"""
Used by crispy_forms_tags to get helper attributes
"""
items = {
"disable_csrf": self.disable_csrf,
"error_text_inline": self.error_text_inline,
"field_class": self.field_class,
"field_template": self.field_template or "%s/field.html" % template_pack,
"form_method": self.form_method.strip(),
"form_show_errors": self.form_show_errors,
"form_show_labels": self.form_show_labels,
"form_style": self.form_style.strip(),
"form_tag": self.form_tag,
"help_text_inline": self.help_text_inline,
"html5_required": self.html5_required,
"include_media": self.include_media,
"label_class": self.label_class,
"use_custom_control": self.use_custom_control,
}
if template_pack == "bootstrap4":
if "form-horizontal" in self.form_class.split():
bootstrap_size_match = re.findall(r"col(-(xl|lg|md|sm))?-(\d+)", self.label_class)
if bootstrap_size_match:
offset_pattern = "offset%s-%s"
items["bootstrap_checkbox_offsets"] = [
offset_pattern % (m[0], m[-1]) for m in bootstrap_size_match
]
else:
bootstrap_size_match = re.findall(r"col-(lg|md|sm|xs)-(\d+)", self.label_class)
if bootstrap_size_match:
offset_pattern = "col-%s-offset-%s"
items["bootstrap_checkbox_offsets"] = [offset_pattern % m for m in bootstrap_size_match]
items["attrs"] = {}
if self.attrs:
items["attrs"] = self.attrs.copy()
if self.form_action:
items["attrs"]["action"] = self.form_action.strip()
if self.form_id:
items["attrs"]["id"] = self.form_id.strip()
if self.form_class:
# uni_form TEMPLATE PACK has a uniForm class by default
if template_pack == "uni_form":
items["attrs"]["class"] = "uniForm %s" % self.form_class.strip()
else:
items["attrs"]["class"] = self.form_class.strip()
else:
if template_pack == "uni_form":
items["attrs"]["class"] = self.attrs.get("class", "") + " uniForm"
if self.form_group_wrapper_class:
items["attrs"]["form_group_wrapper_class"] = self.form_group_wrapper_class
items["flat_attrs"] = flatatt(items["attrs"])
if self.inputs:
items["inputs"] = self.inputs
if self.form_error_title:
items["form_error_title"] = self.form_error_title.strip()
if self.formset_error_title:
items["formset_error_title"] = self.formset_error_title.strip()
for attribute_name, value in self.__dict__.items():
if (
attribute_name not in items
and attribute_name not in ["layout", "inputs"]
and not attribute_name.startswith("_")
):
items[attribute_name] = value
return items

View File

@@ -0,0 +1,491 @@
from django.template import Template
from django.template.loader import render_to_string
from django.utils.html import conditional_escape
from crispy_forms.utils import TEMPLATE_PACK, flatatt, get_template_pack, render_field
class TemplateNameMixin:
def get_template_name(self, template_pack):
if "%s" in self.template:
template = self.template % template_pack
else:
template = self.template
return template
class LayoutObject(TemplateNameMixin):
def __getitem__(self, slice):
return self.fields[slice]
def __setitem__(self, slice, value):
self.fields[slice] = value
def __delitem__(self, slice):
del self.fields[slice]
def __len__(self):
return len(self.fields)
def __getattr__(self, name):
"""
This allows us to access self.fields list methods like append or insert, without
having to declare them one by one
"""
# Check necessary for unpickling, see #107
if "fields" in self.__dict__ and hasattr(self.fields, name):
return getattr(self.fields, name)
else:
return object.__getattribute__(self, name)
def get_field_names(self, index=None):
"""
Returns a list of lists, those lists are named pointers. First parameter
is the location of the field, second one the name of the field. Example::
[
[[0,1,2], 'field_name1'],
[[0,3], 'field_name2']
]
"""
return self.get_layout_objects(str, index=None, greedy=True)
def get_layout_objects(self, *LayoutClasses, **kwargs):
"""
Returns a list of lists pointing to layout objects of any type matching
`LayoutClasses`::
[
[[0,1,2], 'div'],
[[0,3], 'field_name']
]
:param max_level: An integer that indicates max level depth to reach when
traversing a layout.
:param greedy: Boolean that indicates whether to be greedy. If set, max_level
is skipped.
"""
index = kwargs.pop("index", None)
max_level = kwargs.pop("max_level", 0)
greedy = kwargs.pop("greedy", False)
pointers = []
if index is not None and not isinstance(index, list):
index = [index]
elif index is None:
index = []
for i, layout_object in enumerate(self.fields):
if isinstance(layout_object, LayoutClasses):
if len(LayoutClasses) == 1 and LayoutClasses[0] == str:
pointers.append([index + [i], layout_object])
else:
pointers.append([index + [i], layout_object.__class__.__name__.lower()])
# If it's a layout object and we haven't reached the max depth limit or greedy
# we recursive call
if hasattr(layout_object, "get_field_names") and (len(index) < max_level or greedy):
new_kwargs = {"index": index + [i], "max_level": max_level, "greedy": greedy}
pointers = pointers + layout_object.get_layout_objects(*LayoutClasses, **new_kwargs)
return pointers
def get_rendered_fields(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
return "".join(
render_field(field, form, form_style, context, template_pack=template_pack, **kwargs)
for field in self.fields
)
class Layout(LayoutObject):
"""
Form Layout. It is conformed by Layout objects: `Fieldset`, `Row`, `Column`, `MultiField`,
`HTML`, `ButtonHolder`, `Button`, `Hidden`, `Reset`, `Submit` and fields. Form fields
have to be strings.
Layout objects `Fieldset`, `Row`, `Column`, `MultiField` and `ButtonHolder` can hold other
Layout objects within. Though `ButtonHolder` should only hold `HTML` and BaseInput
inherited classes: `Button`, `Hidden`, `Reset` and `Submit`.
Example::
helper.layout = Layout(
Fieldset('Company data',
'is_company'
),
Fieldset(_('Contact details'),
'email',
Row('password1', 'password2'),
'first_name',
'last_name',
HTML('<img src="/media/somepicture.jpg"/>'),
'company'
),
ButtonHolder(
Submit('Save', 'Save', css_class='button white'),
),
)
"""
def __init__(self, *fields):
self.fields = list(fields)
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
return self.get_rendered_fields(form, form_style, context, template_pack, **kwargs)
class ButtonHolder(LayoutObject):
"""
Layout object. It wraps fields in a <div class="buttonHolder">
This is where you should put Layout objects that render to form buttons like Submit.
It should only hold `HTML` and `BaseInput` inherited objects.
Example::
ButtonHolder(
HTML(<span style="display: hidden;">Information Saved</span>),
Submit('Save', 'Save')
)
"""
template = "%s/layout/buttonholder.html"
def __init__(self, *fields, **kwargs):
self.fields = list(fields)
self.css_class = kwargs.get("css_class", None)
self.css_id = kwargs.get("css_id", None)
self.template = kwargs.get("template", self.template)
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
html = self.get_rendered_fields(form, form_style, context, template_pack, **kwargs)
template = self.get_template_name(template_pack)
context.update({"buttonholder": self, "fields_output": html})
return render_to_string(template, context.flatten())
class BaseInput(TemplateNameMixin):
"""
A base class to reduce the amount of code in the Input classes.
"""
template = "%s/layout/baseinput.html"
def __init__(self, name, value, **kwargs):
self.name = name
self.value = value
self.id = kwargs.pop("css_id", "")
self.attrs = {}
if "css_class" in kwargs:
self.field_classes += " %s" % kwargs.pop("css_class")
self.template = kwargs.pop("template", self.template)
self.flat_attrs = flatatt(kwargs)
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
"""
Renders an `<input />` if container is used as a Layout object.
Input button value can be a variable in context.
"""
self.value = Template(str(self.value)).render(context)
template = self.get_template_name(template_pack)
context.update({"input": self})
return render_to_string(template, context.flatten())
class Submit(BaseInput):
"""
Used to create a Submit button descriptor for the {% crispy %} template tag::
submit = Submit('Search the Site', 'search this site')
.. note:: The first argument is also slugified and turned into the id for the submit button.
"""
input_type = "submit"
def __init__(self, *args, **kwargs):
self.field_classes = "submit submitButton" if get_template_pack() == "uni_form" else "btn btn-primary"
super().__init__(*args, **kwargs)
class Button(BaseInput):
"""
Used to create a Submit input descriptor for the {% crispy %} template tag::
button = Button('Button 1', 'Press Me!')
.. note:: The first argument is also slugified and turned into the id for the button.
"""
input_type = "button"
def __init__(self, *args, **kwargs):
self.field_classes = "button" if get_template_pack() == "uni_form" else "btn"
super().__init__(*args, **kwargs)
class Hidden(BaseInput):
"""
Used to create a Hidden input descriptor for the {% crispy %} template tag.
"""
input_type = "hidden"
field_classes = "hidden"
class Reset(BaseInput):
"""
Used to create a Reset button input descriptor for the {% crispy %} template tag::
reset = Reset('Reset This Form', 'Revert Me!')
.. note:: The first argument is also slugified and turned into the id for the reset.
"""
input_type = "reset"
def __init__(self, *args, **kwargs):
self.field_classes = "reset resetButton" if get_template_pack() == "uni_form" else "btn btn-inverse"
super().__init__(*args, **kwargs)
class Fieldset(LayoutObject):
"""
Layout object. It wraps fields in a <fieldset>
Example::
Fieldset("Text for the legend",
'form_field_1',
'form_field_2'
)
The first parameter is the text for the fieldset legend. This text is context aware,
so you can do things like::
Fieldset("Data for {{ user.username }}",
'form_field_1',
'form_field_2'
)
"""
template = "%s/layout/fieldset.html"
def __init__(self, legend, *fields, **kwargs):
self.fields = list(fields)
self.legend = legend
self.css_class = kwargs.pop("css_class", "")
self.css_id = kwargs.pop("css_id", None)
self.template = kwargs.pop("template", self.template)
self.flat_attrs = flatatt(kwargs)
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
fields = self.get_rendered_fields(form, form_style, context, template_pack, **kwargs)
legend = ""
if self.legend:
legend = "%s" % Template(str(self.legend)).render(context)
template = self.get_template_name(template_pack)
return render_to_string(
template, {"fieldset": self, "legend": legend, "fields": fields, "form_style": form_style}
)
class MultiField(LayoutObject):
""" MultiField container. Renders to a MultiField <div> """
template = "%s/layout/multifield.html"
field_template = "%s/multifield.html"
def __init__(self, label, *fields, **kwargs):
self.fields = list(fields)
self.label_html = label
self.label_class = kwargs.pop("label_class", "blockLabel")
self.css_class = kwargs.pop("css_class", "ctrlHolder")
self.css_id = kwargs.pop("css_id", None)
self.help_text = kwargs.pop("help_text", None)
self.template = kwargs.pop("template", self.template)
self.field_template = kwargs.pop("field_template", self.field_template)
self.flat_attrs = flatatt(kwargs)
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
# If a field within MultiField contains errors
if context["form_show_errors"]:
for field in map(lambda pointer: pointer[1], self.get_field_names()):
if field in form.errors:
self.css_class += " error"
field_template = self.field_template % template_pack
fields_output = self.get_rendered_fields(
form,
form_style,
context,
template_pack,
template=field_template,
labelclass=self.label_class,
layout_object=self,
**kwargs,
)
template = self.get_template_name(template_pack)
context.update({"multifield": self, "fields_output": fields_output})
return render_to_string(template, context.flatten())
class Div(LayoutObject):
"""
Layout object. It wraps fields in a <div>
You can set `css_id` for a DOM id and `css_class` for a DOM class. Example::
Div('form_field_1', 'form_field_2', css_id='div-example', css_class='divs')
"""
template = "%s/layout/div.html"
def __init__(self, *fields, **kwargs):
self.fields = list(fields)
if hasattr(self, "css_class") and "css_class" in kwargs:
self.css_class += " %s" % kwargs.pop("css_class")
if not hasattr(self, "css_class"):
self.css_class = kwargs.pop("css_class", None)
self.css_id = kwargs.pop("css_id", "")
self.template = kwargs.pop("template", self.template)
self.flat_attrs = flatatt(kwargs)
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
fields = self.get_rendered_fields(form, form_style, context, template_pack, **kwargs)
template = self.get_template_name(template_pack)
return render_to_string(template, {"div": self, "fields": fields})
class Row(Div):
"""
Layout object. It wraps fields in a div whose default class is "formRow". Example::
Row('form_field_1', 'form_field_2', 'form_field_3')
"""
template = "%s/layout/row.html"
class Column(Div):
"""
Layout object. It wraps fields in a div so the wrapper can be used as a column. Example::
Column('form_field_1', 'form_field_2')
Depending on the template, css class associated to the div is formColumn, row, or nothing. For this last case, you
must provide css classes. Example::
Column('form_field_1', 'form_field_2', css_class='col-xs-6',)
"""
template = "%s/layout/column.html"
class HTML:
"""
Layout object. It can contain pure HTML and it has access to the whole
context of the page where the form is being rendered.
Examples::
HTML("{% if saved %}Data saved{% endif %}")
HTML('<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />')
"""
def __init__(self, html):
self.html = html
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
return Template(str(self.html)).render(context)
class Field(LayoutObject):
"""
Layout object, It contains one field name, and you can add attributes to it easily.
For setting class attributes, you need to use `css_class`, as `class` is a Python keyword.
Example::
Field('field_name', style="color: #333;", css_class="whatever", id="field_name")
"""
template = "%s/field.html"
def __init__(self, *args, **kwargs):
self.fields = list(args)
if not hasattr(self, "attrs"):
self.attrs = {}
else:
# Make sure shared state is not edited.
self.attrs = self.attrs.copy()
if "css_class" in kwargs:
if "class" in self.attrs:
self.attrs["class"] += " %s" % kwargs.pop("css_class")
else:
self.attrs["class"] = kwargs.pop("css_class")
self.wrapper_class = kwargs.pop("wrapper_class", None)
self.template = kwargs.pop("template", self.template)
# We use kwargs as HTML attributes, turning data_id='test' into data-id='test'
self.attrs.update({k.replace("_", "-"): conditional_escape(v) for k, v in kwargs.items()})
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, extra_context=None, **kwargs):
if extra_context is None:
extra_context = {}
if hasattr(self, "wrapper_class"):
extra_context["wrapper_class"] = self.wrapper_class
template = self.get_template_name(template_pack)
return self.get_rendered_fields(
form,
form_style,
context,
template_pack,
template=template,
attrs=self.attrs,
extra_context=extra_context,
**kwargs,
)
class MultiWidgetField(Field):
"""
Layout object. For fields with :class:`~django.forms.MultiWidget` as `widget`, you can pass
additional attributes to each widget.
Example::
MultiWidgetField(
'multiwidget_field_name',
attrs=(
{'style': 'width: 30px;'},
{'class': 'second_widget_class'}
),
)
.. note:: To override widget's css class use ``class`` not ``css_class``.
"""
def __init__(self, *args, **kwargs):
self.fields = list(args)
self.attrs = kwargs.pop("attrs", {})
self.template = kwargs.pop("template", self.template)
self.wrapper_class = kwargs.pop("wrapper_class", None)

View File

@@ -0,0 +1,156 @@
from crispy_forms.bootstrap import Container
from crispy_forms.exceptions import DynamicError
from crispy_forms.layout import Fieldset, MultiField
class LayoutSlice:
# List of layout objects that need args passed first before fields
args_first = (Fieldset, MultiField, Container)
def __init__(self, layout, key):
self.layout = layout
if isinstance(key, int):
self.slice = slice(key, key + 1, 1)
else:
self.slice = key
def wrapped_object(self, LayoutClass, fields, *args, **kwargs):
"""
Returns a layout object of type `LayoutClass` with `args` and `kwargs` that
wraps `fields` inside.
"""
if args:
if isinstance(fields, list):
fields = tuple(fields)
else:
fields = (fields,)
if LayoutClass in self.args_first:
arguments = args + fields
else:
arguments = fields + args
return LayoutClass(*arguments, **kwargs)
else:
if isinstance(fields, list):
return LayoutClass(*fields, **kwargs)
else:
return LayoutClass(fields, **kwargs)
def pre_map(self, function):
"""
Iterates over layout objects pointed in `self.slice` executing `function` on them.
It passes `function` penultimate layout object and the position where to find last one
"""
if isinstance(self.slice, slice):
for i in range(*self.slice.indices(len(self.layout.fields))):
function(self.layout, i)
elif isinstance(self.slice, list):
# A list of pointers Ex: [[[0, 0], 'div'], [[0, 2, 3], 'field_name']]
for pointer in self.slice:
position = pointer[0]
# If it's pointing first level
if len(position) == 1:
function(self.layout, position[-1])
else:
layout_object = self.layout.fields[position[0]]
for i in position[1:-1]:
layout_object = layout_object.fields[i]
try:
function(layout_object, position[-1])
except IndexError:
# We could avoid this exception, recalculating pointers.
# However this case is most of the time an undesired behavior
raise DynamicError(
"Trying to wrap a field within an already wrapped field, \
recheck your filter or layout"
)
def wrap(self, LayoutClass, *args, **kwargs):
"""
Wraps every layout object pointed in `self.slice` under a `LayoutClass` instance with
`args` and `kwargs` passed.
"""
def wrap_object(layout_object, j):
layout_object.fields[j] = self.wrapped_object(LayoutClass, layout_object.fields[j], *args, **kwargs)
self.pre_map(wrap_object)
def wrap_once(self, LayoutClass, *args, **kwargs):
"""
Wraps every layout object pointed in `self.slice` under a `LayoutClass` instance with
`args` and `kwargs` passed, unless layout object's parent is already a subclass of
`LayoutClass`.
"""
def wrap_object_once(layout_object, j):
if not isinstance(layout_object, LayoutClass):
layout_object.fields[j] = self.wrapped_object(LayoutClass, layout_object.fields[j], *args, **kwargs)
self.pre_map(wrap_object_once)
def wrap_together(self, LayoutClass, *args, **kwargs):
"""
Wraps all layout objects pointed in `self.slice` together under a `LayoutClass`
instance with `args` and `kwargs` passed.
"""
if isinstance(self.slice, slice):
# The start of the slice is replaced
start = self.slice.start if self.slice.start is not None else 0
self.layout.fields[start] = self.wrapped_object(
LayoutClass, self.layout.fields[self.slice], *args, **kwargs
)
# The rest of places of the slice are removed, as they are included in the previous
for i in reversed(range(*self.slice.indices(len(self.layout.fields)))):
if i != start:
del self.layout.fields[i]
elif isinstance(self.slice, list):
raise DynamicError("wrap_together doesn't work with filter, only with [] operator")
def map(self, function):
"""
Iterates over layout objects pointed in `self.slice` executing `function` on them
It passes `function` last layout object
"""
if isinstance(self.slice, slice):
for i in range(*self.slice.indices(len(self.layout.fields))):
function(self.layout.fields[i])
elif isinstance(self.slice, list):
# A list of pointers Ex: [[[0, 0], 'div'], [[0, 2, 3], 'field_name']]
for pointer in self.slice:
position = pointer[0]
layout_object = self.layout.fields[position[0]]
for i in position[1:]:
previous_layout_object = layout_object
layout_object = layout_object.fields[i]
# If update_attrs is applied to a string, we call to its wrapping layout object
if function.__name__ == "update_attrs" and isinstance(layout_object, str):
function(previous_layout_object)
else:
function(layout_object)
def update_attributes(self, **original_kwargs):
"""
Updates attributes of every layout object pointed in `self.slice` using kwargs
"""
def update_attrs(layout_object):
kwargs = original_kwargs.copy()
if hasattr(layout_object, "attrs"):
if "css_class" in kwargs:
if "class" in layout_object.attrs:
layout_object.attrs["class"] += " %s" % kwargs.pop("css_class")
else:
layout_object.attrs["class"] = kwargs.pop("css_class")
layout_object.attrs.update(kwargs)
self.map(update_attrs)

View File

@@ -0,0 +1,10 @@
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#{{ div.data_parent }}" href="#{{ div.css_id }}">{{ div.name }}</a>
</div>
<div id="{{ div.css_id }}" class="accordion-body collapse{% if div.active %} in{% endif %}" >
<div class="accordion-inner">
{{ fields|safe }}
</div>
</div>
</div>

View File

@@ -0,0 +1,3 @@
<div class="accordion" id="{{ accordion.css_id }}">
{{ content|safe }}
</div>

View File

@@ -0,0 +1,22 @@
{% for fieldset in form.fieldsets %}
<fieldset class="fieldset-{{ forloop.counter }} {{ fieldset.classes }}">
{% if fieldset.legend %}
<legend>{{ fieldset.legend }}</legend>
{% endif %}
{% if fieldset.description %}
<p class="description">{{ fieldset.description }}</p>
{% endif %}
{% for field in fieldset %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% include "bootstrap/field.html" %}
{% endif %}
{% endfor %}
{% if not forloop.last or not fieldset_open %}
</fieldset>
{% endif %}
{% endfor %}

View File

@@ -0,0 +1,9 @@
{% if form.form_html %}
{% if include_media %}{{ form.media }}{% endif %}
{% if form_show_errors %}
{% include "bootstrap/errors.html" %}
{% endif %}
{{ form.form_html }}
{% else %}
{% include "bootstrap/uni_form.html" %}
{% endif %}

View File

@@ -0,0 +1,8 @@
{% if form.non_field_errors %}
<div class="alert alert-block alert-error">
{% if form_error_title %}<h4 class="alert-heading">{{ form_error_title }}</h4>{% endif %}
<ul>
{{ form.non_field_errors|unordered_list }}
</ul>
</div>
{% endif %}

View File

@@ -0,0 +1,9 @@
{% if formset.non_form_errors %}
<div class="alert alert-block alert-error">
{% if formset_error_title %}<h4 class="alert-heading">{{ formset_error_title }}</h4>{% endif %}
<ul>
{{ formset.non_form_errors|unordered_list }}
</ul>
</div>
{% endif %}

View File

@@ -0,0 +1,36 @@
{% load crispy_forms_field %}
{% if field.is_hidden %}
{{ field }}
{% else %}
<{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" class="control-group{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if form_show_errors%}{% if field.errors %} error{% endif %}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
{% if field.label and not field|is_checkbox and form_show_labels %}
<label for="{{ field.id_for_label }}" class="control-label {% if field.field.required %}requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
{% if field|is_checkboxselectmultiple %}
{% include 'bootstrap/layout/checkboxselectmultiple.html' %}
{% endif %}
{% if field|is_radioselect %}
{% include 'bootstrap/layout/radioselect.html' %}
{% endif %}
{% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
<div class="controls">
{% if field|is_checkbox and form_show_labels %}
<label for="{{ field.id_for_label }}" class="checkbox {% if field.field.required %}requiredField{% endif %}">
{% crispy_field field %}
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% include 'bootstrap/layout/help_text_and_errors.html' %}
{% else %}
{% crispy_field field %}
{% include 'bootstrap/layout/help_text_and_errors.html' %}
{% endif %}
</div>
{% endif %}
</{% if tag %}{{ tag }}{% else %}div{% endif %}>
{% endif %}

View File

@@ -0,0 +1,4 @@
<div{% if alert.css_id %} id="{{ alert.css_id }}"{% endif %}{% if alert.css_class %} class="{{ alert.css_class }}"{% endif %}>
{% if dismiss %}<button type="button" class="close" data-dismiss="alert">&times;</button>{% endif %}
{{ content|safe }}
</div>

View File

@@ -0,0 +1,9 @@
<input type="{{ input.input_type }}"
name="{% if input.name|wordcount > 1 %}{{ input.name|slugify }}{% else %}{{ input.name }}{% endif %}"
value="{{ input.value }}"
{% if input.input_type != "hidden" %}
class="{{ input.field_classes }}"
id="{% if input.id %}{{ input.id }}{% else %}{{ input.input_type }}-id-{{ input.name|slugify }}{% endif %}"
{% endif %}
{{ input.flat_attrs|safe }}
/>

View File

@@ -0,0 +1 @@
<button {{ button.flat_attrs|safe }}>{{ button.content|safe }}</button>

View File

@@ -0,0 +1,4 @@
<div {% if buttonholder.css_id %}id="{{ buttonholder.css_id }}"{% endif %}
class="buttonHolder{% if buttonholder.css_class %} {{ buttonholder.css_class }}{% endif %}">
{{ fields_output|safe }}
</div>

View File

@@ -0,0 +1,14 @@
{% load crispy_forms_filters %}
{% load l10n %}
<div class="controls"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}>
{% include 'bootstrap/layout/field_errors_block.html' %}
{% for choice in field.field.choices %}
<label class="checkbox{% if inline_class %} {{ inline_class }}{% endif %}" for="id_{{ field.html_name }}_{{ forloop.counter }}">
<input type="checkbox"{% if choice.0 in field.value or choice.0|stringformat:"s" in field.value or choice.0|stringformat:"s" == field.value|default_if_none:""|stringformat:"s" %} checked="checked"{% endif %} name="{{ field.html_name }}" id="id_{{ field.html_name }}_{{ forloop.counter }}" value="{{ choice.0|unlocalize }}" {{ field.field.widget.attrs|flatatt }}>{{ choice.1|unlocalize }}
</label>
{% endfor %}
{% include 'bootstrap/layout/help_text.html' %}
</div>

View File

@@ -0,0 +1,14 @@
{% if field.is_hidden %}
{{ field }}
{% else %}
<div id="div_{{ field.auto_id }}" class="control-group{% if form_show_errors and field.errors %} error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
{% if field.label %}
<label for="{{ field.auto_id }}" class="control-label{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
{% include 'bootstrap/layout/checkboxselectmultiple.html' %}
</div>
{% endif %}

View File

@@ -0,0 +1,3 @@
<div {% if div.css_id %}id="{{ div.css_id }}"{% endif %} class="{{ div.css_class|default:'' }}" {{ div.flat_attrs|safe }}>
{{ fields|safe }}
</div>

View File

@@ -0,0 +1,4 @@
<div {% if div.css_id %}id="{{ div.css_id }}"{% endif %}
{% if div.css_class %}class="{{ div.css_class }}"{% endif %} {{ div.flat_attrs|safe }}>
{{ fields|safe }}
</div>

View File

@@ -0,0 +1,5 @@
{% if form_show_errors and field.errors %}
{% for error in field.errors %}
<span id="error_{{ forloop.counter }}_{{ field.auto_id }}" class="help-inline"><strong>{{ error }}</strong></span>
{% endfor %}
{% endif %}

View File

@@ -0,0 +1,5 @@
{% if form_show_errors and field.errors %}
{% for error in field.errors %}
<p id="error_{{ forloop.counter }}_{{ field.auto_id }}" class="help-block"><strong>{{ error }}</strong></p>
{% endfor %}
{% endif %}

View File

@@ -0,0 +1,17 @@
{% load crispy_forms_field %}
<div{% if div.css_id %} id="{{ div.css_id }}"{% endif %} class="control-group{% if form_show_errors and field.errors %} error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}{% if div.css_class %} {{ div.css_class }}{% endif %}" {{ div.flat_attrs|safe }}>
{% if field.label and form_show_labels %}
<label for="{{ field.id_for_label }}" class="control-label{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
<div class="controls">
<div class="input-append">
{% crispy_field field %}
{{ buttons|safe }}
</div>
{% include 'bootstrap/layout/help_text_and_errors.html' %}
</div>
</div>

View File

@@ -0,0 +1,6 @@
<fieldset {% if fieldset.css_id %}id="{{ fieldset.css_id }}"{% endif %}
{% if fieldset.css_class or form_style %}class="{{ fieldset.css_class }} {{ form_style }}"{% endif %}
{{ fieldset.flat_attrs|safe }}>
{% if legend %}<legend>{{ legend|safe }}</legend>{% endif %}
{{ fields|safe }}
</fieldset>

View File

@@ -0,0 +1,3 @@
<div{% if formactions.attrs %} {{ formactions.flat_attrs|safe }}{% endif %} class="form-actions">
{{ fields_output|safe }}
</div>

View File

@@ -0,0 +1,7 @@
{% if field.help_text %}
{% if help_text_inline %}
<span id="hint_{{ field.auto_id }}" class="help-inline">{{ field.help_text|safe }}</span>
{% else %}
<p id="hint_{{ field.auto_id }}" class="help-block">{{ field.help_text|safe }}</p>
{% endif %}
{% endif %}

View File

@@ -0,0 +1,13 @@
{% if help_text_inline and not error_text_inline %}
{% include 'bootstrap/layout/help_text.html' %}
{% endif %}
{% if error_text_inline %}
{% include 'bootstrap/layout/field_errors.html' %}
{% else %}
{% include 'bootstrap/layout/field_errors_block.html' %}
{% endif %}
{% if not help_text_inline %}
{% include 'bootstrap/layout/help_text.html' %}
{% endif %}

View File

@@ -0,0 +1,27 @@
{% load crispy_forms_field %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field.label %}
<label for="{{ field.id_for_label }}"{% if labelclass %} class="{{ labelclass }}"{% endif %}>
{% endif %}
{% if field|is_checkbox %}
{% crispy_field field %}
{% endif %}
{% if field.label %}
{{ field.label }}
{% endif %}
{% if not field|is_checkbox %}
{% crispy_field field %}
{% endif %}
{% if field.label %}
</label>
{% endif %}
{% endif %}

View File

@@ -0,0 +1,24 @@
{% load crispy_forms_field %}
{% if field.is_hidden %}
{{ field }}
{% else %}
<div id="div_{{ field.auto_id }}" class="control-group{% if form_show_errors and field.errors %} error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
{% if field.label and form_show_labels %}
<label for="{{ field.id_for_label }}" class="control-label{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
<div class="controls">
<div class="{% if crispy_prepended_text %}input-prepend{% endif %} {% if crispy_appended_text %}input-append{% endif %}">
{% if crispy_prepended_text %}<span class="{% if not field|is_select %}add-on{% endif %}{% if active %} active{% endif %}">{{ crispy_prepended_text|safe }}</span>{% endif %}
{% crispy_field field %}
{% if crispy_appended_text %}<span class="{% if not field|is_select %}add-on{% endif %}{% if active %} active{% endif %}">{{ crispy_appended_text|safe }}</span>{% endif %}
</div>
{% include 'bootstrap/layout/help_text_and_errors.html' %}
</div>
</div>
{% endif %}

View File

@@ -0,0 +1,14 @@
{% load crispy_forms_filters %}
{% load l10n %}
<div class="controls"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}>
{% include 'bootstrap/layout/field_errors_block.html' %}
{% for choice in field.field.choices %}
<label for="id_{{ field.html_name }}_{{ forloop.counter }}" class="radio{% if inline_class %} {{ inline_class }}{% endif %}">
<input type="radio"{% if choice.0|stringformat:"s" == field.value|default_if_none:""|stringformat:"s" %} checked="checked"{% endif %} name="{{ field.html_name }}" id="id_{{ field.html_name }}_{{ forloop.counter }}" value="{{ choice.0|unlocalize }}" {{ field.field.widget.attrs|flatatt }}>{{ choice.1|unlocalize }}
</label>
{% endfor %}
{% include 'bootstrap/layout/help_text.html' %}
</div>

View File

@@ -0,0 +1,14 @@
{% if field.is_hidden %}
{{ field }}
{% else %}
<div id="div_{{ field.auto_id }}" class="control-group{% if form_show_errors and field.errors %} error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
{% if field.label %}
<label for="{{ field.auto_id }}" class="control-label{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
{% include 'bootstrap/layout/radioselect.html' %}
</div>
{% endif %}

View File

@@ -0,0 +1,3 @@
<div {% if div.css_id %}id="{{ div.css_id }}"{% endif %} class="row {{ div.css_class|default:'' }}" {{ div.flat_attrs|safe }}>
{{ fields|safe }}
</div>

View File

@@ -0,0 +1 @@
<li class="tab-pane{% if 'active' in link.css_class %} active{% endif %}"><a href="#{{ link.css_id }}" data-toggle="tab">{{ link.name|capfirst }}{% if tab.errors %}!{% endif %}</a></li>

View File

@@ -0,0 +1,6 @@
<ul{% if tabs.css_id %} id="{{ tabs.css_id }}"{% endif %} class="nav nav-tabs">
{{ links|safe }}
</ul>
<div class="tab-content">
{{ content|safe }}
</div>

View File

@@ -0,0 +1,7 @@
<div id="div_{{ field.auto_id }}" class="control-group{% if form_show_errors and field.errors %} error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
<div class="control-label{% if field.field.required %} requiredField{% endif %}">{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}</div>
<div class="controls">
<span {{ flat_attrs|safe }}>{% if field.value %}{{ field.value }}{% endif %}</span>
{% include 'bootstrap/layout/help_text.html' %}
</div>
</div>

View File

@@ -0,0 +1,62 @@
{% load crispy_forms_tags %}
{% load crispy_forms_utils %}
{% load crispy_forms_field %}
{% specialspaceless %}
{% if formset_tag %}
<form {{ flat_attrs|safe }} method="{{ form_method }}" {% if formset.is_multipart %} enctype="multipart/form-data"{% endif %}>
{% endif %}
{% if formset_method|lower == 'post' and not disable_csrf %}
{% csrf_token %}
{% endif %}
<div>
{{ formset.management_form|crispy }}
</div>
<table{% if form_id %} id="{{ form_id }}_table"{% endif%} class="table table-striped table-condensed">
<thead>
{% if formset.readonly and not formset.queryset.exists %}
{% else %}
<tr>
{% for field in formset.forms.0 %}
{% if field.label and not field.is_hidden %}
<th for="{{ field.auto_id }}" class="control-label {% if field.field.required and not field|is_checkbox %}requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required and not field|is_checkbox %}<span class="asteriskField">*</span>{% endif %}
</th>
{% endif %}
{% endfor %}
</tr>
{% endif %}
</thead>
<tbody>
<tr class="hidden empty-form">
{% for field in formset.empty_form %}
{% include 'bootstrap/field.html' with tag="td" form_show_labels=False %}
{% endfor %}
</tr>
{% for form in formset %}
{% if form_show_errors and not form.is_extra %}
{% include "bootstrap/errors.html" %}
{% endif %}
<tr>
{% for field in form %}
{% include 'bootstrap/field.html' with tag="td" form_show_labels=False %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% if inputs %}
<div class="form-actions">
{% for input in inputs %}
{% include "bootstrap/layout/baseinput.html" %}
{% endfor %}
</div>
{% endif %}
{% if formset_tag %}</form>{% endif %}
{% endspecialspaceless %}

View File

@@ -0,0 +1,11 @@
{% load crispy_forms_utils %}
{% specialspaceless %}
{% if include_media %}{{ form.media }}{% endif %}
{% if form_show_errors %}
{% include "bootstrap/errors.html" %}
{% endif %}
{% for field in form %}
{% include field_template %}
{% endfor %}
{% endspecialspaceless %}

View File

@@ -0,0 +1,8 @@
{% with formset.management_form as form %}
{% include 'bootstrap/uni_form.html' %}
{% endwith %}
{% for form in formset %}
<div class="multiField">
{% include 'bootstrap/uni_form.html' %}
</div>
{% endfor %}

View File

@@ -0,0 +1,19 @@
{% load crispy_forms_utils %}
{% specialspaceless %}
{% if form_tag %}<form {{ flat_attrs|safe }} method="{{ form_method }}" {% if form.is_multipart %} enctype="multipart/form-data"{% endif %}>{% endif %}
{% if form_method|lower == 'post' and not disable_csrf %}
{% csrf_token %}
{% endif %}
{% include "bootstrap/display_form.html" %}
{% if inputs %}
<div class="form-actions">
{% for input in inputs %}
{% include "bootstrap/layout/baseinput.html" %}
{% endfor %}
</div>
{% endif %}
{% if form_tag %}</form>{% endif %}
{% endspecialspaceless %}

View File

@@ -0,0 +1,30 @@
{% load crispy_forms_tags %}
{% load crispy_forms_utils %}
{% specialspaceless %}
{% if formset_tag %}
<form {{ flat_attrs|safe }} method="{{ form_method }}" {% if formset.is_multipart %} enctype="multipart/form-data"{% endif %}>
{% endif %}
{% if formset_method|lower == 'post' and not disable_csrf %}
{% csrf_token %}
{% endif %}
<div>
{{ formset.management_form|crispy }}
</div>
{% include "bootstrap/errors_formset.html" %}
{% for form in formset %}
{% include "bootstrap/display_form.html" %}
{% endfor %}
{% if inputs %}
<div class="form-actions">
{% for input in inputs %}
{% include "bootstrap/layout/baseinput.html" %}
{% endfor %}
</div>
{% endif %}
{% if formset_tag %}</form>{% endif %}
{% endspecialspaceless %}

View File

@@ -0,0 +1,12 @@
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#{{ div.data_parent }}" href="#{{ div.css_id }}">{{ div.name }}</a>
</h4>
</div>
<div id="{{ div.css_id }}" class="panel-collapse collapse{% if div.active %} in{% endif %}" >
<div class="panel-body">
{{ fields|safe }}
</div>
</div>
</div>

View File

@@ -0,0 +1,3 @@
<div class="panel-group" id="{{ accordion.css_id }}">
{{ content|safe }}
</div>

View File

@@ -0,0 +1,22 @@
{% for fieldset in form.fieldsets %}
<fieldset class="fieldset-{{ forloop.counter }} {{ fieldset.classes }}">
{% if fieldset.legend %}
<legend>{{ fieldset.legend }}</legend>
{% endif %}
{% if fieldset.description %}
<p class="description">{{ fieldset.description }}</p>
{% endif %}
{% for field in fieldset %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% include "bootstrap3/field.html" %}
{% endif %}
{% endfor %}
{% if not forloop.last or not fieldset_open %}
</fieldset>
{% endif %}
{% endfor %}

View File

@@ -0,0 +1,9 @@
{% if form.form_html %}
{% if include_media %}{{ form.media }}{% endif %}
{% if form_show_errors %}
{% include "bootstrap3/errors.html" %}
{% endif %}
{{ form.form_html }}
{% else %}
{% include "bootstrap3/uni_form.html" %}
{% endif %}

View File

@@ -0,0 +1,8 @@
{% if form.non_field_errors %}
<div class="alert alert-block alert-danger">
{% if form_error_title %}<h4 class="alert-heading">{{ form_error_title }}</h4>{% endif %}
<ul>
{{ form.non_field_errors|unordered_list }}
</ul>
</div>
{% endif %}

View File

@@ -0,0 +1,9 @@
{% if formset.non_form_errors %}
<div class="alert alert-block alert-danger">
{% if formset_error_title %}<h4 class="alert-heading">{{ formset_error_title }}</h4>{% endif %}
<ul>
{{ formset.non_form_errors|unordered_list }}
</ul>
</div>
{% endif %}

View File

@@ -0,0 +1,48 @@
{% load crispy_forms_field %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field|is_checkbox %}
<div class="form-group">
{% if label_class %}
<div class="controls {% for offset in bootstrap_checkbox_offsets %}{{ offset }} {% endfor %}{{ field_class }}">
{% endif %}
{% endif %}
<{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" {% if not field|is_checkbox %}class="form-group{% else %}class="checkbox{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if form_show_errors%}{% if field.errors %} has-error{% endif %}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
{% if field.label and not field|is_checkbox and form_show_labels %}
<label for="{{ field.id_for_label }}" class="control-label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
{% if field|is_checkboxselectmultiple %}
{% include 'bootstrap3/layout/checkboxselectmultiple.html' %}
{% endif %}
{% if field|is_radioselect %}
{% include 'bootstrap3/layout/radioselect.html' %}
{% endif %}
{% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
{% if field|is_checkbox and form_show_labels %}
<label for="{{ field.id_for_label }}" class="{% if field.field.required %} requiredField{% endif %}">
{% crispy_field field %}
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% include 'bootstrap3/layout/help_text_and_errors.html' %}
{% else %}
<div class="controls {{ field_class }}">
{% crispy_field field %}
{% include 'bootstrap3/layout/help_text_and_errors.html' %}
</div>
{% endif %}
{% endif %}
</{% if tag %}{{ tag }}{% else %}div{% endif %}>
{% if field|is_checkbox %}
{% if label_class %}
</div>
{% endif %}
</div>
{% endif %}
{% endif %}

View File

@@ -0,0 +1,13 @@
{% if inputs %}
<div class="form-group">
{% if label_class %}
<div class="aab controls {{ label_class }}"></div>
{% endif %}
<div class="controls {{ field_class }}">
{% for input in inputs %}
{% include "bootstrap3/layout/baseinput.html" %}
{% endfor %}
</div>
</div>
{% endif %}

View File

@@ -0,0 +1,4 @@
<div{% if alert.css_id %} id="{{ alert.css_id }}"{% endif %}{% if alert.css_class %} class="{{ alert.css_class }}"{% endif %}>
{% if dismiss %}<button type="button" class="close" data-dismiss="alert">&times;</button>{% endif %}
{{ content|safe }}
</div>

View File

@@ -0,0 +1,9 @@
<input type="{{ input.input_type }}"
name="{% if input.name|wordcount > 1 %}{{ input.name|slugify }}{% else %}{{ input.name }}{% endif %}"
value="{{ input.value }}"
{% if input.input_type != "hidden" %}
class="{{ input.field_classes }}"
id="{% if input.id %}{{ input.id }}{% else %}{{ input.input_type }}-id-{{ input.name|slugify }}{% endif %}"
{% endif %}
{{ input.flat_attrs|safe }}
/>

View File

@@ -0,0 +1 @@
<button {{ button.flat_attrs|safe }}>{{ button.content|safe }}</button>

View File

@@ -0,0 +1,4 @@
<div {% if buttonholder.css_id %}id="{{ buttonholder.css_id }}"{% endif %}
class="buttonHolder{% if buttonholder.css_class %} {{ buttonholder.css_class }}{% endif %}">
{{ fields_output|safe }}
</div>

View File

@@ -0,0 +1,17 @@
{% load crispy_forms_filters %}
{% load l10n %}
<div class="controls {{ field_class }}"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}>
{% include 'bootstrap3/layout/field_errors_block.html' %}
{% for choice in field.field.choices %}
{% if not inline_class %}<div class="checkbox">{% endif %}
<label class="{% if inline_class %}checkbox-{{ inline_class }}{% endif %}" for="id_{{ field.html_name }}_{{ forloop.counter }}">
<input type="checkbox"{% if choice.0 in field.value or choice.0|stringformat:"s" in field.value or choice.0|stringformat:"s" == field.value|default_if_none:""|stringformat:"s" %} checked="checked"{% endif %} name="{{ field.html_name }}" id="id_{{ field.html_name }}_{{ forloop.counter }}" value="{{ choice.0|unlocalize }}" {{ field.field.widget.attrs|flatatt }}>{{ choice.1|unlocalize }}
</label>
{% if not inline_class %}</div>{% endif %}
{% endfor %}
{% include 'bootstrap3/layout/help_text.html' %}
</div>

View File

@@ -0,0 +1,14 @@
{% if field.is_hidden %}
{{ field }}
{% else %}
<div id="div_{{ field.auto_id }}" class="form-group{% if form_show_errors and field.errors %} has-error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
{% if field.label %}
<label for="{{ field.auto_id }}" class="control-label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
{% include 'bootstrap3/layout/checkboxselectmultiple.html' %}
</div>
{% endif %}

View File

@@ -0,0 +1,3 @@
<div {% if div.css_id %}id="{{ div.css_id }}"{% endif %} class="formColumn {{ div.css_class|default:'' }}" {{ div.flat_attrs|safe }}>
{{ fields|safe }}
</div>

View File

@@ -0,0 +1,4 @@
<div {% if div.css_id %}id="{{ div.css_id }}"{% endif %}
{% if div.css_class %}class="{{ div.css_class }}"{% endif %} {{ div.flat_attrs|safe }}>
{{ fields|safe }}
</div>

View File

@@ -0,0 +1,5 @@
{% if form_show_errors and field.errors %}
{% for error in field.errors %}
<span id="error_{{ forloop.counter }}_{{ field.auto_id }}" class="help-block"><strong>{{ error }}</strong></span>
{% endfor %}
{% endif %}

View File

@@ -0,0 +1,5 @@
{% if form_show_errors and field.errors %}
{% for error in field.errors %}
<p id="error_{{ forloop.counter }}_{{ field.auto_id }}" class="help-block"><strong>{{ error }}</strong></p>
{% endfor %}
{% endif %}

View File

@@ -0,0 +1,17 @@
{% load crispy_forms_field %}
<div{% if div.css_id %} id="{{ div.css_id }}"{% endif %} class="form-group{% if form_show_errors and field.errors %} has-error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}{% if div.css_class %} {{ div.css_class }}{% endif %}" {{ div.flat_attrs|safe }}>
{% if field.label and form_show_labels %}
<label for="{{ field.id_for_label }}" class="control-label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
<div class="controls {{ field_class }}">
<div class="input-group">
{% crispy_field field %}
<span class="input-group-btn{% if active %} active{% endif %}{% if input_size %} {{ input_size }}{% endif %}">{{ buttons|safe }}</span>
</div>
{% include 'bootstrap3/layout/help_text_and_errors.html' %}
</div>
</div>

View File

@@ -0,0 +1,6 @@
<fieldset {% if fieldset.css_id %}id="{{ fieldset.css_id }}"{% endif %}
{% if fieldset.css_class or form_style %}class="{{ fieldset.css_class }} {{ form_style }}"{% endif %}
{{ fieldset.flat_attrs|safe }}>
{% if legend %}<legend>{{ legend|safe }}</legend>{% endif %}
{{ fields|safe }}
</fieldset>

View File

@@ -0,0 +1,9 @@
<div{% if formactions.attrs %} {{ formactions.flat_attrs|safe }}{% endif %} class="form-group">
{% if label_class %}
<div class="aab controls {{ label_class }}"></div>
{% endif %}
<div class="controls {{ field_class }}">
{{ fields_output|safe }}
</div>
</div>

View File

@@ -0,0 +1,7 @@
{% if field.help_text %}
{% if help_text_inline %}
<span id="hint_{{ field.auto_id }}" class="help-block">{{ field.help_text|safe }}</span>
{% else %}
<div id="hint_{{ field.auto_id }}" class="help-block">{{ field.help_text|safe }}</div>
{% endif %}
{% endif %}

View File

@@ -0,0 +1,13 @@
{% if help_text_inline and not error_text_inline %}
{% include 'bootstrap3/layout/help_text.html' %}
{% endif %}
{% if error_text_inline %}
{% include 'bootstrap3/layout/field_errors.html' %}
{% else %}
{% include 'bootstrap3/layout/field_errors_block.html' %}
{% endif %}
{% if not help_text_inline %}
{% include 'bootstrap3/layout/help_text.html' %}
{% endif %}

View File

@@ -0,0 +1,21 @@
{% load crispy_forms_field %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field|is_checkbox %}
<div id="div_{{ field.auto_id }}" class="checkbox{% if wrapper_class %} {{ wrapper_class }}{% endif %}">
<label for="{{ field.id_for_label }}" class="{% if field.field.required %} requiredField{% endif %}">
{% crispy_field field 'class' 'checkbox' %}
{{ field.label|safe }}
</label>
</div>
{% else %}
<div id="div_{{ field.auto_id }}" class="form-group{% if wrapper_class %} {{ wrapper_class }}{% endif %}">
<label for="{{ field.id_for_label }}" class="sr-only{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}
</label>
{% crispy_field field 'placeholder' field.label %}
</div>
{% endif %}
{% endif %}

View File

@@ -0,0 +1,25 @@
<div {% if multifield.css_id or errors %}id="{{ multifield.css_id }}"{% endif %}
{% if multifield.css_class %}class="{{ multifield.css_class }}"{% endif %}
{{ multifield.flat_attrs|safe }}>
{% if form_show_errors %}
<div class="alert alert-danger" role="alert">
{% for field in multifield.bound_fields %}
{% if field.errors %}
{% for error in field.errors %}
<p id="error_{{ forloop.counter }}_{{ field.auto_id }}">{{ error }}</p>
{% endfor %}
{% endif %}
{% endfor %}
</div>
{% endif %}
{% if multifield.label_html %}
<p {% if multifield.label_class %}class="{{ multifield.label_class }}"{% endif %}>{{ multifield.label_html|safe }}</p>
{% endif %}
<div class="multiField">
{{ fields_output|safe }}
</div>
</div>

View File

@@ -0,0 +1,24 @@
{% load crispy_forms_field %}
{% if field.is_hidden %}
{{ field }}
{% else %}
<div id="div_{{ field.auto_id }}" class="form-group{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if form_show_errors and field.errors %} has-error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
{% if field.label and form_show_labels %}
<label for="{{ field.id_for_label }}" class="control-label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
<div class="controls {{ field_class }}">
<div class="input-group">
{% if crispy_prepended_text %}<span class="input-group-addon{% if active %} active{% endif %}{% if input_size %} {{ input_size }}{% endif %}">{{ crispy_prepended_text|safe }}</span>{% endif %}
{% crispy_field field %}
{% if crispy_appended_text %}<span class="input-group-addon{% if active %} active{% endif %}{% if input_size %} {{ input_size }}{% endif %}">{{ crispy_appended_text|safe }}</span>{% endif %}
</div>
{% include 'bootstrap3/layout/help_text_and_errors.html' %}
</div>
</div>
{% endif %}

View File

@@ -0,0 +1,16 @@
{% load crispy_forms_filters %}
{% load l10n %}
<div class="controls {{ field_class }}"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}>
{% include 'bootstrap3/layout/field_errors_block.html' %}
{% for choice in field.field.choices %}
{% if not inline_class %}<div class="radio">{% endif %}
<label for="id_{{ field.html_name }}_{{ forloop.counter }}" class="{% if inline_class %}radio-{{ inline_class }}{% endif %}">
<input type="radio"{% if choice.0|stringformat:"s" == field.value|default_if_none:""|stringformat:"s" %} checked="checked"{% endif %} name="{{ field.html_name }}" id="id_{{ field.html_name }}_{{ forloop.counter }}" value="{{ choice.0|unlocalize }}" {{ field.field.widget.attrs|flatatt }}>{{ choice.1|unlocalize }}
</label>
{% if not inline_class %}</div>{% endif %}
{% endfor %}
{% include 'bootstrap3/layout/help_text.html' %}
</div>

View File

@@ -0,0 +1,14 @@
{% if field.is_hidden %}
{{ field }}
{% else %}
<div id="div_{{ field.auto_id }}" class="form-group{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if form_show_errors and field.errors %} has-error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
{% if field.label %}
<label for="{{ field.auto_id }}" class="control-label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
{% include 'bootstrap3/layout/radioselect.html' %}
</div>
{% endif %}

View File

@@ -0,0 +1,3 @@
<div {% if div.css_id %}id="{{ div.css_id }}"{% endif %} class="row {{ div.css_class|default:'' }}" {{ div.flat_attrs|safe }}>
{{ fields|safe }}
</div>

View File

@@ -0,0 +1 @@
<li class="tab-pane{% if 'active' in link.css_class %} active{% endif %}"><a href="#{{ link.css_id }}" data-toggle="tab">{{ link.name|capfirst }}{% if tab.errors %}!{% endif %}</a></li>

View File

@@ -0,0 +1,6 @@
<ul{% if tabs.css_id %} id="{{ tabs.css_id }}"{% endif %} class="nav nav-tabs">
{{ links|safe }}
</ul>
<div class="tab-content panel-body">
{{ content|safe }}
</div>

View File

@@ -0,0 +1,10 @@
{% load crispy_forms_field %}
<div id="div_{{ field.auto_id }}" class="form-group{% if form_show_errors and field.errors %} error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
<label class="control-label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}</label>
<div class="controls {{ field_class }}">
{% crispy_field field 'disabled' 'disabled' %}
{% include 'bootstrap3/layout/help_text.html' %}
</div>
</div>

View File

@@ -0,0 +1,39 @@
{% load crispy_forms_field %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field|is_checkbox %}
{% if field.errors %}<div class="has-error">{% endif %}
<div class="checkbox">
{% if field.label %}
<label for="{{ field.id_for_label }}"{% if labelclass %} class="{{ labelclass }}"{% endif %}>
{% endif %}
{% crispy_field field %}
{{ field.label }}
{% if field.label %}
</label>
{% endif %}
{% if field.help_text %}
<p id="help_{{ field.auto_id }}" class="help-block">{{ field.help_text|safe }}</span>
{% endif %}
</div>
{% if field.errors %}</div>{% endif %}
{% else %}
<div class="form-group {% if field.errors %}has-error{% endif %}">
{% if field.label %}
<label class="control-label" for="{{ field.id_for_label }}"{% if labelclass %} class="{{ labelclass }}"{% endif %}>
{{ field.label }}
</label>
{% endif %}
{% crispy_field field %}
{% if field.help_text %}
<span id="help_{{ field.auto_id }}" class="help-block">{{ field.help_text|safe }}</span>
{% endif %}
</div>
{% endif %}
{% endif %}

View File

@@ -0,0 +1,57 @@
{% load crispy_forms_tags %}
{% load crispy_forms_utils %}
{% load crispy_forms_field %}
{% specialspaceless %}
{% if formset_tag %}
<form {{ flat_attrs|safe }} method="{{ form_method }}" {% if formset.is_multipart %} enctype="multipart/form-data"{% endif %}>
{% endif %}
{% if formset_method|lower == 'post' and not disable_csrf %}
{% csrf_token %}
{% endif %}
<div>
{{ formset.management_form|crispy }}
</div>
<table{% if form_id %} id="{{ form_id }}_table"{% endif%} class="table table-striped table-condensed">
<thead>
{% if formset.readonly and not formset.queryset.exists %}
{% else %}
<tr>
{% for field in formset.forms.0 %}
{% if field.label and not field.is_hidden %}
<th for="{{ field.auto_id }}" class="control-label {% if field.field.required %}requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required and not field|is_checkbox %}<span class="asteriskField">*</span>{% endif %}
</th>
{% endif %}
{% endfor %}
</tr>
{% endif %}
</thead>
<tbody>
<tr class="hidden empty-form">
{% for field in formset.empty_form %}
{% include 'bootstrap3/field.html' with tag="td" form_show_labels=False %}
{% endfor %}
</tr>
{% for form in formset %}
{% if form_show_errors and not form.is_extra %}
{% include "bootstrap3/errors.html" %}
{% endif %}
<tr>
{% for field in form %}
{% include 'bootstrap3/field.html' with tag="td" form_show_labels=False %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% include "bootstrap3/inputs.html" %}
{% if formset_tag %}</form>{% endif %}
{% endspecialspaceless %}

View File

@@ -0,0 +1,11 @@
{% load crispy_forms_utils %}
{% specialspaceless %}
{% if include_media %}{{ form.media }}{% endif %}
{% if form_show_errors %}
{% include "bootstrap3/errors.html" %}
{% endif %}
{% for field in form %}
{% include field_template %}
{% endfor %}
{% endspecialspaceless %}

View File

@@ -0,0 +1,8 @@
{% with formset.management_form as form %}
{% include 'bootstrap3/uni_form.html' %}
{% endwith %}
{% for form in formset %}
<div class="multiField">
{% include 'bootstrap3/uni_form.html' %}
</div>
{% endfor %}

View File

@@ -0,0 +1,14 @@
{% load crispy_forms_utils %}
{% specialspaceless %}
{% if form_tag %}<form {{ flat_attrs|safe }} method="{{ form_method }}" {% if form.is_multipart %} enctype="multipart/form-data"{% endif %}>{% endif %}
{% if form_method|lower == 'post' and not disable_csrf %}
{% csrf_token %}
{% endif %}
{% include "bootstrap3/display_form.html" %}
{% include "bootstrap3/inputs.html" %}
{% if form_tag %}</form>{% endif %}
{% endspecialspaceless %}

View File

@@ -0,0 +1,30 @@
{% load crispy_forms_tags %}
{% load crispy_forms_utils %}
{% specialspaceless %}
{% if formset_tag %}
<form {{ flat_attrs|safe }} method="{{ form_method }}" {% if formset.is_multipart %} enctype="multipart/form-data"{% endif %}>
{% endif %}
{% if formset_method|lower == 'post' and not disable_csrf %}
{% csrf_token %}
{% endif %}
<div>
{{ formset.management_form|crispy }}
</div>
{% include "bootstrap3/errors_formset.html" %}
{% for form in formset %}
{% include "bootstrap3/display_form.html" %}
{% endfor %}
{% if inputs %}
<div class="form-actions">
{% for input in inputs %}
{% include "bootstrap3/layout/baseinput.html" %}
{% endfor %}
</div>
{% endif %}
{% if formset_tag %}</form>{% endif %}
{% endspecialspaceless %}

View File

@@ -0,0 +1,17 @@
<div class="card mb-2">
<div class="card-header" role="tab">
<h5 class="mb-0">
<a data-toggle="collapse" href="#{{ div.css_id }}" aria-expanded="true"
aria-controls="{{ div.css_id }}">
{{ div.name }}
</a>
</h5>
</div>
<div id="{{ div.css_id }}" class="collapse{% if div.active %} show{% endif %}" role="tabpanel"
aria-labelledby="{{ div.css_id }}" data-parent="#accordion">
<div class="card-body">
{{ fields|safe }}
</div>
</div>
</div>

View File

@@ -0,0 +1,3 @@
<div id="accordion" role="tablist">
{{ content|safe }}
</div>

View File

@@ -0,0 +1,22 @@
{% for fieldset in form.fieldsets %}
<fieldset class="fieldset-{{ forloop.counter }} {{ fieldset.classes }}">
{% if fieldset.legend %}
<legend>{{ fieldset.legend }}</legend>
{% endif %}
{% if fieldset.description %}
<p class="description">{{ fieldset.description }}</p>
{% endif %}
{% for field in fieldset %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% include "bootstrap4/field.html" %}
{% endif %}
{% endfor %}
{% if not forloop.last or not fieldset_open %}
</fieldset>
{% endif %}
{% endfor %}

View File

@@ -0,0 +1,9 @@
{% if form.form_html %}
{% if include_media %}{{ form.media }}{% endif %}
{% if form_show_errors %}
{% include "bootstrap4/errors.html" %}
{% endif %}
{{ form.form_html }}
{% else %}
{% include "bootstrap4/uni_form.html" %}
{% endif %}

View File

@@ -0,0 +1,8 @@
{% if form.non_field_errors %}
<div class="alert alert-block alert-danger">
{% if form_error_title %}<h4 class="alert-heading">{{ form_error_title }}</h4>{% endif %}
<ul class="m-0">
{{ form.non_field_errors|unordered_list }}
</ul>
</div>
{% endif %}

View File

@@ -0,0 +1,9 @@
{% if formset.non_form_errors %}
<div class="alert alert-block alert-danger">
{% if formset_error_title %}<h4 class="alert-heading">{{ formset_error_title }}</h4>{% endif %}
<ul class="m-0">
{{ formset.non_form_errors|unordered_list }}
</ul>
</div>
{% endif %}

View File

@@ -0,0 +1,54 @@
{% load crispy_forms_field %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field|is_checkbox %}
<div class="form-group{% if 'form-horizontal' in form_class %} row{% endif %}">
{% if label_class %}
<div class="{% for offset in bootstrap_checkbox_offsets %}{{ offset }} {% endfor %}{{ field_class }}">
{% endif %}
{% endif %}
<{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" class="{% if not field|is_checkbox %}form-group{% if 'form-horizontal' in form_class %} row{% endif %}{% else %}{%if use_custom_control%}custom-control custom-checkbox{% else %}form-check{% endif %}{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
{% if field.label and not field|is_checkbox and form_show_labels %}
<label for="{{ field.id_for_label }}" class="{% if 'form-horizontal' in form_class %}col-form-label {% endif %}{{ label_class }}{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
{% if field|is_checkboxselectmultiple %}
{% include 'bootstrap4/layout/checkboxselectmultiple.html' %}
{% endif %}
{% if field|is_radioselect %}
{% include 'bootstrap4/layout/radioselect.html' %}
{% endif %}
{% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
{% if field|is_checkbox and form_show_labels %}
{%if use_custom_control%}
{% crispy_field field 'class' 'custom-control-input' %}
{% else %}
{% crispy_field field 'class' 'form-check-input' %}
{% endif %}
<label for="{{ field.id_for_label }}" class="{%if use_custom_control%}custom-control-label{% else %}form-check-label{% endif %}{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% include 'bootstrap4/layout/help_text_and_errors.html' %}
{% elif field|is_file and use_custom_control %}
{% include 'bootstrap4/layout/field_file.html' %}
{% else %}
<div class="{{ field_class }}">
{% crispy_field field %}
{% include 'bootstrap4/layout/help_text_and_errors.html' %}
</div>
{% endif %}
{% endif %}
</{% if tag %}{{ tag }}{% else %}div{% endif %}>
{% if field|is_checkbox %}
{% if label_class %}
</div>
{% endif %}
</div>
{% endif %}
{% endif %}

View File

@@ -0,0 +1,13 @@
{% if inputs %}
<div class="form-group{% if 'form-horizontal' in form_class %} row{% endif %}">
{% if label_class %}
<div class="aab {{ label_class }}"></div>
{% endif %}
<div class="{{ field_class }}">
{% for input in inputs %}
{% include "bootstrap4/layout/baseinput.html" %}
{% endfor %}
</div>
</div>
{% endif %}

View File

@@ -0,0 +1,4 @@
<div{% if alert.css_id %} id="{{ alert.css_id }}"{% endif %}{% if alert.css_class %} class="{{ alert.css_class }}"{% endif %}>
{% if dismiss %}<button type="button" class="close" data-dismiss="alert">&times;</button>{% endif %}
{{ content|safe }}
</div>

View File

@@ -0,0 +1,9 @@
<input type="{{ input.input_type }}"
name="{% if input.name|wordcount > 1 %}{{ input.name|slugify }}{% else %}{{ input.name }}{% endif %}"
value="{{ input.value }}"
{% if input.input_type != "hidden" %}
class="{{ input.field_classes }}"
id="{% if input.id %}{{ input.id }}{% else %}{{ input.input_type }}-id-{{ input.name|slugify }}{% endif %}"
{% endif %}
{{ input.flat_attrs|safe }}
/>

Some files were not shown because too many files have changed in this diff Show More