Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 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 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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ function get_value_from_dom(
if (name === 'group') {
const binding_group = get_binding_group(renderer, binding.node.expression.node);
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`;
Expand Down
11 changes: 7 additions & 4 deletions src/runtime/internal/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,15 @@ export function xlink_attr(node, attribute, value) {
node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);
}

export function get_binding_group_value(group) {
const value = [];
export function get_binding_group_value(group, __value, checked) {
const value = new Set();
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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
},
};
Original file line number Diff line number Diff line change
@@ -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>