alphagov / govuk-frontend

GOV.UK Frontend contains the code you need to start building a user interface for government platforms and services.
https://frontend.design-system.service.gov.uk/
MIT License
1.18k stars 325 forks source link

Reveal named div on radio select #718

Closed alextea closed 6 years ago

alextea commented 6 years ago

In some layouts it would be useful to reveal a div below the set of radio buttons based on the option selected.

The markup could work a bit like this:

{{ govukRadios ({
  "id-prefix": "example",
  "name": "example",
  "fieldset": {
    "legend": {
      "text": "Example",
      "isPageHeading": false,
      "classes": 'govuk-fieldset__legend--m'
    }
  },
  "items": [
    {
      "value": "1",
      "text": "Option 1",
      "conditional": {
        "id": element_id
      }
    },
    {
      "value": "2",
      "text": "Option 2",
      "conditional": {
        "id": element_id
      }
    }
  ]
}) }}
kr8n3r commented 6 years ago

Hi @alextea, thanks for raising this. We will add this to our backlog and see if and when we can prioritise this.

NickColley commented 6 years ago

Until we have something better, a work around you can use is to structure your markup like so

<div data-module="radios">
  <div class="govuk-radios">
    <!-- items here -->
  </div>  
  <!-- other stuff here -->
  <div id="conditional-reveal"></div>
</div>
kr8n3r commented 6 years ago

Hi @alextea, could you share more insight about the use-case of this, or any research conducted? It might be something for the GOV.UK Design System Backlog

Design system team trello ticket

NickColley commented 6 years ago

We're intending to fix the inline radios with conditional reveal which should address some of the issues here.

https://github.com/alphagov/govuk-frontend/issues/754

In the meantime you can use the HTML approach, if you find yourself needing to do this in the future, please raise in the backlog as Jani says above.

Thanks for raising.

NickColley commented 5 years ago

This has also been raised by another community member who wanted to be able to do something like this:

{{ govukRadios({
        classes: "govuk-radios--inline",
        idPrefix: "basedInTheUK",
        name: "createNewAccount.basedInTheUK",
        fieldset: {},
        items: [
          {
            value: "yes",
            text: "Yes",
            checked: checked("createNewAccount.basedInTheUK",'yes'),
            attributes: 
              {
                "data-aria-controls": "hidden-representative-email"
              }
          },
          {
            value: "no",
            text: "No",
            checked: checked("createNewAccount.basedInTheUK",'no')
          }
        ]
      }) }}
gonogo commented 5 years ago

We've found a workaround that isn't too clunky:

  <fieldset class="govuk-fieldset">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--l">
      <h1 class="govuk-fieldset__heading">
        Do you want to add a representative to the account now?
      </h1>
    </legend>
    <p>If you want to trade on the account you'll need to add another individual to the account</p>
    <div class="govuk-radios--inline govuk-radios--conditional" data-module="radios">
      <div class="govuk-radios__item">
        <input class="govuk-radios__input" id="add-rep-1" name="createNewAccount.addRep" type="radio" value="yes" aria-controls="hidden-representative-email" aria-expanded="false" {{ checked("createNewAccount.addRep",'yes') }}>
        <label class="govuk-label govuk-radios__label" for="add-rep-1">
          Yes
        </label>
      </div>
      <div class="govuk-radios__item">
        <input class="govuk-radios__input" id="add-rep-2" name="createNewAccount.addRep" type="radio" value="no" {{ checked("createNewAccount.addRep",'no') }}>
        <label class="govuk-label govuk-radios__label" for="add-rep-2">
          No
        </label>
      </div>
      <div class="{% if (data.createNewAccount.addRep == "no") or ( not data.createNewAccount.addRep) %} govuk-radios__conditional--hidden {% endif %} govuk-!-padding-top-5" id="hidden-representative-email">
        <h2 class="govuk-heading-m">
          Invite a representative to the account
        </h2>
        {{ govukInput({
        id: "rep-email-address",
        name: "createNewAccount.repEmailAddress",
        classes: "govuk-input--width-20 format-number",
        label: {
            text: "Enter their email address"
        },
        value: data.createNewAccount.repEmailAddress
        }) }}
      </div>
    </div>
  </fieldset>
</div>

Would be nice to find a more concise way of doing this bit:

{% if (data.createNewAccount.addRep == "no") or ( not data.createNewAccount.addRep) %}

Any ideas?

36degrees commented 5 years ago

Separating content from other content from which it is associated with in the markup needs particular consideration with regards to assistive technologies.

If we were going to introduce this as a proper feature, we'd need to be confident that it could be done in such a way that it didn't introduce barriers for users of assistive technologies – especially screen readers and magnification tools.

We'd need to see evidence from user research with those users (of mixed abilities, i.e. not just 'power' users), showing that conditionally revealing another element elsewhere on the page (as in, not immediately following the radio button / checkbox) is clearly communicated to the user, that they understand that something has happened and how to navigate to the revealed controls.

We'd also need to see examples of cases where this pattern is shown to provide a better experience than e.g. splitting the form over multiple pages or using the existing conditional reveal pattern where the content is revealed immediately after the control.