Merge pull request #3731 from alphagov/add-govuk-radios-5

Add GOVUK radios [part 5]
This commit is contained in:
Tom Byers
2020-12-16 14:48:49 +00:00
committed by GitHub
9 changed files with 71 additions and 73 deletions

View File

@@ -4,7 +4,7 @@
$ = global.jQuery; $ = global.jQuery;
let branding_style = $('.multiple-choice input[name="branding_style"]:checked'); let branding_style = $('.govuk-radios__item input[name="branding_style"]:checked');
if (!branding_style.length) { return; } if (!branding_style.length) { return; }

View File

@@ -951,6 +951,10 @@ class OrganisationTypeField(GovukRadiosField):
) )
class GovukRadiosFieldWithNoneOption(FieldWithNoneOption, GovukRadiosField):
pass
# guard against data entries that aren't a role in permissions # guard against data entries that aren't a role in permissions
def filter_by_permissions(valuelist): def filter_by_permissions(valuelist):
if valuelist is None: if valuelist is None:
@@ -1728,8 +1732,9 @@ class ServiceSwitchChannelForm(ServiceOnOffSettingForm):
class SetEmailBranding(StripWhitespaceForm): class SetEmailBranding(StripWhitespaceForm):
branding_style = RadioFieldWithNoneOption( branding_style = GovukRadiosFieldWithNoneOption(
'Branding style', 'Branding style',
param_extensions={'fieldset': {'legend': {'classes': 'govuk-visually-hidden'}}},
thing='a branding style', thing='a branding style',
) )

View File

@@ -1,5 +1,4 @@
{% extends "org_template.html" %} {% extends "org_template.html" %}
{% from "components/radios.html" import radios %}
{% from "components/page-footer.html" import page_footer %} {% from "components/page-footer.html" import page_footer %}
{% from "components/page-header.html" import page_header %} {% from "components/page-header.html" import page_header %}
{% from "components/live-search.html" import live_search %} {% from "components/live-search.html" import live_search %}
@@ -25,13 +24,13 @@
<div class="govuk-grid-row"> <div class="govuk-grid-row">
<div class="govuk-grid-column-full"> <div class="govuk-grid-column-full">
{{ live_search( {{ live_search(
target_selector='.multiple-choice', target_selector='.govuk-radios__item',
show=True, show=True,
form=search_form, form=search_form,
label='Search branding styles by name', label='Search branding styles by name',
autofocus=True autofocus=True
) }} ) }}
{{ radios(form.branding_style) }} {{ form.branding_style }}
</div> </div>
</div> </div>
<div class="js-stick-at-bottom-when-scrolling"> <div class="js-stick-at-bottom-when-scrolling">

View File

@@ -1,5 +1,4 @@
{% extends "org_template.html" %} {% extends "org_template.html" %}
{% from "components/radios.html" import radios %}
{% from "components/live-search.html" import live_search %} {% from "components/live-search.html" import live_search %}
{% from "components/page-footer.html" import page_footer %} {% from "components/page-footer.html" import page_footer %}
{% from "components/page-header.html" import page_header %} {% from "components/page-header.html" import page_header %}
@@ -25,13 +24,13 @@
<div class="govuk-grid-row"> <div class="govuk-grid-row">
<div class="govuk-grid-column-full"> <div class="govuk-grid-column-full">
{{ live_search( {{ live_search(
target_selector='.multiple-choice', target_selector='.govuk-radios__item',
show=True, show=True,
form=search_form, form=search_form,
label='Search by name', label='Search by name',
autofocus=True autofocus=True
) }} ) }}
{{ radios(form.branding_style, hide_legend=True) }} {{ form.branding_style }}
</div> </div>
</div> </div>
<div class="js-stick-at-bottom-when-scrolling"> <div class="js-stick-at-bottom-when-scrolling">

View File

@@ -1,5 +1,4 @@
{% extends "withnav_template.html" %} {% extends "withnav_template.html" %}
{% from "components/radios.html" import radios %}
{% from "components/page-header.html" import page_header %} {% from "components/page-header.html" import page_header %}
{% from "components/page-footer.html" import page_footer, sticky_page_footer %} {% from "components/page-footer.html" import page_footer, sticky_page_footer %}
{% from "components/live-search.html" import live_search %} {% from "components/live-search.html" import live_search %}
@@ -25,13 +24,13 @@
<div class="govuk-grid-row"> <div class="govuk-grid-row">
<div class="govuk-grid-column-full"> <div class="govuk-grid-column-full">
{{ live_search( {{ live_search(
target_selector='.multiple-choice', target_selector='.govuk-radios__item',
show=True, show=True,
form=search_form, form=search_form,
label='Search branding styles by name', label='Search branding styles by name',
autofocus=True autofocus=True
) }} ) }}
{{ radios(form.branding_style) }} {{ form.branding_style }}
</div> </div>
</div> </div>
{{ sticky_page_footer('Preview') }} {{ sticky_page_footer('Preview') }}

View File

@@ -1,5 +1,4 @@
{% extends "withnav_template.html" %} {% extends "withnav_template.html" %}
{% from "components/radios.html" import radios %}
{% from "components/live-search.html" import live_search %} {% from "components/live-search.html" import live_search %}
{% from "components/page-header.html" import page_header %} {% from "components/page-header.html" import page_header %}
{% from "components/page-footer.html" import page_footer %} {% from "components/page-footer.html" import page_footer %}
@@ -25,13 +24,13 @@
<div class="govuk-grid-row"> <div class="govuk-grid-row">
<div class="govuk-grid-column-full"> <div class="govuk-grid-column-full">
{{ live_search( {{ live_search(
target_selector='.multiple-choice', target_selector='.govuk-radios__item',
show=True, show=True,
form=search_form, form=search_form,
label='Search by name', label='Search by name',
autofocus=True autofocus=True
) }} ) }}
{{ radios(form.branding_style, hide_legend=True) }} {{ form.branding_style }}
</div> </div>
</div> </div>
<div class="js-stick-at-bottom-when-scrolling"> <div class="js-stick-at-bottom-when-scrolling">

View File

@@ -29,51 +29,42 @@ describe('Live search', () => {
searchLabelText = "Search branding styles by name"; searchLabelText = "Search branding styles by name";
function getRadiosHTML (departments) {
let result = '';
departments.forEach((department, idx) => result += `
<div class="multiple-choice">
<input id="${department.id}" name="${department.name}" type="radio" value="${department.id}">
<label class="block-label" for="${department.id}">
${department.label}
</label>
</div>
`);
return result;
};
beforeEach(() => { beforeEach(() => {
const departments = [ const departmentData = {
{ name: 'departments',
'label': 'NHS', hideLegend: true,
'id': 'nhs', fields: [
'name': 'branding' {
}, 'label': 'NHS',
{ 'id': 'nhs',
'label': 'Department for Work and Pensions', 'name': 'branding',
'id': 'dwp', 'value': 'nhs'
'name': 'branding' },
}, {
{ 'label': 'Department for Work and Pensions',
'label': 'Department for Education', 'id': 'dwp',
'id': 'dfe', 'name': 'branding',
'name': 'branding' 'value': 'dwp'
}, },
{ {
'label': 'Home Office', 'label': 'Department for Education',
'id': 'home-office', 'id': 'dfe',
'name': 'branding' 'name': 'branding',
} 'value': 'dfe'
]; },
{
'label': 'Home Office',
'id': 'home-office',
'name': 'branding',
'value': 'home-office'
}
]
};
// set up DOM // set up DOM
document.body.innerHTML = ` document.body.innerHTML = `
<div class="live-search js-header" data-module="live-search" data-targets=".multiple-choice"> <div class="live-search js-header" data-module="live-search" data-targets=".govuk-radios__item">
<div class="form-group"> <div class="form-group">
<label class="form-label" for="search"> <label class="form-label" for="search">
${searchLabelText} ${searchLabelText}
@@ -83,13 +74,15 @@ describe('Live search', () => {
</div> </div>
</div> </div>
<form method="post" autocomplete="off" novalidate> <form method="post" autocomplete="off" novalidate>
${getRadiosHTML(departments)}
</form>`; </form>`;
searchTextbox = document.getElementById('search'); searchTextbox = document.getElementById('search');
liveRegion = document.querySelector('.live-search__status'); liveRegion = document.querySelector('.live-search__status');
list = document.querySelector('form'); list = document.querySelector('form');
// getRadioGroup returns a DOM node so append once DOM is set up
list.appendChild(helpers.getRadioGroup(departmentData));
}); });
describe("When the page loads", () => { describe("When the page loads", () => {
@@ -99,7 +92,7 @@ describe('Live search', () => {
// start the module // start the module
window.GOVUK.modules.start(); window.GOVUK.modules.start();
const listItems = list.querySelectorAll('.multiple-choice'); const listItems = list.querySelectorAll('.govuk-radios__item');
const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none'); const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none');
expect(listItemsShowing.length).toEqual(listItems.length); expect(listItemsShowing.length).toEqual(listItems.length);
@@ -114,7 +107,7 @@ describe('Live search', () => {
// start the module // start the module
window.GOVUK.modules.start(); window.GOVUK.modules.start();
const listItems = list.querySelectorAll('.multiple-choice'); const listItems = list.querySelectorAll('.govuk-radios__item');
const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none'); const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none');
expect(listItemsShowing.length).toEqual(2); expect(listItemsShowing.length).toEqual(2);
@@ -130,7 +123,7 @@ describe('Live search', () => {
// start the module // start the module
window.GOVUK.modules.start(); window.GOVUK.modules.start();
const listItems = list.querySelectorAll('.multiple-choice'); const listItems = list.querySelectorAll('.govuk-radios__item');
const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none'); const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none');
expect(listItemsShowing.length).toEqual(1); expect(listItemsShowing.length).toEqual(1);
@@ -169,7 +162,7 @@ describe('Live search', () => {
searchTextbox.value = ''; searchTextbox.value = '';
helpers.triggerEvent(searchTextbox, 'input'); helpers.triggerEvent(searchTextbox, 'input');
const listItems = list.querySelectorAll('.multiple-choice'); const listItems = list.querySelectorAll('.govuk-radios__item');
const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none'); const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none');
expect(listItemsShowing.length).toEqual(listItems.length); expect(listItemsShowing.length).toEqual(listItems.length);
@@ -188,7 +181,7 @@ describe('Live search', () => {
searchTextbox.value = 'Home'; searchTextbox.value = 'Home';
helpers.triggerEvent(searchTextbox, 'input'); helpers.triggerEvent(searchTextbox, 'input');
const listItems = list.querySelectorAll('.multiple-choice'); const listItems = list.querySelectorAll('.govuk-radios__item');
const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none'); const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none');
expect(listItemsShowing.length).toEqual(1); expect(listItemsShowing.length).toEqual(1);
@@ -207,7 +200,7 @@ describe('Live search', () => {
searchTextbox.value = 'Department for'; searchTextbox.value = 'Department for';
helpers.triggerEvent(searchTextbox, 'input'); helpers.triggerEvent(searchTextbox, 'input');
const listItems = list.querySelectorAll('.multiple-choice'); const listItems = list.querySelectorAll('.govuk-radios__item');
const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none'); const listItemsShowing = Array.from(listItems).filter(item => window.getComputedStyle(item).display !== 'none');
expect(listItemsShowing.length).toEqual(2); expect(listItemsShowing.length).toEqual(2);

View File

@@ -65,7 +65,7 @@ describe('Preview pane', () => {
<div class="govuk-grid-row"> <div class="govuk-grid-row">
<div class="govuk-grid-column-full"> <div class="govuk-grid-column-full">
<div data-module="autofocus"> <div data-module="autofocus">
<div class="live-search js-header" data-module="live-search" data-targets=".multiple-choice"> <div class="live-search js-header" data-module="live-search" data-targets=".govuk-radios__item">
<div class="form-group"> <div class="form-group">
<label class="form-label" for="search"> <label class="form-label" for="search">
Search branding styles by name Search branding styles by name

View File

@@ -5,11 +5,12 @@ function getRadios (fields, name) {
return fields.map((field, idx) => { return fields.map((field, idx) => {
const count = idx + 1; const count = idx + 1;
const id = field.id || `${name}-${count}`;
return ` return `
<div class="multiple-choice"> <div class="govuk-radios__item">
<input id="${name}-1" name="${name}" type="radio" value="${field.value}" ${field.checked ? 'checked' : ''}> <input class="govuk-radios__input" id="${id}" name="${name}" type="radio" value="${field.value}" ${field.checked ? 'checked' : ''}>
<label class="block-label" for="${name}-1"> <label class="govuk-label govuk-radios__label" for="${id}">
${field.label} ${field.label}
</label> </label>
</div>`; </div>`;
@@ -19,16 +20,19 @@ function getRadios (fields, name) {
function getRadioGroup (data) { function getRadioGroup (data) {
let radioGroup = document.createElement('div'); let radioGroup = document.createElement('div');
data.cssClasses.forEach(cssClass => radioGroup.classList.add(cssClass)); radioGroup.classList.add('govuk-form-group');
if ('cssClasses' in data) {
data.cssClasses.forEach(cssClass => radioGroup.classList.add(cssClass));
}
radioGroup.innerHTML = ` radioGroup.innerHTML = `
<div class="form-group "> <fieldset class="govuk-fieldset" id="${data.name}">
<fieldset id="${data.name}"> <legend class="govuk-fieldset__legend${data.hideLegend ? " govuk-visually-hidden" : ""}">
<legend class="form-label"> ${data.label}
${data.label} </legend>
</legend> <div class="govuk-radios">
${getRadios(data.fields, data.name)} ${getRadios(data.fields, data.name)}
</fieldset> </div>
</div>`; </fieldset>`;
return radioGroup; return radioGroup;
}; };