A Torchbox-flavoured template pack for django-crispy-forms, adapted from crispy-forms-gds
Project description
Torchbox Forms
A Torchbox-flavoured template pack for django-crispy-forms, adapted from crispy-forms-gds.
Out of the box, forms created with tbxforms
will look like the
GOV.UK Design System, though many
variables can be customised.
Contents
Installation
You must install both a Python package and an NPM package.
Install the Python package
Install using pip:
pip install tbxforms
Add django-crispy-forms
and tbxforms
to your installed apps:
INSTALLED_APPS = [
...
'crispy_forms', # django-crispy-forms
'tbxforms',
]
Now add the following settings to tell django-crispy-forms
to use this theme:
CRISPY_ALLOWED_TEMPLATE_PACKS = ["tbx"]
CRISPY_TEMPLATE_PACK = "tbx"
Install the NPM package
Install using NPM:
npm install tbxforms
Instantiate your forms:
import TbxForms from 'tbxforms';
document.addEventListener('DOMContentLoaded', () => {
for (const form of document.querySelectorAll(TbxForms.selector())) {
new TbxForms(form);
}
});
Import the styles into your project, either as CSS:
// Either as CSS without any customisations:
@use 'node_modules/tbxforms/style.css';
Or as Sass, to customise variables:
// Or as Sass, with variables to customise:
@use 'node_modules/tbxforms/tbxforms.scss' with (
$tbxforms-error-colour: #f00,
$tbxforms-text-colour: #000,
);
Variables can also be defined in a centralised variables SCSS file, too.
See tbxforms/static/sass/abstracts/_variables.scss for customisable variables.
Usage
Create a Django form
from tbxforms.forms import BaseForm as TbxFormsBaseForm
class ExampleForm(TbxFormsBaseForm, forms.Form):
# < Your field definitions >
class ExampleModelForm(TbxFormsBaseForm, forms.ModelForm):
# < Your field definitions and ModelForm config >
Create a Wagtail form
Two parts are required for this to work:
- Add a
helper
property to the Wagtail form - Instruct a Wagtail Page model to use the newly created form
Add a helper
property to the Wagtail form
from wagtail.contrib.forms.forms import BaseForm as WagtailBaseForm
from tbxforms.forms import BaseForm as TbxFormsBaseForm
class ExampleWagtailForm(TbxFormsBaseForm, WagtailBaseForm):
# Extend the `TbxFormsBaseForm.helper()` to add a submit button.
@property
def helper(self):
fh = super().helper
fh.add_input(
Button.primary(
name="submit",
type="submit",
value=_("Submit"),
)
)
return fh
Instruct a Wagtail Page model to use the newly created form
# -----------------------------------------------------------------------------
# in your forms definitions (e.g. forms.py)
from tbxforms.forms import BaseWagtailFormBuilder as TbxFormsBaseWagtailFormBuilder
from path.to.your.forms import ExampleWagtailForm
class WagtailFormBuilder(TbxFormsBaseWagtailFormBuilder):
def get_form_class(self):
return type(str("WagtailForm"), (ExampleWagtailForm,), self.formfields)
# -----------------------------------------------------------------------------
# in your page models (e.g. models.py)
from path.to.your.forms import WagtailFormBuilder
class ExampleFormPage(...):
...
form_builder = WagtailFormBuilder
...
Render a form
Just like Django Crispy Forms, you need to pass your form object to the
{% crispy ... %}
template tag, e.g.:
{% load crispy_forms_tags %}
{% crispy your_form %}
Customise a form's attributes (via the helper
property)
By default, every form that inherits from TbxFormsBaseForm
will have the following
attributes set:
html5_required = True
label_size = Size.MEDIUM
legend_size = Size.MEDIUM
form_error_title = _("There is a problem with your submission")
- Plus everything from django-crispy-forms' default attributes.
These can be overridden (and/or additional attributes from the above list defined) just like you would do with any other inherited class, e.g.:
class YourSexyForm(TbxFormsBaseForm, forms.Form):
@property
def helper(self):
fh = super().helper
fh.html5_required = False
fh.label_size = Size.SMALL
fh.form_error_title = _("Something's wrong, yo.")
return fh
Possible values for the label_size
and legend_size
:
SMALL
MEDIUM
(default)LARGE
EXTRA_LARGE
Conditionally-required fields
tbxforms
supports hiding/showing of fields and/or div
/fieldset
elements
based on the values of a given input field.
Field example:
class ExampleForm(TbxFormsBaseForm, forms.Form):
NEWSLETTER_CHOICES = (
Choice("yes", "Yes please", hint="Receive occasional email newsletters."),
Choice("no", "No thanks"),
)
newsletter_signup = forms.ChoiceField(
choices=NEWSLETTER_CHOICES
)
email = forms.EmailField(
widget=forms.EmailInput(required=False)
)
@staticmethod
def conditional_fields_to_show_as_required() -> [str]:
return [
"email", # Include any fields that should show as required to the user.
]
@property
def helper(self):
fh = super().helper
# Override what is rendered for this form.
fh.layout = Layout(
# Add our newsletter sign-up field.
Field("newsletter_signup"),
# Add our email field, and define the conditional 'show' logic.
Field(
"email",
data_conditional={
"field_name": "newsletter_signup", # Field to inspect.
"values": ["yes"], # Value(s) to cause this field to show.
},
),
)
return fh
def clean(self):
cleaned_data = super().clean()
newsletter_signup = cleaned_data.get("newsletter_signup")
email = cleaned_data.get("email")
# Assuming `form.helper.html5_required == True`, tbxforms will toggle the
# html5 'required' attribute when a conditionally-required field is shown,
# though it is recommended to also check the value in your clean() method.
if newsletter_signup == "yes" and not email:
raise ValidationError(
{
"email": _("This field is required."),
}
)
# The tbxforms JS will attempt to clear any redundant data upon submission,
# though it is recommended to also handle this in your clean() method.
elif newsletter_signup == "no" and email:
del cleaned_data['email']
return cleaned_data
Container example:
When you have multiple fields/elements that you want to show/hide together, you
can use the exact same data_conditional
definition as above but on a div
or
fieldset
element, e.g.:
Div(
HTML("<p>Some relevant text.</p>"),
Field("some_other_field"),
Field("email"),
data_conditional={
"field_name": "newsletter_signup",
"values": ["yes"],
},
),
Further reading
- Download the PyPi package
- Download the NPM package
- Learn more about Django Crispy Forms
- Learn more about Crispy Forms GDS
- Learn more about GOV.UK Design System
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
File details
Details for the file tbxforms-1.0.2.tar.gz
.
File metadata
- Download URL: tbxforms-1.0.2.tar.gz
- Upload date:
- Size: 38.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.5 CPython/3.7.9 Darwin/20.6.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0afe6fc033b01d768d4f60d195971d850647bc86112f1186b5dfba0ffd279975 |
|
MD5 | 313f210aa8171d4512b192bca87e2b7d |
|
BLAKE2b-256 | ed4c40b123d86a50ad5ddef50c4ae700ef3dad7c9d8ef580a0889047053a9a91 |
Provenance
File details
Details for the file tbxforms-1.0.2-py3-none-any.whl
.
File metadata
- Download URL: tbxforms-1.0.2-py3-none-any.whl
- Upload date:
- Size: 51.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.5 CPython/3.7.9 Darwin/20.6.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 89f8a4145326bf6eb871e96760cc8905b9324f4b0e60904f784241ac529ec00c |
|
MD5 | 7ff4901e6e8a6ad24159fd60246f6878 |
|
BLAKE2b-256 | b7addafac10824ab3804ade177f5ea8a9921df32a293e855d1244fa96852a612 |