From 8cf037c90461c5ce2fb0f0c552868d045d5c9b3f Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Mon, 27 Feb 2023 06:11:06 -0600 Subject: [PATCH] fix: select first enabled option by default when initial value is undefined (#8331) Fixes an unintended regression introduced in #6170. Fixes #7041 --- src/runtime/internal/dom.ts | 10 +++++- .../_config.js | 4 ++- .../main.svelte | 1 + .../binding-select-unmatched/_config.js | 35 +++++++++++++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index 52f1198833..23c0fdac51 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -567,8 +567,16 @@ export function select_options(select, value) { } } +function first_enabled_option(select) { + for (const option of select.options) { + if (!option.disabled) { + return option; + } + } +} + export function select_value(select) { - const selected_option = select.querySelector(':checked') || select.options[0]; + const selected_option = select.querySelector(':checked') || first_enabled_option(select); return selected_option && selected_option.__value; } diff --git a/test/runtime/samples/binding-select-initial-value-undefined/_config.js b/test/runtime/samples/binding-select-initial-value-undefined/_config.js index 27bac7ef77..c95cd44046 100644 --- a/test/runtime/samples/binding-select-initial-value-undefined/_config.js +++ b/test/runtime/samples/binding-select-initial-value-undefined/_config.js @@ -5,6 +5,7 @@ export default {

selected: a

+ diff --git a/test/runtime/samples/binding-select-unmatched/_config.js b/test/runtime/samples/binding-select-unmatched/_config.js index 99e7d23927..45594407b3 100644 --- a/test/runtime/samples/binding-select-unmatched/_config.js +++ b/test/runtime/samples/binding-select-unmatched/_config.js @@ -56,5 +56,40 @@ export default {

selected: d

`); + + component.selected = 'b'; // second option should now be selected + assert.equal(select.value, 'b'); + assert.ok(options[1].selected); + + assert.htmlEqual(target.innerHTML, ` +

selected: b

+ + + +

selected: b

+ `); + + component.selected = undefined; // also doesn't match an option + + // now no option should be selected again + assert.equal(select.value, ''); + assert.equal(select.selectedIndex, -1); + assert.ok(!options[0].selected); + + assert.htmlEqual(target.innerHTML, ` +

selected: undefined

+ + + +

selected: undefined

+ `); } };