Wizards
=======
Fast-gov-uk have some handy tools for building
`GDS Question pages `_ -
also known as ``Wizard`` on the interwebs.
The following is a simplified implementation of the
`Equality Survey `_ -
.. code-block:: python
:linenos:
@fast.wizard
def equality(step=0, data=None):
return forms.Wizard(
"equality",
forms.Question(
ds.Radios(
name="permission",
label="Do you want to answer the equality questions?",
choices={
"yes": "Yes, answer the equality questions",
"no": "No, skip the equality questions"
},
),
cta="Continue",
),
forms.Question(
ds.Radios(
name="health",
label=(
"Do you have any physical or mental health conditions or illness "
"lasting or expected to last 12 months or more?"
),
choices={"yes": "Yes", "no": "No", "skip": "Prefer not to say"},
),
predicates={"permission": "yes"},
cta="Continue",
),
forms.Question(
ds.Radios(
name="ability",
label=(
"Do any of your conditions or illnesses reduce your ability "
"to carry out day to day activities?"
),
choices={"alot": "Yes, a lot", "little": "Yes, a little", "not": "Not at all", "skip": "Prefer not to say"},
required=False,
),
predicates={"permission": "yes", "health": "yes"},
cta="Continue",
),
forms.Question(
ds.Fieldset(
ds.Radios(
name="sex",
label="What is your sex?",
choices={"female": "Female", "male": "Male", "skip": "Prefer not to say"},
),
ds.Radios(
name="gender",
label=(
"Is the gender you identify with the same as "
"your sex registered at birth?"
),
choices={"yes": "Yes", "no": "No", "skip": "Prefer not to say"},
),
legend="Sex and gender identity",
name="sex-and-gender",
),
predicates={"permission": "yes"},
cta="Continue",
),
backends=[forms.DBBackend(db=fast.db)],
step=step,
data=data,
)
1. The ``wizard`` decorator "registers" this function as a wizard rendered at
``/wizards/equality``. You can easily render this at a different url -
``@fast.wizard("/not-equality")`` would render the wizard at ``/wizards/not-equality``.
2. The ``equality`` function must return a ``Wizard`` object (see below) and it must accept
``step`` and ``data`` arguments. You can think of Wizards as a series of Forms. The ``step``
argument identifies a form within a ``Wizard``. Each Form can be empty or filled and when
they are filled, the ``data`` argument would contain the values that we can use to populate
our form fields.
3. The ``Wizard`` class is used to define a wizard. A Wizard comprises of one or more
``Question`` objects - which are a subclass of ``Form`` - and so they look like forms and
they work like forms.
25. Except, unlike ``Form`` objects, ``Question`` objects accept an argument called
``predicates``. This is a dictionary that defines the names of fields and the values they must
have if this particular ``Question`` is to be shown to our user. In our example, we are saying
that each ``Question`` following the first "permission" question would render only if the user
clicked "Yes, answer the equality questions".
62. Like ``Form`` objects, ``Wizard`` objects accepts a list of backends that define
what happens when a ``Wizard`` is processed upon submission. These backends are the same
as the ones in ``Form``.