fix bind:group with duplicated values (#4877)

pull/4994/head
Tan Li Hau 5 years ago committed by GitHub
parent e75831201e
commit 787ece66a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,6 +2,7 @@
## Unreleased ## Unreleased
* Fix checkbox `bind:group` when multiple options have the same value ([#4397](https://github.com/sveltejs/svelte/issues/4397))
* Fix `bind:this` to the value of an `{#each}` block ([#4517](https://github.com/sveltejs/svelte/issues/4517)) * Fix `bind:this` to the value of an `{#each}` block ([#4517](https://github.com/sveltejs/svelte/issues/4517))
* Fix reactivity when assigning to contextual `{#each}` variable ([#4574](https://github.com/sveltejs/svelte/issues/4574), [#4744](https://github.com/sveltejs/svelte/issues/4744)) * Fix reactivity when assigning to contextual `{#each}` variable ([#4574](https://github.com/sveltejs/svelte/issues/4574), [#4744](https://github.com/sveltejs/svelte/issues/4744))
* Fix binding to contextual `{#each}` values that shadow outer names ([#4757](https://github.com/sveltejs/svelte/issues/4757)) * Fix binding to contextual `{#each}` values that shadow outer names ([#4757](https://github.com/sveltejs/svelte/issues/4757))

@ -335,7 +335,7 @@ function get_value_from_dom(
if (name === 'group') { if (name === 'group') {
const binding_group = get_binding_group(renderer, binding.node.expression.node); const binding_group = get_binding_group(renderer, binding.node.expression.node);
if (type === 'checkbox') { if (type === 'checkbox') {
return x`@get_binding_group_value($$binding_groups[${binding_group}])`; return x`@get_binding_group_value($$binding_groups[${binding_group}], this.__value, this.checked)`;
} }
return x`this.__value`; return x`this.__value`;

@ -126,12 +126,15 @@ export function xlink_attr(node, attribute, value) {
node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value); node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);
} }
export function get_binding_group_value(group) { export function get_binding_group_value(group, __value, checked) {
const value = []; const value = new Set();
for (let i = 0; i < group.length; i += 1) { for (let i = 0; i < group.length; i += 1) {
if (group[i].checked) value.push(group[i].__value); if (group[i].checked) value.add(group[i].__value);
} }
return value; if (!checked) {
value.delete(__value);
}
return Array.from(value);
} }
export function to_number(value) { export function to_number(value) {

@ -0,0 +1,81 @@
export default {
html: `
<p>Checked: </p>
<hr>
<input type='checkbox' value='a'>a<br>
<input type='checkbox' value='b'>b<br>
<input type='checkbox' value='c'>c<br>
<input type='checkbox' value='d'>d<br>
<hr>
<input type='checkbox' value='a'>a<br>
<input type='checkbox' value='b'>b<br>
<input type='checkbox' value='c'>c<br>
<input type='checkbox' value='d'>d<br>
`,
async test({ assert, component, target, window }) {
const inputs = target.querySelectorAll("input");
const p = target.querySelector("p");
assert.equal(inputs[0].checked, false);
assert.equal(inputs[1].checked, false);
assert.equal(inputs[2].checked, false);
assert.equal(inputs[3].checked, false);
assert.equal(inputs[4].checked, false);
assert.equal(inputs[5].checked, false);
assert.equal(inputs[6].checked, false);
assert.equal(inputs[7].checked, false);
const event = new window.Event("change");
inputs[0].checked = true;
await inputs[0].dispatchEvent(event);
assert.htmlEqual(p.innerHTML, `Checked: a`);
assert.equal(inputs[0].checked, true);
assert.equal(inputs[1].checked, false);
assert.equal(inputs[2].checked, false);
assert.equal(inputs[3].checked, false);
assert.equal(inputs[4].checked, true);
assert.equal(inputs[5].checked, false);
assert.equal(inputs[6].checked, false);
assert.equal(inputs[7].checked, false);
inputs[3].checked = true;
await inputs[3].dispatchEvent(event);
assert.htmlEqual(p.innerHTML, `Checked: a,d`);
assert.equal(inputs[0].checked, true);
assert.equal(inputs[1].checked, false);
assert.equal(inputs[2].checked, false);
assert.equal(inputs[3].checked, true);
assert.equal(inputs[4].checked, true);
assert.equal(inputs[5].checked, false);
assert.equal(inputs[6].checked, false);
assert.equal(inputs[7].checked, true);
inputs[4].checked = false;
await inputs[4].dispatchEvent(event);
assert.htmlEqual(p.innerHTML, `Checked: d`);
assert.equal(inputs[0].checked, false);
assert.equal(inputs[1].checked, false);
assert.equal(inputs[2].checked, false);
assert.equal(inputs[3].checked, true);
assert.equal(inputs[4].checked, false);
assert.equal(inputs[5].checked, false);
assert.equal(inputs[6].checked, false);
assert.equal(inputs[7].checked, true);
},
};

@ -0,0 +1,19 @@
<script>
let foo = [];
</script>
<p>Checked: {foo}</p>
<hr>
<input type='checkbox' bind:group={foo} value='a'>a<br>
<input type='checkbox' bind:group={foo} value='b'>b<br>
<input type='checkbox' bind:group={foo} value='c'>c<br>
<input type='checkbox' bind:group={foo} value='d'>d<br>
<hr>
<input type='checkbox' bind:group={foo} value='a'>a<br>
<input type='checkbox' bind:group={foo} value='b'>b<br>
<input type='checkbox' bind:group={foo} value='c'>c<br>
<input type='checkbox' bind:group={foo} value='d'>d<br>
Loading…
Cancel
Save