use <option> children as value attribute, if none exists. fixes #928

pull/931/head
Rich Harris 7 years ago
parent 4411ab116e
commit 7e07cde021

@ -358,6 +358,19 @@ const preprocessors = {
}
});
const valueAttribute = node.attributes.find((attribute: Node) => attribute.name === 'value');
// Treat these the same way:
// <option>{{foo}}</option>
// <option value='{{foo}}'>{{foo}}</option>
if (node.name === 'option' && !valueAttribute) {
node.attributes.push({
type: 'Attribute',
name: 'value',
value: node.children
});
}
// special case — in a case like this...
//
// <select bind:value='foo'>
@ -369,12 +382,9 @@ const preprocessors = {
// so that if `foo.qux` changes, we know that we need to
// mark `bar` and `baz` as dirty too
if (node.name === 'select') {
const value = node.attributes.find(
(attribute: Node) => attribute.name === 'value'
);
if (value) {
if (valueAttribute) {
// TODO does this also apply to e.g. `<input type='checkbox' bind:group='foo'>`?
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());

@ -69,6 +69,19 @@ const preprocessors = {
if (slot && isChildOfComponent(node, generator)) {
node.slotted = true;
}
// Treat these the same way:
// <option>{{foo}}</option>
// <option value='{{foo}}'>{{foo}}</option>
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) {

@ -0,0 +1,40 @@
export default {
data: {
values: [1, 2, 3],
foo: 2
},
html: `
<select>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
</select>
<p>foo: 2</p>
`,
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, `
<select>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
</select>
<p>foo: 3</p>
` );
}
};

@ -0,0 +1,7 @@
<select bind:value='foo'>
{{#each values as v}}
<option>{{v}}</option>
{{/each}}
</select>
<p>foo: {{foo}}</p>
Loading…
Cancel
Save