diff --git a/src/generators/dom/preprocess.ts b/src/generators/dom/preprocess.ts index 94b8ea444d..33a305146f 100644 --- a/src/generators/dom/preprocess.ts +++ b/src/generators/dom/preprocess.ts @@ -358,6 +358,19 @@ const preprocessors = { } }); + const valueAttribute = node.attributes.find((attribute: Node) => attribute.name === 'value'); + + // Treat these the same way: + // + // + if (node.name === 'option' && !valueAttribute) { + node.attributes.push({ + type: 'Attribute', + name: 'value', + value: node.children + }); + } + // special case — in a case like this... // // `? - const dependencies = block.findDependencies(value.value); + const dependencies = block.findDependencies(valueAttribute.value); state.selectBindingDependencies = dependencies; dependencies.forEach((prop: string) => { generator.indirectDependencies.set(prop, new Set()); diff --git a/src/generators/server-side-rendering/preprocess.ts b/src/generators/server-side-rendering/preprocess.ts index a8a790f754..afddae077c 100644 --- a/src/generators/server-side-rendering/preprocess.ts +++ b/src/generators/server-side-rendering/preprocess.ts @@ -69,6 +69,19 @@ const preprocessors = { if (slot && isChildOfComponent(node, generator)) { node.slotted = true; } + + // Treat these the same way: + // + // + const valueAttribute = node.attributes.find((attribute: Node) => attribute.name === 'value'); + + if (node.name === 'option' && !valueAttribute) { + node.attributes.push({ + type: 'Attribute', + name: 'value', + value: node.children + }); + } } if (node.children.length) { diff --git a/test/runtime/samples/binding-select-implicit-option-value/_config.js b/test/runtime/samples/binding-select-implicit-option-value/_config.js new file mode 100644 index 0000000000..40a7364797 --- /dev/null +++ b/test/runtime/samples/binding-select-implicit-option-value/_config.js @@ -0,0 +1,40 @@ +export default { + data: { + values: [1, 2, 3], + foo: 2 + }, + + html: ` + + +

foo: 2

+ `, + + test(assert, component, target, window) { + const select = target.querySelector('select'); + const options = [...target.querySelectorAll('option')]; + + assert.ok(options[1].selected); + assert.equal(component.get('foo'), 2); + + const change = new window.Event('change'); + + options[2].selected = true; + select.dispatchEvent(change); + + assert.equal(component.get('foo'), 3); + assert.htmlEqual( target.innerHTML, ` + + +

foo: 3

+ ` ); + } +}; diff --git a/test/runtime/samples/binding-select-implicit-option-value/main.html b/test/runtime/samples/binding-select-implicit-option-value/main.html new file mode 100644 index 0000000000..ec5cc84a8d --- /dev/null +++ b/test/runtime/samples/binding-select-implicit-option-value/main.html @@ -0,0 +1,7 @@ + + +

foo: {{foo}}

\ No newline at end of file