Fieldsets¶
Learn how to organize your form fields in multiple fieldsets and have them rendered nicely.
Manual fieldsets¶
The first way to get fieldsets for organizing your form’s fields is using the
TapeformFieldset
directly. This is also the low-level approach with full
control of whats happening.
class MyForm(TapeformMixin, forms.Form):
field1 = forms.CharField()
field2 = forms.CharField()
field3 = forms.CharField()
field4 = forms.CharField(widget=forms.HiddenInput)
def first_fieldset(self):
return TapeformFieldset(self, fields=('field1', 'field2'), primary=True)
def second_fieldset(self):
return TapeformFieldset(self, exclude=('field1', 'field1'))
Note
You have to make sure that at least one fieldset is marked as your primary fieldsets. This is required because only the primary fieldset will render the non field errors and all hidden fields of the form.
The fieldsets can then be rendered using the form
template tag just like classic forms.
<form action="." method="post" >
{% csrf_token %}
<fieldset>
{% form form.first_fieldset %}
</fieldset>
<fieldset>
{% form form.second_fieldset %}
</fieldset>
<button type="submit">Submit</button>
</form>
Generated fieldsets¶
It might come to your mind that defining alle the fieldsets using methods is a bit to much boilerplate.
Because of this, django-tapeforms provides another Mixin you can use to make generation of fieldsets a lot easier.
Lets have a look on an example.
class MyForm(TapeformMixin, forms.Form):
field1 = forms.CharField()
field2 = forms.CharField()
field3 = forms.CharField()
field4 = forms.CharField(widget=forms.HiddenInput)
fieldsets = [
{'fields': ('field1', 'field2')},
{'exclude': ('field1', 'field2')}, # Render all remaining fields
]
Also, the template is simpler now.
<form action="." method="post" >
{% csrf_token %}
{% for fieldset in form.get_fieldsets %}
<fieldset>
{% form fieldset %}
</fieldset>
{% endfor %}
<button type="submit">Submit</button>
</form>
While the difference in code written might not be that big when rendering two fieldsets, imagine the difference when having lets say 7 oder 8 fieldsets.
As you can see, we don’t have to care for the primary flag anymore. The get_fieldsets
methods make sure that one fieldset is the primary fieldset (by default, the first fieldset
is marked as primary).
There are many methods in the TapeformFieldsetsMixin you can override to get your hands on the generation process (like selection the right fieldset class or manipulating the data which is used to instantiate the fieldset).
It is also possible to generate the fieldsets configuration on the fly by overriding
the get_fieldsets
method and pass a config to your super call.
class MyForm(TapeformMixin, forms.Form):
field1 = forms.CharField()
field2 = forms.CharField()
field3 = forms.CharField()
field4 = forms.CharField(widget=forms.HiddenInput)
def get_fieldsets(self):
# Geneate a fieldset for every form field. Why would one do that?
return super().get_fieldsets([
{'fields': (field.name,)}
for field in self.visible_fields()
])
Passing around additional data¶
In more compex setups you might want to pass around additional data. In our example we assume that we require a css class added to the fieldset element.
class MyForm(TapeformMixin, forms.Form):
field1 = forms.CharField()
field2 = forms.CharField()
field3 = forms.CharField()
field4 = forms.CharField(widget=forms.HiddenInput)
fieldsets = [{
'fields': ('field1', 'field2'),
'extra': {'css_class': 'my-class-foo'}
}, {
'exclude': ('field1', 'field2'),
'extra': {'css_class': 'my-class-bar'}
}]
<form action="." method="post" >
{% csrf_token %}
{% for fieldset in form.get_fieldsets %}
<fieldset class="{{ fieldset.extra.css_class }}">
{% form fieldset %}
</fieldset>
{% endfor %}
<button type="submit">Submit</button>
</form>
The extra key in the fieldset configuration is not checked in any way. Its just passed
around. You might use it to carry things in a dic
like in the example or push
a model instance to the template for further use.
Advanced usage¶
For a full overview of the methods TapeformFieldset and TapeformFieldsetsMixin provide, go to the API Reference for fieldsets.