Skip to content

Commit 09b1635

Browse files
authored
Merge pull request #521 from sveltejs/select-change-handler
[WIP] Fix select change handler
2 parents fbfd011 + 1cd2287 commit 09b1635

File tree

3 files changed

+54
-17
lines changed

3 files changed

+54
-17
lines changed

src/generators/dom/visitors/Element/Element.js

+15-17
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,19 @@ export default function visitElement ( generator, block, state, node ) {
5656
block.builders.create.addLine( `${generator.helper( 'setAttribute' )}( ${name}, '${generator.cssId}', '' );` );
5757
}
5858

59-
let selectValueAttribute;
60-
61-
node.attributes
62-
.sort( ( a, b ) => order[ a.type ] - order[ b.type ] )
63-
.forEach( attribute => {
64-
// <select> value attributes are an annoying special case — it must be handled
65-
// *after* its children have been updated
66-
if ( ( attribute.type === 'Attribute' || attribute.type === 'Binding' ) && attribute.name === 'value' && node.name === 'select' ) {
67-
selectValueAttribute = attribute;
68-
return;
69-
}
70-
71-
visitors[ attribute.type ]( generator, block, childState, node, attribute );
72-
});
59+
function visitAttributes () {
60+
node.attributes
61+
.sort( ( a, b ) => order[ a.type ] - order[ b.type ] )
62+
.forEach( attribute => {
63+
visitors[ attribute.type ]( generator, block, childState, node, attribute );
64+
});
65+
}
66+
67+
if ( node.name !== 'select' ) {
68+
// <select> value attributes are an annoying special case — it must be handled
69+
// *after* its children have been updated
70+
visitAttributes();
71+
}
7372

7473
// special case – bound <option> without a value attribute
7574
if ( node.name === 'option' && !node.attributes.find( attribute => attribute.type === 'Attribute' && attribute.name === 'value' ) ) { // TODO check it's bound
@@ -116,9 +115,8 @@ export default function visitElement ( generator, block, state, node ) {
116115
block.builders.update.addLine( node.lateUpdate );
117116
}
118117

119-
if ( selectValueAttribute ) {
120-
const visitor = selectValueAttribute.type === 'Attribute' ? visitAttribute : visitBinding;
121-
visitor( generator, block, childState, node, selectValueAttribute );
118+
if ( node.name === 'select' ) {
119+
visitAttributes();
122120
}
123121

124122
if ( node.initialUpdate ) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export default {
2+
skip: true, // JSDOM
3+
4+
data: {
5+
options: [ { id: 'a' }, { id: 'b' }, { id: 'c' } ],
6+
selected: 'b'
7+
},
8+
9+
test ( assert, component, target, window ) {
10+
const select = target.querySelector( 'select' );
11+
assert.equal( select.value, 'b' );
12+
13+
const event = new window.Event( 'change' );
14+
15+
select.value = 'c';
16+
select.dispatchEvent( event );
17+
18+
assert.equal( select.value, 'c' );
19+
assert.equal( component.get( 'lastChangedTo' ), 'c' );
20+
assert.equal( component.get( 'selected' ), 'c' );
21+
22+
component.destroy();
23+
}
24+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<select bind:value="selected" on:change="updateLastChangedTo(selected)">
2+
{{#each options as option}}
3+
<option value="{{option.id}}">{{option.id}}</option>
4+
{{/each}}
5+
</select>
6+
7+
<script>
8+
export default {
9+
methods: {
10+
updateLastChangedTo(result) {
11+
this.set({ lastChangedTo: result });
12+
}
13+
}
14+
};
15+
</script>

0 commit comments

Comments
 (0)