Skip to content

Commit

Permalink
Merge pull request #756 from nhsuk/feature/checkboxes-none-of-these
Browse files Browse the repository at this point in the history
Checkboxes - none of these JS behaviour
  • Loading branch information
chrimesdev authored Aug 23, 2021
2 parents 76e801c + 6589ad3 commit d1345ef
Show file tree
Hide file tree
Showing 17 changed files with 560 additions and 53 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# NHS.UK frontend Changelog

## 5.2.0 - Unreleased

:new: **New features**

- Add "None of these" JavaScript behaviour to checkboxes - allowing all checkboxes in a group to be automatically unchecked when the "None of the above" option is checked ([PR 756](https://github.com/nhsuk/nhsuk-frontend/pull/756))

## 5.1.1 - Unreleased

:wrench: **Fixes**
Expand Down
68 changes: 35 additions & 33 deletions app/components/checkboxes/conditional.njk
Original file line number Diff line number Diff line change
Expand Up @@ -44,43 +44,45 @@

<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-two-thirds">
{{ checkboxes({
"idPrefix": "contact",
"name": "contact",
"fieldset": {
"legend": {
"text": "How would you prefer to be contacted?",
"classes": "nhsuk-fieldset__legend--l",
"isPageHeading": "true"
}
},
"hint": {
"text": "Select all options that are relevant to you."
},
"items": [
{
"value": "email",
"text": "Email",
"conditional": {
"html": emailHtml
<form>
{{ checkboxes({
"idPrefix": "contact",
"name": "contact",
"fieldset": {
"legend": {
"text": "How would you prefer to be contacted?",
"classes": "nhsuk-fieldset__legend--l",
"isPageHeading": "true"
}
},
{
"value": "phone",
"text": "Phone",
"conditional": {
"html": phoneHtml
}
"hint": {
"text": "Select all options that are relevant to you."
},
{
"value": "text",
"text": "Text message",
"conditional": {
"html": mobileHtml
"items": [
{
"value": "email",
"text": "Email",
"conditional": {
"html": emailHtml
}
},
{
"value": "phone",
"text": "Phone",
"conditional": {
"html": phoneHtml
}
},
{
"value": "text",
"text": "Text message",
"conditional": {
"html": mobileHtml
}
}
}
]
}) }}
]
}) }}
</form>
</div>
</div>

Expand Down
108 changes: 108 additions & 0 deletions app/components/checkboxes/none-of-the-above.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
{% set html_style = 'background-color: #f0f4f5;' %}
{% set title = 'Checkboxes with "none of the above" option' %}
{% from 'components/checkboxes/macro.njk' import checkboxes %}
{% from 'components/input/macro.njk' import input %}
{% extends 'layout.njk' %}

{% set emailHtml %}
{{ input({
id: "email",
name: "email",
classes: "nhsuk-u-width-two-thirds",
label: {
text: "Email address"
}
}) }}
{% endset -%}

{% set phoneHtml %}
{{ input({
id: "phone",
name: "phone",
classes: "nhsuk-u-width-two-thirds",
label: {
text: "Phone number"
}
}) }}
{% endset -%}

{% set mobileHtml %}
{{ input({
id: "mobile",
name: "mobile",
classes: "nhsuk-u-width-two-thirds",
label: {
text: "Mobile phone number"
}
}) }}
{% endset -%}

{% block body %}

<div class="nhsuk-width-container">
<main class="nhsuk-main-wrapper" id="maincontent">

<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-two-thirds">
<form>
{{ checkboxes({
"idPrefix": "contact",
"name": "contact",
"fieldset": {
"legend": {
"text": "How would you prefer to be contacted?",
"classes": "nhsuk-fieldset__legend--l",
"isPageHeading": "true"
}
},
"hint": {
"text": "Select all options that are relevant to you."
},
"items": [
{
"value": "email",
"text": "Email",
"name": "email",
"exclusiveGroup": "communication-preferences",
"conditional": {
"html": emailHtml
}
},
{
"value": "phone",
"text": "Phone",
"name": "phone",
"exclusiveGroup": "communication-preferences",
"conditional": {
"html": phoneHtml
}
},
{
"value": "text",
"text": "Text message",
"name": "text",
"exclusiveGroup": "communication-preferences",
"conditional": {
"html": mobileHtml
}
},
{
"divider": "or"
},
{
"value": "none",
"text": "None of the above",
"name": "none",
"exclusive": true,
"exclusiveGroup": "communication-preferences"
}
]
}) }}
</form>
</div>
</div>

</main>
</div>

{% endblock %}
127 changes: 127 additions & 0 deletions app/components/radios/nested-conditionals.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
{% set html_style = 'background-color: #f0f4f5;' %}
{% set title = 'Radios with nested conditonal content' %}
{% from 'components/radios/macro.njk' import radios %}
{% from 'components/input/macro.njk' import input %}
{% from 'components/warning-callout/macro.njk' import warningCallout %}
{% extends 'layout.njk' %}

{% set emailHtml %}
{{ input({
id: "email",
name: "email",
classes: "nhsuk-u-width-two-thirds",
label: {
text: "Email address"
}
}) }}
{% endset -%}

{% set phoneHtml %}
{{ input({
id: "phone",
name: "phone",
classes: "nhsuk-u-width-two-thirds",
label: {
text: "Phone number"
}
}) }}
{% endset -%}

{% set mobileHtml %}
{{ input({
id: "mobile",
name: "mobile",
classes: "nhsuk-u-width-two-thirds",
label: {
text: "Mobile phone number"
}
}) }}
{% endset -%}

{%- set nestedConditional %}
{{ radios({
"idPrefix": "inner",
"name": "inner",
"fieldset": {
"legend": {
"text": "How would you prefer to be contacted?",
"classes": "nhsuk-fieldset__legend--l"
}
},
"hint": {
"text": "Select one option."
},
"items": [
{
"value": "email",
"text": "Email",
"conditional": {
"html": emailHtml
}
},
{
"value": "phone",
"text": "Phone",
"conditional": {
"html": phoneHtml
}
},
{
"value": "text",
"text": "Text message",
"conditional": {
"html": mobileHtml
}
}
]
}) }}
{% endset -%}

{% block body %}

<div class="nhsuk-width-container">
<main class="nhsuk-main-wrapper" id="maincontent">

<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-two-thirds">

{{ warningCallout({
"heading": "Important",
"HTML": "<p>Please do everything in your power to avoid nested conditionals like this. The example is here to demonstrate that it works - not as a recommendation!</p>"
}) }}
<form>
{{ radios({
"idPrefix": "outer",
"name": "outer",
"fieldset": {
"legend": {
"text": "How would you prefer to be contacted?",
"classes": "nhsuk-fieldset__legend--l",
"isPageHeading": "true"
}
},
"hint": {
"text": "Select one option."
},
"items": [
{
"value": "no-conditional",
"text": "No conditional"
},
{
"value": "nested",
"text": "Nested conditional",
"conditional": {
"html": nestedConditional
}
}
]
}) }}
</form>
</div>
</div>

</main>
</div>

{% endblock %}
2 changes: 2 additions & 0 deletions app/pages/examples.njk
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<li><a href="../components/checkboxes/page-heading.html">Checkboxes with legend as page heading</a></li>
<li><a href="../components/checkboxes/error.html">Checkboxes with error message</a></li>
<li><a href="../components/checkboxes/conditional.html">Checkboxes with conditional content</a></li>
<li><a href="../components/checkboxes/none-of-the-above.html">Checkboxes with "none of the above" option</a></li>
<li><a href="../components/contents-list/index.html">Contents list</a></li>
<li><a href="../components/date-input/index.html">Date input</a></li>
<li><a href="../components/date-input/autocomplete.html">Date input with autocomplete attribute</a></li>
Expand Down Expand Up @@ -95,6 +96,7 @@
<li><a href="../components/radios/without-fieldset.html">Radios without fieldset</a></li>
<li><a href="../components/radios/hint-error.html">Radios with hint text and error message</a></li>
<li><a href="../components/radios/conditional.html">Radios with conditional content</a></li>
<li><a href="../components/radios/nested-conditionals.html">Radios with nested conditional radios</a></li>
<li><a href="../components/select/index.html">Select</a></li>
<li><a href="../components/select/hint-error.html">Select with hint text and error message</a></li>
<li><a href="../components/skip-link/index.html">Skip link</a></li>
Expand Down
9 changes: 7 additions & 2 deletions packages/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@ export const toggleConditionalInput = (input, className) => {
// Get the conditional element from the input data-aria-controls attribute
const conditionalElement = document.getElementById(conditionalId);
if (conditionalElement) {
conditionalElement.classList.toggle(className);
toggleAttribute(input, 'aria-expanded');
if (input.checked) {
conditionalElement.classList.remove(className);
input.setAttribute('aria-expanded', true);
} else {
conditionalElement.classList.add(className);
input.setAttribute('aria-expanded', false);
}
}
}
};
Loading

0 comments on commit d1345ef

Please sign in to comment.