Reputation: 951
I have created a quiz with wagtail form builder, but I need the form to contain some fields which are constant. For example, I have the following:
How do I integrate fields [1-3] in the form builder to show up on all quizzes?
Upvotes: 1
Views: 883
Reputation: 5196
A simple way to do this is to override the get_form_fields
method on your FormPage model.
This method simply returns a query for all stored FormFields on the FormPage model. We can add instances of FormField as needed and this will make the fields available in the form (view). They will also be available in form reports and emails.
get_form_fields
in your FormPage
class.In myapp/models.py wherever you have defined your FormPage model, add the following:
class FormPage(AbstractEmailForm):
# ...additional FormPage fiels and content_panels
def get_form_fields(self):
# get form_fields as defined by the super class & convert to list
# otherwise returns queryset
fields = list(super(FormPage, self).get_form_fields())
# append instances of FormField - not actually stored in the db
# field_type can only be one of the following:
# 'singleline', 'multiline', 'email', 'number', 'url', 'checkbox',
# 'checkboxes', 'dropdown', 'multiselect', 'radio', 'date',
# 'datetime', 'hidden'
# Important: Label MUST be unique in each form
# `insert(0` will prepend these items, so here ID will be first
fields.insert(0, FormField(
label='Employee Name',
field_type='singleline',
required=False,
help_text="Employee's Name"))
fields.insert(0, FormField(
label='Employee Email',
field_type='email',
required=False,
help_text="Employee's Email"))
fields.insert(0, FormField(
label='Employee ID',
field_type='number',
required=False,
help_text="Employee's ID"))
return fields
Note: When creating our FormField
instances, these are not stored in the database, but their responses will be. You should provide the attributes label, field_type, required and help_text.
If the form label 'Employee ID' is used already in a form - not sure what will happen but it will likely break things so check you do not have conflicts in existing form pages.
Note: If the label is the same, you will not loose your data from previous submissions. All data is stored for past submissions even if you change the FormFields in use.
label
field on FormField
with some validationIn myapp/models.py wherever you have defined your FormField model, add the following:
from django.core.exceptions import ValidationError
# ... other imports and then models
RESERVED_LABELS = ['Employee Name', 'Employee Email', 'Employee ID']
def validate_label(value):
if value in RESERVED_LABELS:
raise ValidationError("'%s' is reserved." % value)
class FormField(AbstractFormField):
# page = ...
# redefine 'label' field so we can ensure there will be no conflicts with constant fields
label = models.CharField(
verbose_name='label',
max_length=255,
help_text='The label of the form field, cannot be one of the following: %s.'
% ', '.join(RESERVED_LABELS),
validators=[validate_label]
)
RESERVED_VALUES
should match the labels used in your FormPage model.
This creates a simple Django Field Validator to check that you will not have conflicting labels. It also adds some nice help text so users do not get confused.
You should also do a migrations as you have now changed the label
field on the FormField
model.
Upvotes: 3