You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4.8 KiB
4.8 KiB
| parent | grand_parent | nav_order |
|---|---|---|
| Form definition | Generating forms | 4 |
Question
Updated for 2026.
Questions are under the page level of the form definition.
An example question might look something like this:
class Form::Sales::Questions::PreviousPostcodeKnown < ::Form::Question
def initialize(id, hsh, page)
super
@id = "ppcodenk"
@copy_key = "sales.household_situation.last_accommodation.ppcodenk"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@conditional_for = {
"ppostcode_full" => [0],
}
@hidden_in_check_answers = {
"depends_on" => [
{
"ppcodenk" => 0,
},
{
"ppcodenk" => 1,
},
],
}
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
@disable_clearing_if_not_routed_or_dynamic_answer_options = true
end
ANSWER_OPTIONS = {
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
}.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 57, 2024 => 59, 2025 => 57 }.freeze
end
Let's take a look at the properties in the initialize function.
- id
- The name of the field. This should correspond to a column in the database. In the example, the id is 'ppcodenk'.
- copy_key
- This specifies copy from
config/locales/forms/...that should be associated with the question - type
- Determines what type of question is rendered on the page. In the example, the question is a Radio Form so the
app/views/form/_radio_question.html.erbpartial will be rendered on the page when this question is displayed to the user - answer_options
- Some types of question offer multiple options to pick from, which can be defined here. In the example, there are two options. The option that will be rendered with the label 'Yes' has the underlying value 0. The option with the label 'No' has the underlying value 1.
- conditional_for
- Allows for additional questions to be rendered on the page if a certain value is chosen for the current question. In the example, if the value of this question is 0 (the 'Yes' option is selected), then the question with id 'ppostcode_full' will be rendered beneath the selected option.
If the user has JavaScript enabled then this realtime conditional display is handled by theapp/frontend/controllers/conditional_question_controller.jsfile. - hidden_in_check_answers
-
Allows us to hide the question on the 'check your answers' page. You only need to provide this if you want to set it to true in order to hide the value for some reason e.g. it's one of two questions appearing on a page and the other question is displayed on the check answers page.
Ifdepends_onis supplied, then whether this question is hidden can be made conditional on the answers provided to any question. In the example, the question is hidden if 'ppcodenk' (this question) has value 0 or 1. (As these are the only two possible answers, the question will always be hidden.) - question_number
-
Determines which number gets rendered next to the question text on the question page and in the 'check your answers' page.
The convention that we use for the question number is that we only add to the 'QUESTION_NUMBER_FROM_YEAR' hash when the question number changes. So, if the example remains unchanged into 2026, 2027, etc., that means that it is still question 57.
Another example shows us some fields that are used when we want to infer the answers to one question based on a user's answers to another question. This can allow the user to have to answer fewer questions, lowering their total number of clicks.
class Form::Sales::Questions::PostcodeForFullAddress < ::Form::Question
def initialize(id, hsh, page)
super
@id = "postcode_full"
@inferred_check_answers_value = [{
"condition" => {
"pcodenk" => 1,
},
"value" => "Not known",
}]
@inferred_answers = {
"la" => {
"is_la_inferred" => true,
},
}
# Other fields omitted for brevity
end
end
- inferred_check_answers_value
- Determines what gets shown on the 'check your answers' page if we infer the answer to this question. In the example, if the question 'pcodenk' has value 1 (indicating that the postcode is not known), then the answer shown for this question will be 'Not known'.
- inferred_answers
- Determines any questions whose answers can be inferred based on the answer to this question. In the example, the 'la' question (Local Authority) can be inferred from the Postcode. We set a property 'is_la_inferred' on the log to record this inferrance.