Branching journeys using checkboxes
You can create branches using any form fields, including checkboxes and radios. In this example we will use checkboxes.
We will look at an example question to ask the user what they export. If the user:
- exports fruit, we will take them to a page with specific questions about fruit
- does not export fruit, we will send them to a different path that skips the questions about fruit
Sending users to different pages based on their answers is called branching.
Create the page
Create a page that has a form with checkboxes, using this code:
<form class="form" action="/exports-answer" method="post">
{{ govukCheckboxes({
name: "exports",
values: data["exports"],
fieldset: {
legend: {
text: "What do you export?",
isPageHeading: true,
classes: "govuk-fieldset__legend--l"
}
},
hint: {
text: "Select all that apply."
},
items: [
{
value: "Fruit",
text: "Fruit"
},
{
value: "Vegetables",
text: "Vegetables"
},
{
value: "Meat",
text: "Meat"
}
]
}) }}
{{ govukButton({
text: "Continue"
}) }}
</form>
In the checkboxes component, the name
is "exports". The name is important - it is where the kit stores the answer to the question. Names cannot have spaces, so use hyphens instead and use lowercase for simplicity.
The button needs to be between the 2 form
tags. Do not add an href
to the button - this will turn it into a link and means it no longer submits the form.
The page should look like this:
Using routes
We need some logic to decide when to send users to different pages. This kind of logic goes in a file called app/routes.js
, which is written in JavaScript. Routes tell the kit what to do when the user goes to specific pages.
The route takes the answer the user gave to the question and either sends them to the next question or the ineligible page, depending on their answer.
How we set the route from the page
In the page’s form tag, we have an action "/exports-answer" and a method "post":
<form class="form" action="/exports-answer" method="post">
The action is where the form data goes and the method is post
because we are sending (posting) data.
This will make a post
request to the path /exports-answer
, we will write a route to respond to that request.
Create a route
We’re going to write some logic to process the user’s answer to the question.
We will look at 2 example routes for checkboxes:
- A specific answer is selected (and it does not matter if any other answer is selected)
- Only a specific answer is selected
Example 1: A specific answer is selected (and it does not matter if any other answer is selected)
In this first example we will check if the user selected the 'Fruit' checkbox. We don't care if they selected any other checkboxes.
In app/routes.js
we need to add a route to process the answer from the form.
- Open
/app/routes.js
- Add this code to the end of the file (this is called a route):
router.post('/exports-answer', function(request, response) {
var exports = request.session.data['exports']
if (exports.includes("Fruit")){
response.redirect("/fruit")
} else {
response.redirect("/next-question")
}
})
Let's look at what each line in the route does.
router.post
This route is for a post request - the same as the method
we set on the form. We use a post request to send the kit new information (like the user’s answer to the question).
'/exports-answer'
This is the path for the route - the same as the action
we set on the form.
var exports = request.session.data['exports']
To send users to different pages based on their answers, the kit stores all answers in a variable called request.session.data
.
We need the answer to 'What do you export?', so we use the name
we set on the component: exports
We use var exports =
to copy request.session.data['exports']
to a shorter variable. This makes it easier to type later on.
if (exports.includes("Fruit")){
Answers to checkboxes are stored as lists (called 'arrays') in the kit.
This code checks whether the array stored for exports includes the answer 'Fruit'. This is the same as the value
we set on one of our checkboxes.
As long as the answer 'Fruit' is selected, it does not matter if any other checkbox is also selected. We'll see how to check for a single answer in the 2nd example.
response.redirect("/fruit")
Because the user's answer includes 'Fruit', our response
is to redirect
them to /fruit
- a page with specific questions about fruit.
} else {
If the user's answer does not include 'Fruit', we use else
to set a different response.
response.redirect("/next-question")
Our response
is to redirect
them to /next-question
- skipping the page with specific questions about fruit.
Example 2: Only a specific answer is selected
Add this line at the top of routes.js
:
const util = require('util')
Then add this route:
router.post('/exports-answer', function(request, response) {
var exports = request.session.data['exports']
if (util.deepStrictEqual(exports, ['Fruit'])){
response.redirect("/fruit")
} else {
response.redirect("/next-question")
}
})
This is all the same as our first example, but instead of exports.includes
we have:
util.deepStrictEqual(exports, ['Fruit'])
This checks whether the array stored for exports only has the answer 'Fruit', and no other answer.
We could also check for 2 specific answers:
util.deepStrictEqual(exports, ['Fruit', 'Vegetables'])
Note the order is the same as the checkboxes, that's important - checking ['Vegetables', 'Fruit']
will not work.