diff --git a/CHANGELOG.md b/CHANGELOG.md index 8476105665..08cf39de3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -208,6 +208,16 @@ If you’re not using Nunjucks macros, update your warning text HTML to replace This change was introduced in [pull request #3569: Remove unnecesary class from Warning Text component](https://github.com/alphagov/govuk-frontend/pull/3569). +#### Check that selects work as expected + +The `govukSelect` macro will no longer include an empty value attribute for options that do not have a value set. + +This means that the value of the select if that option is selected will now be the text content of the option, rather than an empty string. + +If you need to maintain the existing behaviour, you can set the value to an empty string. + +This change was introduced in [pull request #3773: Omit the value attribute from select options with no value](https://github.com/alphagov/govuk-frontend/pull/3773). + ## 4.6.0 (Feature release) ### New features diff --git a/packages/govuk-frontend/src/govuk/components/select/select.yaml b/packages/govuk-frontend/src/govuk/components/select/select.yaml index 1eb34e9a63..da5ffcee1a 100644 --- a/packages/govuk-frontend/src/govuk/components/select/select.yaml +++ b/packages/govuk-frontend/src/govuk/components/select/select.yaml @@ -15,7 +15,7 @@ params: - name: value type: string required: false - description: Value for the option item. Defaults to an empty string. + description: Value for the option. If this is omitted, the value is taken from the text content of the option element. - name: text type: string required: true @@ -231,11 +231,11 @@ examples: attributes: data-attribute: GHI data-second-attribute: JKL - - name: with falsey values + - name: with falsey items hidden: true data: - id: with-falsey-values - name: with-falsey-values + id: with-falsey-items + name: with-falsey-items label: text: Label text goes here items: @@ -300,6 +300,46 @@ examples: - value: 2 text: GOV.UK frontend option 2 + - name: without values + hidden: true + data: + name: colors + id: colors + label: + text: Label text goes here + items: + - text: Red + - text: Green + - text: Blue + + - name: without values with selected value + hidden: true + data: + name: colors + id: colors + label: + text: Label text goes here + items: + - text: Red + - text: Green + - text: Blue + value: Green + + - name: with falsey values + hidden: true + data: + name: falsey-values + id: falsey-values + label: + text: Label text goes here + items: + - text: Empty string + value: '' + - text: Boolean false + value: false + - text: Number zero + value: 0 + - name: item selected overrides value hidden: true data: diff --git a/packages/govuk-frontend/src/govuk/components/select/template.njk b/packages/govuk-frontend/src/govuk/components/select/template.njk index 5a71db49f9..77348750c3 100644 --- a/packages/govuk-frontend/src/govuk/components/select/template.njk +++ b/packages/govuk-frontend/src/govuk/components/select/template.njk @@ -44,8 +44,10 @@ {%- for attribute, value in params.attributes %} {{ attribute }}="{{ value }}"{% endfor %}> {% for item in params.items %} {% if item %} - {% endif %} diff --git a/packages/govuk-frontend/src/govuk/components/select/template.test.js b/packages/govuk-frontend/src/govuk/components/select/template.test.js index 86dc9e9b0b..6bf15e4bc1 100644 --- a/packages/govuk-frontend/src/govuk/components/select/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/select/template.test.js @@ -33,13 +33,43 @@ describe('Select', () => { expect($items.length).toEqual(3) }) - it('renders item with value', () => { + it('includes the value attribute', () => { const $ = render('select', examples.default) const $firstItem = $('.govuk-select option:first-child') expect($firstItem.attr('value')).toEqual('1') }) + it('includes the value attribute when the value option is an empty string', () => { + const $ = render('select', examples['with falsey values']) + + const $firstItem = $('.govuk-select option:nth(0)') + expect($firstItem.attr('value')).toEqual('') + }) + + it('includes the value attribute when the value option is false', () => { + const $ = render('select', examples['with falsey values']) + + const $secondItem = $('.govuk-select option:nth(1)') + expect($secondItem.attr('value')).toEqual('false') + }) + + it('includes the value attribute when the value option is 0', () => { + const $ = render('select', examples['with falsey values']) + + const $thirdItem = $('.govuk-select option:nth(2)') + expect($thirdItem.attr('value')).toEqual('0') + }) + + it('omits the value attribute if no value option is provided', () => { + const $ = render('select', examples['without values']) + + const $firstItem = $('.govuk-select option:first-child') + // Ideally we'd test for $firstItem.attr('value') == undefined but it's + // broken in Cheerio – https://github.com/cheeriojs/cheerio/issues/3237 + expect($firstItem.toString()).not.toContain('value') + }) + it('renders item with text', () => { const $ = render('select', examples.default) @@ -61,6 +91,13 @@ describe('Select', () => { expect($selectedItem.attr('selected')).toBeTruthy() }) + it('selects options with implicit value using selected value', () => { + const $ = render('select', examples['without values with selected value']) + + const $selectedItem = $("option:contains('Green')") + expect($selectedItem.attr('selected')).toBeTruthy() + }) + it('allows item.selected to override value', () => { const $ = render('select', examples['item selected overrides value']) @@ -90,7 +127,7 @@ describe('Select', () => { }) it('renders without falsely items', () => { - const $ = render('select', examples['with falsey values']) + const $ = render('select', examples['with falsey items']) const $items = $('.govuk-select option') expect($items.length).toEqual(2)