Kevin Renskers
Kevin Renskers

Reputation: 5950

Svelte: grouped checkbox binding problem when showing and hiding checkboxes

The problem is best shown with an actual example.

<script>
    let searchInput = '';
    let values = ['a', 'b', 'c', 'd', 'e', 'f'];
    $: filteredValues = searchInput ? values.filter(v => v.toLowerCase().includes(searchInput.toLowerCase())) : values;
    
    let chosenValues = [];
</script>

<input type="search" placeholder="Search" bind:value={searchInput} />

{#each filteredValues as value (value)}
    <div class="checkbox">
        <input type="checkbox" bind:group={chosenValues} value={value} />
        {value}
  </div>
{/each}

{chosenValues}

Also available on the REPL: https://svelte.dev/repl/5af87332d81e4d82835bcd0f47ff9d81?version=3.44.1.

The problem happens as follows:

  1. You select options a and b
  2. You search for c
  3. You select option c

Now the chosenValues only holds c; a and b are gone. I guess I could loop over all the values and hide the ones not part of hiddenValues, so that they're still part of the DOM, but why does this even happen, and is there an easier way to deal with this?

Upvotes: 2

Views: 796

Answers (1)

Stephane Vanraes
Stephane Vanraes

Reputation: 16451

This happens because bind:group will only consider the inputs that are actually rendered, as you say one option would be to loop over all the values and use some css to hide the invisible ones.

Another option is to handle the binding by yourself.

<script>
 let chosenValues = []
 function handleChange(ev) {
   const { checked, value } = ev.target
   if (checked) {
     chosenValues = [...chosenValues, value]
   } else {
     chosenValues = chosenValues.filter(v => v !== value)
   }
 }
</script>

{#each ....}
  <input {value} checked={chosenValues.includes(value)} on:change={handleChange}>
{/each}

Upvotes: 5

Related Questions