Cookies on ons.gov.uk

Cookies are small files stored on your device when you visit a website. We use some essential cookies to make this website work.

We would like to set additional cookies to remember your settings and understand how you use the site. This helps us to improve our services.

You have accepted all additional cookies. You have rejected all additional cookies. You can change your cookie preferences at any time.

Skip to main content

Mutually exclusive

Overview

When to use this component

The mutually exclusive component provides the user a way to give an opposing answer to the options provided and say none of the other options apply to them.

How to use this component

Inputs, radios, checkboxes, date inputs, and textareas all call this macro automatically when the mutuallyExclusive parameter is set. This adds the mutually exclusive checkbox, the required aria-live alert markup and the classes required for the JavaScript to run.

Variants

Checkboxes

Example Mutually Exclusive Checkboxes contents

Nunjucks
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{% from "components/question/_macro.njk" import onsQuestion %}

{% call onsQuestion({
    "title": "What type of central heating do you have?",
    "legendIsQuestionTitle": true
}) %}
    {{
        onsCheckboxes({
            "id": "central-heating-answers",
            "dontWrap": true,
            "checkboxesLabel": "Select all that apply",
            "name": "mutually-exclusive",
            "checkboxes": [
                {
                    "id": "gas-example-mutually-exclusive-checkbox",
                    "label": {
                        "text": "Gas"
                    },
                    "value": "gas"
                },
                {
                    "id": "electric-example-mutually-exclusive-checkbox",
                    "label": {
                        "text": "Electric"
                    },
                    "value": "electric"
                },
                {
                    "id": "solid-fuel-example-mutually-exclusive-checkbox",
                    "label": {
                        "text": "Solid fuel"
                    },
                    "value": "solid-fuel"
                },
                {
                    "id": "other-fuel-example-mutually-exclusive-checkbox",
                    "label": {
                        "text": "Other"
                    },
                    "value": "other",
                    "other": {
                        "id": "other-fuel-textbox-example-mutually-exclusive-checkbox",
                        "name": "other-fuel-answer",
                        "label": {
                        "text": "Please specify"
                        }
                    }
                }
            ],
            "mutuallyExclusive": {
                "or": "Or",
                "deselectMessage": "Selecting this will uncheck all other checkboxes",
                "deselectGroupAdjective": "deselected",
                "deselectExclusiveOptionAdjective": "deselected",
                "exclusiveOptions": [
                    {
                        "id": "no-central-heating-example-mutually-exclusive-checkbox",
                        "label": {
                            "text": "No central heating"
                        },
                        "attributes": {
                            "data-attribute": "Example attribute"
                        },
                        "value": "no-central-heating"
                    }
                ]
            }
        })
    }}
{% endcall %}
Nunjucks macro options
NameTypeRequiredDescription
idstringfalseThe HTML id of the fieldset
classesstringfalseClasses to apply to the fieldset
legendstringtrue (unless legendIsQuestionTitle is set)Text for the fieldset’s legend
legendClassesstringfalseClasses to apply to the legend element
legendIsQuestionTitlebooleantrue (unless legend is set)Creates an h1 inside the legend. Use when there is only a single fieldset on the page
descriptionstringfalseDescription for the fieldset
attributesobjectfalseHTML attributes (for example, data attributes) to add to the fieldset
exclusiveOptionsArray<Checkbox> or Array<radio>trueConfiguration for the mutually exclusive options
orstringfalseText for the “Or” label that separates the mutually exclusive checkbox from the answer options, defaults to "Or".
deselectMessagestringtrueThe text the aria-live alert will announce to warn that selecting the exclusive checkbox will clear or unselect all other answer options. For example, ”Selecting this will uncheck all other checkboxes”.
deselectGroupAdjectivestringtrueThe text the aria-live alert will announce when an answer option is cleared or unselected when the mutually exclusive checkbox is selected
deselectExclusiveOptionAdjectivestringtrueThe text the aria-live alert will announce when an option is cleared or unselected when the mutually exclusive checkbox is selected
errorError (ref)falseConfiguration for validation errors
dontWrapbooleanfalsePrevents fields,checkboxes,date input,duration,input and Textarea from being wrapped in a fieldset component
autosuggestresultsstringfalseShows suggested options to users as they enter something into an input field
HTML
<div class="ons-question ons-u-mb-l">
  <div class="ons-question__answer ons-u-mb-m">
    <fieldset class="ons-fieldset">
      <legend class="ons-fieldset__legend ons-u-mb-no">
        <h1 id="fieldset-legend-title" class="ons-fieldset__legend-title">What type of central heating do you have?</h1>
      </legend>
      <div class="ons-input-items">
        <div class="ons-js-mutually-exclusive ons-mutually-exclusive">
          <p class="ons-checkboxes__label">Select all that apply</p>
          <div class="ons-checkboxes__items">
            <span class="ons-checkboxes__item">
              <span class="ons-checkbox">
                <input type="checkbox" id="gas-example-mutually-exclusive-checkbox"
                  class="ons-checkbox__input ons-js-checkbox  ons-js-exclusive-group-item" value="gas">
                <label class=" ons-checkbox__label " for="gas-example-mutually-exclusive-checkbox"
                  id="gas-example-mutually-exclusive-checkbox-label">Gas</label>
              </span>
            </span>
            <br>
            <span class="ons-checkboxes__item">
              <span class="ons-checkbox">
                <input type="checkbox" id="electric-example-mutually-exclusive-checkbox"
                  class="ons-checkbox__input ons-js-checkbox  ons-js-exclusive-group-item" value="electric">
                <label class=" ons-checkbox__label " for="electric-example-mutually-exclusive-checkbox"
                  id="electric-example-mutually-exclusive-checkbox-label">Electric</label>
              </span>
            </span>
            <br>
            <span class="ons-checkboxes__item">
              <span class="ons-checkbox">
                <input type="checkbox" id="solid-fuel-example-mutually-exclusive-checkbox"
                  class="ons-checkbox__input ons-js-checkbox  ons-js-exclusive-group-item" value="solid-fuel">
                <label class=" ons-checkbox__label " for="solid-fuel-example-mutually-exclusive-checkbox"
                  id="solid-fuel-example-mutually-exclusive-checkbox-label">Solid fuel</label>
              </span>
            </span>
            <br>
            <span class="ons-checkboxes__item">
              <span class="ons-checkbox">
                <input type="checkbox" id="other-fuel-example-mutually-exclusive-checkbox"
                  class="ons-checkbox__input ons-js-checkbox  ons-js-exclusive-group-item ons-js-other" value="other"
                  aria-controls="other-fuel-example-mutually-exclusive-checkbox-other-wrap" aria-haspopup="true">
                <label class=" ons-checkbox__label " for="other-fuel-example-mutually-exclusive-checkbox"
                  id="other-fuel-example-mutually-exclusive-checkbox-label">Other</label>
                <span class="ons-checkbox__other" id="other-fuel-example-mutually-exclusive-checkbox-other-wrap">
                  <label class="ons-label ons-u-fw-n" for="other-fuel-textbox-example-mutually-exclusive-checkbox"
                    id="other-fuel-textbox-example-mutually-exclusive-checkbox-label">Please specify</label>
                  <input type="text" id="other-fuel-textbox-example-mutually-exclusive-checkbox"
                    class="ons-input ons-input--text ons-input-type__input  ons-js-exclusive-group-item ons-input--w-auto"
                    name="other-fuel-answer" />
                </span>
              </span>
            </span>
          </div>
          <p class="ons-checkboxes--mutually-exclusive__item ons-u-mt-s">
            <span class="ons-checkboxes__label ons-u-fs-r--b" aria-hidden="true">Or</span>
            <span class="ons-checkbox">
              <input type="checkbox" id="no-central-heating-example-mutually-exclusive-checkbox"
                class="ons-checkbox__input ons-js-checkbox ons-js-exclusive-option" value="no-central-heating"
                data-attribute="Example attribute"
                data-deselect-message="Selecting this will uncheck all other checkboxes">
              <label class=" ons-checkbox__label " for="no-central-heating-example-mutually-exclusive-checkbox"
                id="no-central-heating-example-mutually-exclusive-checkbox-label"><span class="ons-u-vh">Or, </span> No
                central heating</label>
            </span>
          </p>
          <span class="ons-js-exclusive-alert ons-u-vh" role="alert" aria-live="polite"
            data-group-adjective="deselected" data-option-adjective="deselected"></span>
        </div>
      </div>
    </fieldset>
  </div>
</div>

Date

Example Mutually Exclusive Date contents

Nunjucks
{% from "components/date-input/_macro.njk" import onsDateInput %}
{% from "components/question/_macro.njk" import onsQuestion %}

{% call onsQuestion({
    "title": "When did you leave your last paid job?",
    "description": "<p>For example, 31 3 2018</p>",
    "legendIsQuestionTitle": true
}) %}
    {{
        onsDateInput({
            "id": "date-mutually-exclusive",
            "dontWrap": true,
            "day": {
                "label": {
                    "text": "Day"
                },
                "name": "day-exclusive"
            },
            "month": {
                "label": {
                    "text": "Month"
                },
                "name": "month-exclusive"
            },
            "year": {
                "label": {
                    "text": "Year"
                },
                "name": "year-exclusive"
            },
            "mutuallyExclusive": {
                "or": "Or",
                "deselectMessage": "Selecting this will clear the date if one has been inputted",
                "deselectGroupAdjective": "cleared",
                "deselectExclusiveOptionAdjective": "deselected",
                "exclusiveOptions": [
                    {
                        "id": "date-exclusive-checkbox",
                        "name": "no-paid-job",
                        "value": "no-paid-job",
                        "label": {
                            "text": "I have never had a paid job"
                        }
                    }
                ]
            }
        })
    }}
{% endcall %}
Nunjucks macro options
NameTypeRequiredDescription
idstringfalseThe HTML id of the fieldset
classesstringfalseClasses to apply to the fieldset
legendstringtrue (unless legendIsQuestionTitle is set)Text for the fieldset’s legend
legendClassesstringfalseClasses to apply to the legend element
legendIsQuestionTitlebooleantrue (unless legend is set)Creates an h1 inside the legend. Use when there is only a single fieldset on the page
descriptionstringfalseDescription for the fieldset
attributesobjectfalseHTML attributes (for example, data attributes) to add to the fieldset
exclusiveOptionsArray<Checkbox> or Array<radio>trueConfiguration for the mutually exclusive options
orstringfalseText for the “Or” label that separates the mutually exclusive checkbox from the answer options, defaults to "Or".
deselectMessagestringtrueThe text the aria-live alert will announce to warn that selecting the exclusive checkbox will clear or unselect all other answer options. For example, ”Selecting this will uncheck all other checkboxes”.
deselectGroupAdjectivestringtrueThe text the aria-live alert will announce when an answer option is cleared or unselected when the mutually exclusive checkbox is selected
deselectExclusiveOptionAdjectivestringtrueThe text the aria-live alert will announce when an option is cleared or unselected when the mutually exclusive checkbox is selected
errorError (ref)falseConfiguration for validation errors
dontWrapbooleanfalsePrevents fields,checkboxes,date input,duration,input and Textarea from being wrapped in a fieldset component
autosuggestresultsstringfalseShows suggested options to users as they enter something into an input field
HTML
<div class="ons-question ons-u-mb-l">
  <div class="ons-question__answer ons-u-mb-m">
    <fieldset class="ons-fieldset">
      <legend aria-describedBy="legend-description"
        class="ons-fieldset__legend ons-u-mb-no ons-fieldset__legend--with-description">
        <h1 id="fieldset-legend-title" class="ons-fieldset__legend-title">When did you leave your last paid job?</h1>
      </legend>
      <div id="legend-description" class="ons-fieldset__description ons-fieldset__description--title ons-u-mb-m">
        <p>For example, 31 3 2018</p>
      </div>
      <div class="ons-input-items">
        <div class="ons-js-mutually-exclusive ons-mutually-exclusive">
          <div class="ons-field-group">
            <div class="ons-field">
              <label class="ons-label" for="date-mutually-exclusive-day"
                id="date-mutually-exclusive-day-label">Day</label>
              <input type="text" id="date-mutually-exclusive-day"
                class="ons-input ons-input--text ons-input-type__input  ons-js-exclusive-group-item ons-input-number--w-2"
                name="day-exclusive" min="1" max="31" maxlength="2" pattern="[0-9]*" inputmode="numeric" />
            </div>
            <div class="ons-field">
              <label class="ons-label" for="date-mutually-exclusive-month"
                id="date-mutually-exclusive-month-label">Month</label>
              <input type="text" id="date-mutually-exclusive-month"
                class="ons-input ons-input--text ons-input-type__input  ons-js-exclusive-group-item ons-input-number--w-2"
                name="month-exclusive" min="1" max="12" maxlength="2" pattern="[0-9]*" inputmode="numeric" />
            </div>
            <div class="ons-field">
              <label class="ons-label" for="date-mutually-exclusive-year"
                id="date-mutually-exclusive-year-label">Year</label>
              <input type="text" id="date-mutually-exclusive-year"
                class="ons-input ons-input--text ons-input-type__input  ons-js-exclusive-group-item ons-input-number--w-4"
                name="year-exclusive" min="1000" max="3000" maxlength="4" pattern="[0-9]*" inputmode="numeric" />
            </div>
          </div>
          <p class="ons-checkboxes--mutually-exclusive__item ons-u-mt-s">
            <span class="ons-checkboxes__label ons-u-fs-r--b" aria-hidden="true">Or</span>
            <span class="ons-checkbox">
              <input type="checkbox" id="date-exclusive-checkbox"
                class="ons-checkbox__input ons-js-checkbox ons-js-exclusive-option" value="no-paid-job"
                name="no-paid-job" data-deselect-message="Selecting this will clear the date if one has been inputted">
              <label class=" ons-checkbox__label " for="date-exclusive-checkbox"
                id="date-exclusive-checkbox-label"><span class="ons-u-vh">Or, </span> I have never had a paid
                job</label>
            </span>
          </p>
          <span class="ons-js-exclusive-alert ons-u-vh" role="alert" aria-live="polite" data-group-adjective="cleared"
            data-option-adjective="deselected"></span>
        </div>
      </div>
    </fieldset>
  </div>
</div>

Textarea

Example Mutually Exclusive Textarea contents

Nunjucks
{% from "components/textarea/_macro.njk" import onsTextarea %}
{% from "components/question/_macro.njk" import onsQuestion %}

{% call onsQuestion({
    "title": "What do you think of this service?",
    "legendIsQuestionTitle": true
}) %}
    {{
        onsTextarea({
            "id": "feedback",
            "name": "feedback",
            "dontWrap": true,
            "width": "30",
            "label": {
                "text": "Enter your feedback"
            },
            "charCheckLimit": {
                "limit": 200,
                "charCountSingular": "You have {x} character remaining",
                "charCountPlural": "You have {x} characters remaining"
            },
            "mutuallyExclusive": {
                "or": "Or",
                "deselectMessage": "Selecting this will clear your feedback",
                "deselectGroupAdjective": "cleared",
                "deselectExclusiveOptionAdjective": "deselected",
                "exclusiveOptions": [
                    {
                        "id": "feedback-checkbox",
                        "name": "no-feedback",
                        "value": "no-feedback",
                        "label": {
                            "text": "I don’t want to provide feedback"
                        }
                    }
                ]
            }
        })
    }}
{% endcall %}
Nunjucks macro options
NameTypeRequiredDescription
idstringfalseThe HTML id of the fieldset
classesstringfalseClasses to apply to the fieldset
legendstringtrue (unless legendIsQuestionTitle is set)Text for the fieldset’s legend
legendClassesstringfalseClasses to apply to the legend element
legendIsQuestionTitlebooleantrue (unless legend is set)Creates an h1 inside the legend. Use when there is only a single fieldset on the page
descriptionstringfalseDescription for the fieldset
attributesobjectfalseHTML attributes (for example, data attributes) to add to the fieldset
exclusiveOptionsArray<Checkbox> or Array<radio>trueConfiguration for the mutually exclusive options
orstringfalseText for the “Or” label that separates the mutually exclusive checkbox from the answer options, defaults to "Or".
deselectMessagestringtrueThe text the aria-live alert will announce to warn that selecting the exclusive checkbox will clear or unselect all other answer options. For example, ”Selecting this will uncheck all other checkboxes”.
deselectGroupAdjectivestringtrueThe text the aria-live alert will announce when an answer option is cleared or unselected when the mutually exclusive checkbox is selected
deselectExclusiveOptionAdjectivestringtrueThe text the aria-live alert will announce when an option is cleared or unselected when the mutually exclusive checkbox is selected
errorError (ref)falseConfiguration for validation errors
dontWrapbooleanfalsePrevents fields,checkboxes,date input,duration,input and Textarea from being wrapped in a fieldset component
autosuggestresultsstringfalseShows suggested options to users as they enter something into an input field
HTML
<div class="ons-question ons-u-mb-l">
  <div class="ons-question__answer ons-u-mb-m">
    <fieldset class="ons-fieldset">
      <legend class="ons-fieldset__legend ons-u-mb-no">
        <h1 id="fieldset-legend-title" class="ons-fieldset__legend-title">What do you think of this service?</h1>
      </legend>
      <div class="ons-input-items">
        <div class="ons-js-mutually-exclusive ons-mutually-exclusive">
          <div class="ons-field">
            <label class="ons-label" for="feedback">Enter your feedback</label>
            <textarea id="feedback"
              class="ons-input ons-input--textarea  ons-js-char-limit-input ons-js-exclusive-group-item  ons-input--w-30"
              name="feedback" rows="8" maxlength="200" data-char-limit-ref="feedback-lim"
              aria-describedby="feedback-lim"></textarea>
            <span id="feedback-lim" class="ons-input__limit ons-u-fs-s--b ons-u-d-no ons-u-mt-xs"
              data-charcount-singular="You have {x} character remaining"
              data-charcount-plural="You have {x} characters remaining" data-charcount-limit-singular=""
              data-charcount-limit-plural="">
            </span>
          </div>
          <p class="ons-checkboxes--mutually-exclusive__item ons-u-mt-s">
            <span class="ons-checkboxes__label ons-u-fs-r--b" aria-hidden="true">Or</span>
            <span class="ons-checkbox">
              <input type="checkbox" id="feedback-checkbox"
                class="ons-checkbox__input ons-js-checkbox ons-js-exclusive-option" value="no-feedback"
                name="no-feedback" data-deselect-message="Selecting this will clear your feedback">
              <label class=" ons-checkbox__label " for="feedback-checkbox" id="feedback-checkbox-label"><span
                  class="ons-u-vh">Or, </span> I don’t want to provide feedback</label>
            </span>
          </p>
          <span class="ons-js-exclusive-alert ons-u-vh" role="alert" aria-live="polite" data-group-adjective="cleared"
            data-option-adjective="deselected"></span>
        </div>
      </div>
    </fieldset>
  </div>
</div>

Email

Example Mutually Exclusive Email contents

Nunjucks
{% from "components/input/_macro.njk" import onsInput %}
{% from "components/question/_macro.njk" import onsQuestion %}

{% call onsQuestion({
    "title": "Get a confirmation email",
    "description": "<p>Enter your email address if you would like to be sent confirmation that you have completed your survey</p>",
    "legendIsQuestionTitle": true
}) %}
    {{
        onsInput({
            "id": "email-example-mutually-exclusive",
            "type": "email",
            "label": {
                "text": "Email address",
                "description": "This will not be stored and only used once to send your confirmation"
            },
            "dontWrap": true,
            "mutuallyExclusive": {
                "or": "Or",
                "deselectMessage": "Selecting this will clear your email",
                "deselectGroupAdjective": "cleared",
                "deselectExclusiveOptionAdjective": "deselected",
                "exclusiveOptions": [
                    {
                        "id": "email-checkbox-example-mutually-exclusive",
                        "name": "no-email",
                        "value": "no-email",
                        "label": {
                            "text": "I don’t want to receive a confirmation email"
                        }
                    }
                ]
            }
        })
    }}
{% endcall %}
Nunjucks macro options
NameTypeRequiredDescription
idstringfalseThe HTML id of the fieldset
classesstringfalseClasses to apply to the fieldset
legendstringtrue (unless legendIsQuestionTitle is set)Text for the fieldset’s legend
legendClassesstringfalseClasses to apply to the legend element
legendIsQuestionTitlebooleantrue (unless legend is set)Creates an h1 inside the legend. Use when there is only a single fieldset on the page
descriptionstringfalseDescription for the fieldset
attributesobjectfalseHTML attributes (for example, data attributes) to add to the fieldset
exclusiveOptionsArray<Checkbox> or Array<radio>trueConfiguration for the mutually exclusive options
orstringfalseText for the “Or” label that separates the mutually exclusive checkbox from the answer options, defaults to "Or".
deselectMessagestringtrueThe text the aria-live alert will announce to warn that selecting the exclusive checkbox will clear or unselect all other answer options. For example, ”Selecting this will uncheck all other checkboxes”.
deselectGroupAdjectivestringtrueThe text the aria-live alert will announce when an answer option is cleared or unselected when the mutually exclusive checkbox is selected
deselectExclusiveOptionAdjectivestringtrueThe text the aria-live alert will announce when an option is cleared or unselected when the mutually exclusive checkbox is selected
errorError (ref)falseConfiguration for validation errors
dontWrapbooleanfalsePrevents fields,checkboxes,date input,duration,input and Textarea from being wrapped in a fieldset component
autosuggestresultsstringfalseShows suggested options to users as they enter something into an input field
HTML
<div class="ons-question ons-u-mb-l">
  <div class="ons-question__answer ons-u-mb-m">
    <fieldset class="ons-fieldset">
      <legend aria-describedBy="legend-description"
        class="ons-fieldset__legend ons-u-mb-no ons-fieldset__legend--with-description">
        <h1 id="fieldset-legend-title" class="ons-fieldset__legend-title">Get a confirmation email</h1>
      </legend>
      <div id="legend-description" class="ons-fieldset__description ons-fieldset__description--title ons-u-mb-m">
        <p>Enter your email address if you would like to be sent confirmation that you have completed your survey</p>
      </div>
      <div class="ons-input-items">
        <div class="ons-js-mutually-exclusive ons-mutually-exclusive">
          <label class="ons-label ons-label--with-description" aria-describedby="description-hint"
            for="email-example-mutually-exclusive">Email address</label>
          <span id="description-hint" class="ons-label__description  ons-input--with-description">This will not be
            stored and only used once to send your confirmation</span>
          <input type="email" id="email-example-mutually-exclusive"
            class="ons-input ons-input--text ons-input-type__input ons-js-exclusive-group-item"
            aria-describedby="description-hint" />
          <p class="ons-checkboxes--mutually-exclusive__item ons-u-mt-s">
            <span class="ons-checkboxes__label ons-u-fs-r--b" aria-hidden="true">Or</span>
            <span class="ons-checkbox">
              <input type="checkbox" id="email-checkbox-example-mutually-exclusive"
                class="ons-checkbox__input ons-js-checkbox ons-js-exclusive-option" value="no-email" name="no-email"
                data-deselect-message="Selecting this will clear your email">
              <label class=" ons-checkbox__label " for="email-checkbox-example-mutually-exclusive"
                id="email-checkbox-example-mutually-exclusive-label"><span class="ons-u-vh">Or, </span> I don’t want to
                receive a confirmation email</label>
            </span>
          </p>
          <span class="ons-js-exclusive-alert ons-u-vh" role="alert" aria-live="polite" data-group-adjective="cleared"
            data-option-adjective="deselected"></span>
        </div>
      </div>
    </fieldset>
  </div>
</div>

Number

Example Mutually Exclusive Number contents

Nunjucks
{% from "components/input/_macro.njk" import onsInput %}
{% from "components/question/_macro.njk" import onsQuestion %}

{% call onsQuestion({
    "title": "What was your annual income before tax in 2018/19?",
    "legendIsQuestionTitle": true
}) %}
    {{
        onsInput({
            "id": "currency",
            "dontWrap": true,
            "type": "number",
            "width": "4",
            "attributes": {
                "min": 0
            },
            "label": {
                "text": "Gross annual income"
            },
            "prefix": {
                "title": "British pounds (GBP)",
                "text": "£",
                "id": "annual-salary-gpb-prefix"
            },
            "mutuallyExclusive": {
                "or": "Or",
                "deselectMessage": "Selecting this will clear your inputted annual income",
                "deselectGroupAdjective": "cleared",
                "deselectExclusiveOptionAdjective": "deselected",
                "exclusiveOptions": [
                    {
                        "id": "currency-checkbox",
                        "name": "no-currency",
                        "value": "no-currency",
                        "label": {
                            "text": "I prefer not to say"
                        }
                    }
                ]
            }
        })
    }}
{% endcall %}
Nunjucks macro options
NameTypeRequiredDescription
idstringfalseThe HTML id of the fieldset
classesstringfalseClasses to apply to the fieldset
legendstringtrue (unless legendIsQuestionTitle is set)Text for the fieldset’s legend
legendClassesstringfalseClasses to apply to the legend element
legendIsQuestionTitlebooleantrue (unless legend is set)Creates an h1 inside the legend. Use when there is only a single fieldset on the page
descriptionstringfalseDescription for the fieldset
attributesobjectfalseHTML attributes (for example, data attributes) to add to the fieldset
exclusiveOptionsArray<Checkbox> or Array<radio>trueConfiguration for the mutually exclusive options
orstringfalseText for the “Or” label that separates the mutually exclusive checkbox from the answer options, defaults to "Or".
deselectMessagestringtrueThe text the aria-live alert will announce to warn that selecting the exclusive checkbox will clear or unselect all other answer options. For example, ”Selecting this will uncheck all other checkboxes”.
deselectGroupAdjectivestringtrueThe text the aria-live alert will announce when an answer option is cleared or unselected when the mutually exclusive checkbox is selected
deselectExclusiveOptionAdjectivestringtrueThe text the aria-live alert will announce when an option is cleared or unselected when the mutually exclusive checkbox is selected
errorError (ref)falseConfiguration for validation errors
dontWrapbooleanfalsePrevents fields,checkboxes,date input,duration,input and Textarea from being wrapped in a fieldset component
autosuggestresultsstringfalseShows suggested options to users as they enter something into an input field
HTML
<div class="ons-question ons-u-mb-l">
  <div class="ons-question__answer ons-u-mb-m">
    <fieldset class="ons-fieldset">
      <legend class="ons-fieldset__legend ons-u-mb-no">
        <h1 id="fieldset-legend-title" class="ons-fieldset__legend-title">What was your annual income before tax in
          2018/19?</h1>
      </legend>
      <div class="ons-input-items">
        <div class="ons-js-mutually-exclusive ons-mutually-exclusive">
          <label class="ons-label" for="currency">Gross annual income</label>
          <span class="ons-input-type ons-input-type--prefix ons-js-input-container-abbr">
            <span class="ons-input-type__inner">
              <input type="text" id="currency"
                class="ons-input ons-input--text ons-input-type__input ons-input-number--w-4 ons-js-exclusive-group-item"
                aria-labelledby="currency annual-salary-gpb-prefix" pattern="[0-9]*" inputmode="numeric" min />
              <abbr id="annual-salary-gpb-prefix" class="ons-input-type__type ons-js-input-abbr"
                aria-label="British pounds (GBP)" role="figure" title="British pounds (GBP)">£</abbr>
            </span>
          </span>
          <p class="ons-checkboxes--mutually-exclusive__item ons-u-mt-s">
            <span class="ons-checkboxes__label ons-u-fs-r--b" aria-hidden="true">Or</span>
            <span class="ons-checkbox">
              <input type="checkbox" id="currency-checkbox"
                class="ons-checkbox__input ons-js-checkbox ons-js-exclusive-option" value="no-currency"
                name="no-currency" data-deselect-message="Selecting this will clear your inputted annual income">
              <label class=" ons-checkbox__label " for="currency-checkbox" id="currency-checkbox-label"><span
                  class="ons-u-vh">Or, </span> I prefer not to say</label>
            </span>
          </p>
          <span class="ons-js-exclusive-alert ons-u-vh" role="alert" aria-live="polite" data-group-adjective="cleared"
            data-option-adjective="deselected"></span>
        </div>
      </div>
    </fieldset>
  </div>
</div>

Duration

Example Mutually Exclusive Duration contents

Nunjucks
{% from "components/question/_macro.njk" import onsQuestion %}
{% from "components/duration/_macro.njk" import onsDuration %}

{% call onsQuestion({
    "title": "How long have you lived at this address?",
    "description": "<p>Enter “0” into the years field if you have lived at this address for less than a year</p>",
    "legendIsQuestionTitle": true
}) %}
    {{ onsDuration({
        "id": "address-duration",
        "dontWrap": true,
        "field1": {
            "id": "address-duration-years",
            "name": "address-duration-years",
            "suffix": {
                "text": "Years",
                "id": "address-duration-years-suffix"
            }
        },
        "field2": {
            "id": "address-duration-months",
            "name": "address-duration-months",
            "suffix": {
                "text": "Months",
                "id": "address-duration-months-suffix"
            }
        },
        "mutuallyExclusive": {
            "or": "Or",
            "deselectMessage": "Selecting this will clear the date if one has been inputted",
            "deselectGroupAdjective": "cleared",
            "deselectExclusiveOptionAdjective": "deselected",
            "exclusiveOptions": [
                {
                    "id": "duration-exclusive-checkbox",
                    "name": "no-duration",
                    "value": "no-duration",
                    "label": {
                        "text": "I have not moved in to this address yet"
                    }
                }
            ]
        }
    }) }}
{% endcall %}
Nunjucks macro options
NameTypeRequiredDescription
idstringfalseThe HTML id of the fieldset
classesstringfalseClasses to apply to the fieldset
legendstringtrue (unless legendIsQuestionTitle is set)Text for the fieldset’s legend
legendClassesstringfalseClasses to apply to the legend element
legendIsQuestionTitlebooleantrue (unless legend is set)Creates an h1 inside the legend. Use when there is only a single fieldset on the page
descriptionstringfalseDescription for the fieldset
attributesobjectfalseHTML attributes (for example, data attributes) to add to the fieldset
exclusiveOptionsArray<Checkbox> or Array<radio>trueConfiguration for the mutually exclusive options
orstringfalseText for the “Or” label that separates the mutually exclusive checkbox from the answer options, defaults to "Or".
deselectMessagestringtrueThe text the aria-live alert will announce to warn that selecting the exclusive checkbox will clear or unselect all other answer options. For example, ”Selecting this will uncheck all other checkboxes”.
deselectGroupAdjectivestringtrueThe text the aria-live alert will announce when an answer option is cleared or unselected when the mutually exclusive checkbox is selected
deselectExclusiveOptionAdjectivestringtrueThe text the aria-live alert will announce when an option is cleared or unselected when the mutually exclusive checkbox is selected
errorError (ref)falseConfiguration for validation errors
dontWrapbooleanfalsePrevents fields,checkboxes,date input,duration,input and Textarea from being wrapped in a fieldset component
autosuggestresultsstringfalseShows suggested options to users as they enter something into an input field
HTML
<div class="ons-question ons-u-mb-l">
  <div class="ons-question__answer ons-u-mb-m">
    <fieldset class="ons-fieldset">
      <legend aria-describedBy="legend-description"
        class="ons-fieldset__legend ons-u-mb-no ons-fieldset__legend--with-description">
        <h1 id="fieldset-legend-title" class="ons-fieldset__legend-title">How long have you lived at this address?</h1>
      </legend>
      <div id="legend-description" class="ons-fieldset__description ons-fieldset__description--title ons-u-mb-m">
        <p>Enter “0” into the years field if you have lived at this address for less than a year</p>
      </div>
      <div class="ons-input-items">
        <div class="ons-js-mutually-exclusive ons-mutually-exclusive">
          <div class="ons-field-group">
            <div class="ons-field">
              <span class="ons-input-type ons-js-input-container-abbr">
                <span class="ons-input-type__inner">
                  <input type="text" id="address-duration-years"
                    class="ons-input ons-input--text ons-input-type__input  ons-js-exclusive-group-item ons-input-number--w-2"
                    aria-labelledby="address-duration-years-suffix"
                    aria-labelledby="address-duration-years address-duration-years-suffix" name="address-duration-years"
                    pattern="[0-9]*" inputmode="numeric" />
                  <span id="address-duration-years-suffix" class="ons-input-type__type ons-js-input-abbr" aria-label=""
                    role="figure">Years</span>
                </span>
              </span>
            </div>
            <div class="ons-field">
              <span class="ons-input-type ons-js-input-container-abbr">
                <span class="ons-input-type__inner">
                  <input type="text" id="address-duration-months"
                    class="ons-input ons-input--text ons-input-type__input  ons-js-exclusive-group-item ons-input-number--w-2"
                    aria-labelledby="address-duration-months-suffix"
                    aria-labelledby="address-duration-months address-duration-months-suffix"
                    name="address-duration-months" pattern="[0-9]*" inputmode="numeric" />
                  <span id="address-duration-months-suffix" class="ons-input-type__type ons-js-input-abbr" aria-label=""
                    role="figure">Months</span>
                </span>
              </span>
            </div>
          </div>
          <p class="ons-checkboxes--mutually-exclusive__item ons-u-mt-s">
            <span class="ons-checkboxes__label ons-u-fs-r--b" aria-hidden="true">Or</span>
            <span class="ons-checkbox">
              <input type="checkbox" id="duration-exclusive-checkbox"
                class="ons-checkbox__input ons-js-checkbox ons-js-exclusive-option" value="no-duration"
                name="no-duration" data-deselect-message="Selecting this will clear the date if one has been inputted">
              <label class=" ons-checkbox__label " for="duration-exclusive-checkbox"
                id="duration-exclusive-checkbox-label"><span class="ons-u-vh">Or, </span> I have not moved in to this
                address yet</label>
            </span>
          </p>
          <span class="ons-js-exclusive-alert ons-u-vh" role="alert" aria-live="polite" data-group-adjective="cleared"
            data-option-adjective="deselected"></span>
        </div>
      </div>
    </fieldset>
  </div>
</div>

Multiple mutually exclusive options

When more than one mutually exclusive option is provided the exclusive options become radio buttons.

Example Mutually Exclusive Multiple Options contents

Nunjucks
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{% from "components/question/_macro.njk" import onsQuestion %}

{% call onsQuestion({
    "title": "What type of central heating do you have?",
    "legendIsQuestionTitle": true
}) %}
    {{
        onsCheckboxes({
            "id": "central-heating-answers",
            "dontWrap": true,
            "checkboxesLabel": "Select all that apply",
            "name": "mutually-exclusive",
            "checkboxes": [
                {
                    "id": "gas-example-mutually-exclusive-multiple-options",
                    "label": {
                        "text": "Gas"
                    },
                    "value": "gas"
                },
                {
                    "id": "electric-example-mutually-exclusive-multiple-options",
                    "label": {
                        "text": "Electric"
                    },
                    "value": "electric"
                },
                {
                    "id": "solid-fuel-example-mutually-exclusive-multiple-options",
                    "label": {
                        "text": "Solid fuel"
                    },
                    "value": "solid-fuel"
                }
            ],
            "mutuallyExclusive": {
                "or": "Or",
                "deselectMessage": "Selecting these will uncheck all other checkboxes",
                "deselectGroupAdjective": "deselected",
                "deselectExclusiveOptionAdjective": "deselected",
                "exclusiveOptions": [
                    {
                        "id": "no-central-heating-example-mutually-exclusive-multiple-options",
                        "name": "no central heating",
                        "label": {
                            "text": "No central heating"
                        },
                        "value": "no-central-heating"
                    },
                    {
                        "id": "other-example-mutually-exclusive-multiple-options",
                        "name": "other",
                        "label": {
                            "text": "Other"
                        },
                        "value": "other"
                    }
                ]
            }
        })
    }}
{% endcall %}
Nunjucks macro options
NameTypeRequiredDescription
idstringfalseThe HTML id of the fieldset
classesstringfalseClasses to apply to the fieldset
legendstringtrue (unless legendIsQuestionTitle is set)Text for the fieldset’s legend
legendClassesstringfalseClasses to apply to the legend element
legendIsQuestionTitlebooleantrue (unless legend is set)Creates an h1 inside the legend. Use when there is only a single fieldset on the page
descriptionstringfalseDescription for the fieldset
attributesobjectfalseHTML attributes (for example, data attributes) to add to the fieldset
exclusiveOptionsArray<Checkbox> or Array<radio>trueConfiguration for the mutually exclusive options
orstringfalseText for the “Or” label that separates the mutually exclusive checkbox from the answer options, defaults to "Or".
deselectMessagestringtrueThe text the aria-live alert will announce to warn that selecting the exclusive checkbox will clear or unselect all other answer options. For example, ”Selecting this will uncheck all other checkboxes”.
deselectGroupAdjectivestringtrueThe text the aria-live alert will announce when an answer option is cleared or unselected when the mutually exclusive checkbox is selected
deselectExclusiveOptionAdjectivestringtrueThe text the aria-live alert will announce when an option is cleared or unselected when the mutually exclusive checkbox is selected
errorError (ref)falseConfiguration for validation errors
dontWrapbooleanfalsePrevents fields,checkboxes,date input,duration,input and Textarea from being wrapped in a fieldset component
autosuggestresultsstringfalseShows suggested options to users as they enter something into an input field
HTML
<div class="ons-question ons-u-mb-l">
  <div class="ons-question__answer ons-u-mb-m">
    <fieldset class="ons-fieldset">
      <legend class="ons-fieldset__legend ons-u-mb-no">
        <h1 id="fieldset-legend-title" class="ons-fieldset__legend-title">What type of central heating do you have?</h1>
      </legend>
      <div class="ons-input-items">
        <div class="ons-js-mutually-exclusive ons-mutually-exclusive">
          <p class="ons-checkboxes__label">Select all that apply</p>
          <div class="ons-checkboxes__items">
            <span class="ons-checkboxes__item">
              <span class="ons-checkbox">
                <input type="checkbox" id="gas-example-mutually-exclusive-multiple-options"
                  class="ons-checkbox__input ons-js-checkbox  ons-js-exclusive-group-item" value="gas">
                <label class=" ons-checkbox__label " for="gas-example-mutually-exclusive-multiple-options"
                  id="gas-example-mutually-exclusive-multiple-options-label">Gas</label>
              </span>
            </span>
            <br>
            <span class="ons-checkboxes__item">
              <span class="ons-checkbox">
                <input type="checkbox" id="electric-example-mutually-exclusive-multiple-options"
                  class="ons-checkbox__input ons-js-checkbox  ons-js-exclusive-group-item" value="electric">
                <label class=" ons-checkbox__label " for="electric-example-mutually-exclusive-multiple-options"
                  id="electric-example-mutually-exclusive-multiple-options-label">Electric</label>
              </span>
            </span>
            <br>
            <span class="ons-checkboxes__item">
              <span class="ons-checkbox">
                <input type="checkbox" id="solid-fuel-example-mutually-exclusive-multiple-options"
                  class="ons-checkbox__input ons-js-checkbox  ons-js-exclusive-group-item" value="solid-fuel">
                <label class=" ons-checkbox__label " for="solid-fuel-example-mutually-exclusive-multiple-options"
                  id="solid-fuel-example-mutually-exclusive-multiple-options-label">Solid fuel</label>
              </span>
            </span>
          </div>
          <p class="ons-checkboxes--mutually-exclusive__item ons-u-mt-s">
            <span class="ons-checkboxes__label ons-u-fs-r--b" aria-hidden="true">Or</span>
          <div class="ons-input-items">
            <div class="ons-radios__items">
              <span class="ons-radios__item">
                <span class="ons-radio">
                  <input type="radio" id="no-central-heating-example-mutually-exclusive-multiple-options"
                    class="ons-radio__input ons-js-radio ons-js-exclusive-option" value="no-central-heating"
                    name="no central heating">
                  <label class=" ons-radio__label " for="no-central-heating-example-mutually-exclusive-multiple-options"
                    id="no-central-heating-example-mutually-exclusive-multiple-options-label">No central heating</label>
                </span>
              </span>
              <br>
              <span class="ons-radios__item">
                <span class="ons-radio">
                  <input type="radio" id="other-example-mutually-exclusive-multiple-options"
                    class="ons-radio__input ons-js-radio ons-js-exclusive-option" value="other"
                    name="no central heating">
                  <label class=" ons-radio__label " for="other-example-mutually-exclusive-multiple-options"
                    id="other-example-mutually-exclusive-multiple-options-label">Other</label>
                </span>
              </span>
            </div>
          </div>
          </p>
          <span class="ons-js-exclusive-alert ons-u-vh" role="alert" aria-live="polite"
            data-group-adjective="deselected" data-option-adjective="deselected"></span>
        </div>
      </div>
    </fieldset>
  </div>
</div>

How to check mutually exclusive answers

To help users answer a mandatory question using this component, you should:

  • check they have selected at least one checkbox
  • show an error message if they have not selected any checkbox, including the mutually exclusive checkbox
  • show an error message if they have not entered something in any of the fields or selected the mutually exclusive checkbox
  • show an error message if what has been entered in a field is not valid

Error messages

Use the correct errors pattern and show the error details above the fieldset.

Example Mutually Exclusive Date With Error contents

Nunjucks
{% from "components/date-input/_macro.njk" import onsDateInput %}

{{
    onsDateInput({
        "id": "date-mutually-exclusive-with-error",
        "legendOrLabel": "When did you leave your last paid job?",
        "legendClasses": "ons-u-vh",
        "day": {
            "label": {
                "text": "Day"
            },
            "name": "day-exclusive"
        },
        "month": {
            "label": {
                "text": "Month"
            },
            "name": "month-exclusive"
        },
        "year": {
            "label": {
                "text": "Year"
            },
            "name": "year-exclusive"
        },
        "mutuallyExclusive": {
            "or": "Or",
            "deselectMessage": "Selecting this will clear the date if one has been inputted",
            "deselectGroupAdjective": "cleared",
            "deselectExclusiveOptionAdjective": "deselected",
            "exclusiveOptions": [
                {
                    "id": "date-exclusive-checkbox-with-error",
                    "name": "no-paid-job",
                    "value": "no-paid-job",
                    "label": {
                        "text": "I have never had a paid job"
                    }
                }
            ]
        },
        "error": {
            "id": 'date-mutually-exclusive-error',
            "text": 'Enter when you left your last paid job'
        }
    })
}}
Nunjucks macro options
NameTypeRequiredDescription
idstringfalseThe HTML id of the fieldset
classesstringfalseClasses to apply to the fieldset
legendstringtrue (unless legendIsQuestionTitle is set)Text for the fieldset’s legend
legendClassesstringfalseClasses to apply to the legend element
legendIsQuestionTitlebooleantrue (unless legend is set)Creates an h1 inside the legend. Use when there is only a single fieldset on the page
descriptionstringfalseDescription for the fieldset
attributesobjectfalseHTML attributes (for example, data attributes) to add to the fieldset
exclusiveOptionsArray<Checkbox> or Array<radio>trueConfiguration for the mutually exclusive options
orstringfalseText for the “Or” label that separates the mutually exclusive checkbox from the answer options, defaults to "Or".
deselectMessagestringtrueThe text the aria-live alert will announce to warn that selecting the exclusive checkbox will clear or unselect all other answer options. For example, ”Selecting this will uncheck all other checkboxes”.
deselectGroupAdjectivestringtrueThe text the aria-live alert will announce when an answer option is cleared or unselected when the mutually exclusive checkbox is selected
deselectExclusiveOptionAdjectivestringtrueThe text the aria-live alert will announce when an option is cleared or unselected when the mutually exclusive checkbox is selected
errorError (ref)falseConfiguration for validation errors
dontWrapbooleanfalsePrevents fields,checkboxes,date input,duration,input and Textarea from being wrapped in a fieldset component
autosuggestresultsstringfalseShows suggested options to users as they enter something into an input field
HTML
<div class="ons-panel ons-panel--error ons-panel--no-title" id="date-mutually-exclusive-error">
  <span class="ons-panel__assistive-text ons-u-vh">Error: </span>
  <div class="ons-panel__body">
    <p class="ons-panel__error">
      <strong>Enter when you left your last paid job</strong>
    </p>
    <fieldset id="date-mutually-exclusive-with-error" class="ons-fieldset">
      <legend class="ons-fieldset__legend ons-u-vh"><span class="ons-fieldset__legend-title ons-u-pb-no">When did you
          leave your last paid job?</span></legend>
      <div class="ons-js-mutually-exclusive ons-mutually-exclusive">
        <div class="ons-field-group">
          <div class="ons-field">
            <label class="ons-label" for="date-mutually-exclusive-with-error-day"
              id="date-mutually-exclusive-with-error-day-label">Day</label>
            <input type="text" id="date-mutually-exclusive-with-error-day"
              class="ons-input ons-input--text ons-input-type__input  ons-input--error ons-js-exclusive-group-item ons-input-number--w-2"
              name="day-exclusive" min="1" max="31" maxlength="2" pattern="[0-9]*" inputmode="numeric" />
          </div>
          <div class="ons-field">
            <label class="ons-label" for="date-mutually-exclusive-with-error-month"
              id="date-mutually-exclusive-with-error-month-label">Month</label>
            <input type="text" id="date-mutually-exclusive-with-error-month"
              class="ons-input ons-input--text ons-input-type__input  ons-input--error ons-js-exclusive-group-item ons-input-number--w-2"
              name="month-exclusive" min="1" max="12" maxlength="2" pattern="[0-9]*" inputmode="numeric" />
          </div>
          <div class="ons-field">
            <label class="ons-label" for="date-mutually-exclusive-with-error-year"
              id="date-mutually-exclusive-with-error-year-label">Year</label>
            <input type="text" id="date-mutually-exclusive-with-error-year"
              class="ons-input ons-input--text ons-input-type__input  ons-input--error ons-js-exclusive-group-item ons-input-number--w-4"
              name="year-exclusive" min="1000" max="3000" maxlength="4" pattern="[0-9]*" inputmode="numeric" />
          </div>
        </div>
        <p class="ons-checkboxes--mutually-exclusive__item ons-u-mt-s">
          <span class="ons-checkboxes__label ons-u-fs-r--b" aria-hidden="true">Or</span>
          <span class="ons-checkbox">
            <input type="checkbox" id="date-exclusive-checkbox-with-error"
              class="ons-checkbox__input ons-js-checkbox ons-js-exclusive-option" value="no-paid-job" name="no-paid-job"
              data-deselect-message="Selecting this will clear the date if one has been inputted">
            <label class=" ons-checkbox__label " for="date-exclusive-checkbox-with-error"
              id="date-exclusive-checkbox-with-error-label"><span class="ons-u-vh">Or, </span> I have never had a paid
              job</label>
          </span>
        </p>
        <span class="ons-js-exclusive-alert ons-u-vh" role="alert" aria-live="polite" data-group-adjective="cleared"
          data-option-adjective="deselected"></span>
      </div>
    </fieldset>
  </div>
</div>

Error validation for this component varies according to the mutually exclusive answer type used.

If no option is selected for a checkbox-only answer

Use “Select [whatever it is]”.
For example, “Select what type of central heating you have”.

If all fields are empty and the mutually exclusive checkbox is not selected

Use “Enter [whatever the field asks for]”.
For example, “Enter your annual income before tax in 2018/19”.

If JavaScript is unavailable

If JavaScript is not available it is possible for the user to enter or select both an answer and the mutually exclusive checkbox.

If the mutually exclusive checkbox is selected as well as an answer checkbox

Use ‘Select [whatever it is], or select “[the mutually exclusive option]”’.
For example, ‘Select what type of central heating you have, or select “No central heating”’.

If the mutually exclusive checkbox is selected and an answer has been entered into the field

Use ‘Enter [whatever the field asks for], or select “[the mutually exclusive option]”’.
For example, ‘Enter your annual income before tax in 2018/19, or select “I prefer not to say”’.

Each pattern and component that uses the mutually exclusive component has specific guidance on writing error messages:

Help improve this page

Let us know how we could improve this page, or share your user research findings. Discuss the ‘Mutually Exclusive’ component on GitHub (opens in a new tab)