Skip to main content
  1. X-GOVUK projects
  2. GOV.UK Form Builder
  3. Checkboxes

Checkboxes

Checkboxes allow users to:

By default the form builder’s checkbox helpers will automatically inject a hidden field. The hidden field ensures that a parameter is always submitted with the form even when no checkboxes have been checked, allowing options to be deselected. The hidden field can be toggled using the multiple keyword argument.

Important

Note that Rails now adds presence validation to associations automatically but usually we set relationships by assigning values to the foreign key column.

This results in errors being added to the object on attributes that don’t appear in the form, for example on department instead of department_id.

You can suppress this behaviour by adding optional: true to the relationship and manually adding the presence validation to the foreign key field yourself.

Generating a collection of checkboxes

Data

departments = [
  OpenStruct.new(id: 1, name: 'Sales'),
  OpenStruct.new(id: 2, name: 'Marketing'),
  OpenStruct.new(id: 3, name: 'Finance')
]

Input

= f.govuk_collection_check_boxes :department_ids,
  departments,
  :id,
  :name,
  caption: nil,
  legend: { text: "Which departments do you work in?" },
  hint: { text: "Select all departments that apply" }
<%= f.govuk_collection_check_boxes :department_ids, departments, :id, :name, caption: nil, legend: { text: "Which departments do you work in?" }, hint: { text: "Select all departments that apply" } %>

Output

Which departments do you work in?
Select all departments that apply
<div class="govuk-form-group">
  <fieldset class="govuk-fieldset" aria-describedby="person-department-ids-hint">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--m">
      Which departments do you work in?
    </legend>
    <div class="govuk-hint" id="person-department-ids-hint">
      Select all departments that apply
    </div>
    <div class="govuk-checkboxes" data-module="govuk-checkboxes">
      <input type="hidden" name="person[department_ids][]" value="" autocomplete="off" />
      <div class="govuk-checkboxes__item">
        <input id="person-department-ids-1-field" class="govuk-checkboxes__input" type="checkbox" value="1" name="person[department_ids][]" />
        <label for="person-department-ids-1-field" class="govuk-label govuk-checkboxes__label">
          Sales
        </label>
      </div>
      <div class="govuk-checkboxes__item">
        <input id="person-department-ids-2-field" class="govuk-checkboxes__input" type="checkbox" value="2" name="person[department_ids][]" />
        <label for="person-department-ids-2-field" class="govuk-label govuk-checkboxes__label">
          Marketing
        </label>
      </div>
      <div class="govuk-checkboxes__item">
        <input id="person-department-ids-3-field" class="govuk-checkboxes__input" type="checkbox" value="3" name="person[department_ids][]" />
        <label for="person-department-ids-3-field" class="govuk-label govuk-checkboxes__label">
          Finance
        </label>
      </div>
    </div>
  </fieldset>
</div>

Generating a collection of checkboxes with hints

Data

lunch_options = [
  OpenStruct.new(
    id: 1,
    name: 'Salad',
    description: 'Lettuce, tomato and cucumber'
  ),
  OpenStruct.new(
    id: 2,
    name: 'Jacket potato',
    description: 'With cheese and baked beans'
  )
]

Input

= f.govuk_collection_check_boxes :lunch_ids,
  lunch_options,
  :id,
  :name,
  :description,
  hint: { text: "Select all options you are happy to eat" },
  legend: { text: "What are your preferred lunch options?" }
<%= f.govuk_collection_check_boxes :lunch_ids, lunch_options, :id, :name, :description, hint: { text: "Select all options you are happy to eat" }, legend: { text: "What are your preferred lunch options?" } %>

Output

What are your preferred lunch options?
Select all options you are happy to eat
Lettuce, tomato and cucumber
With cheese and baked beans
<div class="govuk-form-group">
  <fieldset class="govuk-fieldset" aria-describedby="person-lunch-ids-hint">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--m">
      What are your preferred lunch options?
    </legend>
    <div class="govuk-hint" id="person-lunch-ids-hint">
      Select all options you are happy to eat
    </div>
    <div class="govuk-checkboxes" data-module="govuk-checkboxes">
      <input type="hidden" name="person[lunch_ids][]" value="" autocomplete="off" />
      <div class="govuk-checkboxes__item">
        <input id="person-lunch-ids-1-field" class="govuk-checkboxes__input" aria-describedby="person-lunch-ids-1-hint" type="checkbox" value="1" name="person[lunch_ids][]" />
        <label for="person-lunch-ids-1-field" class="govuk-label govuk-checkboxes__label">
          Salad
        </label>
        <div class="govuk-hint govuk-checkboxes__hint" id="person-lunch-ids-1-hint">
          Lettuce, tomato and cucumber
        </div>
      </div>
      <div class="govuk-checkboxes__item">
        <input id="person-lunch-ids-2-field" class="govuk-checkboxes__input" aria-describedby="person-lunch-ids-2-hint" type="checkbox" value="2" name="person[lunch_ids][]" />
        <label for="person-lunch-ids-2-field" class="govuk-label govuk-checkboxes__label">
          Jacket potato
        </label>
        <div class="govuk-hint govuk-checkboxes__hint" id="person-lunch-ids-2-hint">
          With cheese and baked beans
        </div>
      </div>
    </div>
  </fieldset>
</div>

Generating checkboxes with a conditionally-revealed text field

The form builder does not keep track of its contents so to ensure the error summary correctly links to the first checkbox link_errors must be set to true

When more advanced functionality like conditional fields is required, the govuk_check_boxes_fieldset helper is recommended. Any content passed in via the block will be conditionally revealed when the box is checked.

Input

= f.govuk_check_boxes_fieldset :languages, legend: { text: "Which languages do you speak?", size: "m" } do

  = f.govuk_check_box :languages,
    :english,
    label: { text: "English" },
    link_errors: true,
    hint: { text: "Only select English if you have a GCSE at grade C or above" }

  = f.govuk_check_box :languages,
    :welsh,
    label: { text: "Welsh" }

  = f.govuk_check_box :languages,
    :gaelic,
    label: { text: "Gaelic" }

  = f.govuk_check_box :languages,
    :other,
    label: { text: "Other" } do

    = f.govuk_text_field :other_language,
      label: { text: "Which additional language do you speak?" }
<%= f.govuk_check_boxes_fieldset :languages, legend: { text: "Which languages do you speak?", size: "m" } do %>
  <%= f.govuk_check_box :languages, :english, label: { text: "English" }, link_errors: true, hint: { text: "Only select English if you have a GCSE at grade C or above" } %>
  <%= f.govuk_check_box :languages, :welsh, label: { text: "Welsh" } %>
  <%= f.govuk_check_box :languages, :gaelic, label: { text: "Gaelic" } %>
  <%= f.govuk_check_box :languages, :other, label: { text: "Other" } do %>
    <%= f.govuk_text_field :other_language, label: { text: "Which additional language do you speak?" } %>
  <% end %>
<% end %>

Output

Which languages do you speak?
Only select English if you have a GCSE at grade C or above
<div class="govuk-form-group">
  <fieldset class="govuk-fieldset">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--m">
      Which languages do you speak?
    </legend>
    <input value="" name="person[languages][]" autocomplete="off" type="hidden" id="person_languages" />
    <div class="govuk-checkboxes" data-module="govuk-checkboxes">
      <div class="govuk-checkboxes__item">
        <input id="person-languages-english-field" class="govuk-checkboxes__input" aria-describedby="person-languages-english-hint" type="checkbox" value="english" name="person[languages][]" />
        <label for="person-languages-english-field" class="govuk-label govuk-checkboxes__label">
          English
        </label>
        <div class="govuk-hint govuk-checkboxes__hint" id="person-languages-english-hint">
          Only select English if you have a GCSE at grade C or above
        </div>
      </div>
      <div class="govuk-checkboxes__item">
        <input id="person-languages-welsh-field" class="govuk-checkboxes__input" type="checkbox" value="welsh" name="person[languages][]" />
        <label for="person-languages-welsh-field" class="govuk-label govuk-checkboxes__label">
          Welsh
        </label>
      </div>
      <div class="govuk-checkboxes__item">
        <input id="person-languages-gaelic-field" class="govuk-checkboxes__input" type="checkbox" value="gaelic" name="person[languages][]" />
        <label for="person-languages-gaelic-field" class="govuk-label govuk-checkboxes__label">
          Gaelic
        </label>
      </div>
      <div class="govuk-checkboxes__item">
        <input id="person-languages-other-field" class="govuk-checkboxes__input" data-aria-controls="person-languages-other-conditional" type="checkbox" value="other" name="person[languages][]" />
        <label for="person-languages-other-field" class="govuk-label govuk-checkboxes__label">
          Other
        </label>
      </div>
      <div class="govuk-checkboxes__conditional govuk-checkboxes__conditional--hidden" id="person-languages-other-conditional">
        <div class="govuk-form-group">
          <label for="person-other-language-field" class="govuk-label">
            Which additional language do you speak?
          </label>
          <input id="person-other-language-field" class="govuk-input" type="text" name="person[other_language]" />
        </div>
      </div>
    </div>
  </fieldset>
</div>

Small checkboxes

Use standard-sized checkboxes in nearly all cases. However, smaller versions work well on pages where it’s helpful to make them less visually prominent.

For example, on a page of search results, the primary user need is to see the results. Using smaller checkboxes lets users see and change search filters without distracting them from the main content.

Data

lunch_options = [
  OpenStruct.new(
    id: 1,
    name: 'Salad',
    description: 'Lettuce, tomato and cucumber'
  ),
  OpenStruct.new(
    id: 2,
    name: 'Jacket potato',
    description: 'With cheese and baked beans'
  )
]

Input

= f.govuk_collection_check_boxes :wednesday_lunch_ids,
  lunch_options,
  :id,
  :name,
  :description,
  small: true,
  legend: { text: "What would you like for lunch on Wednesday?" }
<%= f.govuk_collection_check_boxes :wednesday_lunch_ids, lunch_options, :id, :name, :description, small: true, legend: { text: "What would you like for lunch on Wednesday?" } %>

Output

What would you like for lunch on Wednesday?
Lettuce, tomato and cucumber
With cheese and baked beans
<div class="govuk-form-group">
  <fieldset class="govuk-fieldset">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--m">
      What would you like for lunch on Wednesday?
    </legend>
    <div class="govuk-checkboxes govuk-checkboxes--small" data-module="govuk-checkboxes">
      <input type="hidden" name="person[wednesday_lunch_ids][]" value="" autocomplete="off" />
      <div class="govuk-checkboxes__item">
        <input id="person-wednesday-lunch-ids-1-field" class="govuk-checkboxes__input" aria-describedby="person-wednesday-lunch-ids-1-hint" type="checkbox" value="1" name="person[wednesday_lunch_ids][]" />
        <label for="person-wednesday-lunch-ids-1-field" class="govuk-label govuk-checkboxes__label">
          Salad
        </label>
        <div class="govuk-hint govuk-checkboxes__hint" id="person-wednesday-lunch-ids-1-hint">
          Lettuce, tomato and cucumber
        </div>
      </div>
      <div class="govuk-checkboxes__item">
        <input id="person-wednesday-lunch-ids-2-field" class="govuk-checkboxes__input" aria-describedby="person-wednesday-lunch-ids-2-hint" type="checkbox" value="2" name="person[wednesday_lunch_ids][]" />
        <label for="person-wednesday-lunch-ids-2-field" class="govuk-label govuk-checkboxes__label">
          Jacket potato
        </label>
        <div class="govuk-hint govuk-checkboxes__hint" id="person-wednesday-lunch-ids-2-hint">
          With cheese and baked beans
        </div>
      </div>
    </div>
  </fieldset>
</div>

Generating a single checkbox

Single checkboxes are usually used for boolean fields like accepting terms and conditions or toggling a setting.

When asking users questions, favour the use of ‘Yes’ and ‘No’ radio buttons. This ensures the user has understood the question and is actively selecting the appropriate answer.

Note that in this example multiple: false is passed to both the #govuk_check_boxes_fieldset and #govuk_check_box helpers.

They’re required to ensure the both checkbox’s and hidden field’s name attribute is generated in the format that Rails expects for a single field.

Input

= f.govuk_check_boxes_fieldset :terms_and_conditions_agreed,
  multiple: false,
  legend: { text: 'Terms and conditions', size: 'l' } do

  p.govuk-body
    | Our terms and conditions contain important information about:

  ul.govuk-list.govuk-list--bullet
    li the application process
    li contacting us
    li our use of your data
    li checking you're safe to work with children

  = f.govuk_check_box :terms_and_conditions_agreed,
    1,
    0,
    multiple: false,
    link_errors: true,
    label: { text: "I agree to the terms and conditions" }
<%= f.govuk_check_boxes_fieldset :terms_and_conditions_agreed, multiple: false, legend: { text: 'Terms and conditions', size: 'l' } do %>
  <p class="govuk-body">
    Our terms and conditions contain important information about:
  </p>
  <ul class="govuk-list govuk-list--bullet">
    <li>the application process</li>
    <li>contacting us</li>
    <li>our use of your data</li>
    <li>checking you're safe to work with children
    </li>
  </ul>
  <%= f.govuk_check_box :terms_and_conditions_agreed, 1, 0, multiple: false, link_errors: true, label: { text: "I agree to the terms and conditions" } %>
<% end %>

Output

Terms and conditions

Our terms and conditions contain important information about:

  • the application process
  • contacting us
  • our use of your data
  • checking you’re safe to work with children
<div class="govuk-form-group">
  <fieldset class="govuk-fieldset">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--l">
      Terms and conditions
    </legend>
    <div class="govuk-checkboxes" data-module="govuk-checkboxes">
      <p class="govuk-body">
        Our terms and conditions contain important information about:
      </p>
      <ul class="govuk-list govuk-list--bullet">
        <li>
          the application process
        </li>
        <li>
          contacting us
        </li>
        <li>
          our use of your data
        </li>
        <li>
          checking you're safe to work with children
        </li>
      </ul>
      <div class="govuk-checkboxes__item">
        <input name="person[terms_and_conditions_agreed]" type="hidden" value="0" autocomplete="off" />
        <input id="person-terms-and-conditions-agreed-1-field" class="govuk-checkboxes__input" type="checkbox" value="1" name="person[terms_and_conditions_agreed]" />
        <label for="person-terms-and-conditions-agreed-1-field" class="govuk-label govuk-checkboxes__label">
          I agree to the terms and conditions
        </label>
      </div>
    </div>
  </fieldset>
</div>

Adding an option for ‘none of the above’

Sometimes none of the checkbox options apply, but leaving them all blank isn’t always intuitive for users.

Checkboxes created with exclusive: true have special behaviour that:

  • unchecks all other checkboxes in the fieldset when they are checked
  • unchecks them when any other checkboxes in the fieldset are checked

It usually makes sense to separate exclusive checkboxes from the others with a divider.

Input

= f.govuk_check_boxes_fieldset :countries, legend: { text: "Will you be travelling to any of these countries?", size: "m" } do

  = f.govuk_check_box :countries,
    :france,
    label: { text: "France" },
    link_errors: true

  = f.govuk_check_box :countries,
    :portugal,
    label: { text: "Portugal" }

  = f.govuk_check_box :countries,
    :spain,
    label: { text: "Spain" }

  = f.govuk_check_box_divider

  = f.govuk_check_box :countries,
    :none,
    exclusive: true,
    label: { text: "No, I will not be travelling to any of these countries " }
<%= f.govuk_check_boxes_fieldset :countries, legend: { text: "Will you be travelling to any of these countries?", size: "m" } do %>
  <%= f.govuk_check_box :countries, :france, label: { text: "France" }, link_errors: true %>
  <%= f.govuk_check_box :countries, :portugal, label: { text: "Portugal" } %>
  <%= f.govuk_check_box :countries, :spain, label: { text: "Spain" } %>
  <%= f.govuk_check_box_divider %>
  <%= f.govuk_check_box :countries, :none, exclusive: true, label: { text: "No, I will not be travelling to any of these countries " } %>
<% end %>

Output

Will you be travelling to any of these countries?
or
<div class="govuk-form-group">
  <fieldset class="govuk-fieldset">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--m">
      Will you be travelling to any of these countries?
    </legend>
    <input value="" name="person[countries][]" autocomplete="off" type="hidden" id="person_countries" />
    <div class="govuk-checkboxes" data-module="govuk-checkboxes">
      <div class="govuk-checkboxes__item">
        <input id="person-countries-france-field" class="govuk-checkboxes__input" type="checkbox" value="france" name="person[countries][]" />
        <label for="person-countries-france-field" class="govuk-label govuk-checkboxes__label">
          France
        </label>
      </div>
      <div class="govuk-checkboxes__item">
        <input id="person-countries-portugal-field" class="govuk-checkboxes__input" type="checkbox" value="portugal" name="person[countries][]" />
        <label for="person-countries-portugal-field" class="govuk-label govuk-checkboxes__label">
          Portugal
        </label>
      </div>
      <div class="govuk-checkboxes__item">
        <input id="person-countries-spain-field" class="govuk-checkboxes__input" type="checkbox" value="spain" name="person[countries][]" />
        <label for="person-countries-spain-field" class="govuk-label govuk-checkboxes__label">
          Spain
        </label>
      </div>
      <div class="govuk-checkboxes__divider">
        or
      </div>
      <div class="govuk-checkboxes__item">
        <input id="person-countries-none-field" class="govuk-checkboxes__input" data-behaviour="exclusive" type="checkbox" value="none" name="person[countries][]" />
        <label for="person-countries-none-field" class="govuk-label govuk-checkboxes__label">
          No, I will not be travelling to any of these countries 
        </label>
      </div>
    </div>
  </fieldset>
</div>