Reputation: 63
I'm trying to set up a list of checkboxes and a button which allows toggling all the buttons, my code below:
<script>
const items = ["a", "b", "c"]
let selected = [];
function toggleAll() {
if (selected.length === 0) {
selected = [...items]
} else {
selected = [];
}
}
</script>
<div>
{selected.length} Selected
<div>
<input
type="checkbox"
on:click|preventDefault={toggleAll}
checked={selected.length === items.length}
/>
<strong>All</strong>
</div>
{#each items as item}
<div>
<input type="checkbox" bind:group={selected} name={item} value={item} />
{item}
</div>
{/each}
</div>
This has some weird behaviour, if I click the all checkbox all the items are checked but not the all checkbox, but if I click each item without pressing the all checkbox it then is checked.
I think the preventDefault is doing something, because if I remove that the all works as expected, but then checking 1 item, then checking the all checkbox leaves the all checked and none of the items.
Upvotes: 3
Views: 1787
Reputation: 7721
I think the preventDefault
has no effect but it's the logic inside toggleAll
- selecting all is the priority?
If the 'master' checkbox is clicked when not all other checkboxes are checked -> select all.
If all are checked -> deselect all.
REPL
<script>
const items = ["a", "b", "c"]
let selected = [];
$: allSelected = items.length === selected.length
function toggleAll() {
if (allSelected) {
selected = [];
} else {
selected = [...items]
}
}
</script>
<div>
{selected.length} Selected
<div>
<input
type="checkbox"
on:click={toggleAll}
checked={allSelected}
/>
<strong>All</strong>
</div>
{#each items as item}
<div>
<input type="checkbox" bind:group={selected} name={item} value={item} />
{item}
</div>
{/each}
</div>
Upvotes: 2
Reputation: 185225
I would use the change
event and the current DOM checked
state to toggle:
<input
type="checkbox"
on:change={toggleAll}
checked={selected.length === items.length} />
function toggleAll(e) {
selected = e.target.checked ? [...items] : [];
}
Btw, you should use label
elements to label form inputs.
Upvotes: 3