Reputation: 320
Below is the code to reproduce my problem (Svelte 3.0.0).
Repro steps:
EDIT: It seems to be related to this line:
bind:group={selectedVars[schemaVar.name].lts}
If I hardcode that to:
bind:group={selectedVars['bar'].lts}
Then it works fine.
Any ideas why the filter breaks the checkboxes?
<script>
let schema = {
name: "bar",
vars: [{ name: "X" }],
};
$: availableLTs = ["aaa", "bbb", "ccc", "abc"];
function matchesSearch(searchString, text) {
let query = searchString;
console.log("query is", query);
if (!query) return true;
return text.includes(query);
}
let selectedChart = 'bar';
let selectedVars = {X: { lts: [] }};
$: schemaVars = schema.vars;
let searchString = "";
</script>
<main>
{#each schemaVars as schemaVar}
<h6>
{schemaVar.name}
<input type="text" bind:value={searchString} placeholder="Search..." />
</h6>
{#each availableLTs as ele}
{#if matchesSearch(searchString, ele)}
<div class="form-check">
<label>
<input
type="checkbox"
class="form-check-input"
bind:group={selectedVars[schemaVar.name].lts}
value={ele}
/>
{ele}
</label>
</div>
{/if}
{/each}
{/each}
</main>
Upvotes: 1
Views: 1149
Reputation: 7721
Looks like the problem has something to do with the nested each loops
{#each schemaVars as schemaVar}
...
{#each availableLTs as ele}
...//Checkbox
{/each}
{/each}
which can be solved through wrapping the inner loop inside a component.
The previous answer almost solved the problem, but one important thing is missing: The each loop inside the component is not a "keyed each block" ->
(alternatively select 'aaa' and filter for 'b'...)
This can be solved by adding the label text as key/id (assuming that the checkbox labels are unique) ->
{#each filteredLTs as ele (ele)}
...
{/each}
Since the problem wasn't the way the variable was set (...selectedVars[schemaVar.name].lts}), I would try to keep the logic inside the component general and set the variables specifially inside the component tag inside App.svelte -> the component stays universal and can be easyly reused Example in this REPL
<script>
import Checkboxes from './Checkboxes.svelte'
let schema = {
name: "bar",
vars: [{ name: "X" }],
};
let allLTs = ["aaa", "bbb", "ccc", "abc"];
let searchString = "";
$: filteredLTs = allLTs.filter(lt => lt.includes(searchString))
let selectedVars = {X: { lts: [] }};
$: console.log(selectedVars.X.lts)
</script>
<main>
{#each schema.vars as schemaVar}
<h6>
{schemaVar.name}
<input type="text" bind:value={searchString} placeholder="Search..." />
</h6>
<div class="form-check">
<Checkboxes checkboxes={filteredLTs} bind:checked={selectedVars[schemaVar.name].lts}/>
</div>
{/each}
</main>
<script>
export let checkboxes, checked
</script>
{#each checkboxes as checkbox (checkbox)}
<label>
<input
type="checkbox"
class="form-check-input"
bind:group={checked}
value={checkbox}
/>
{checkbox}
</label>
{/each}
Upvotes: 2
Reputation: 386
You can solve this problem like this
In App.Svelte
<script>
import Checkbox from './Checkbox.svelte';
let schema = {
name: "bar",
vars: [{ name: "X" }],
};
$: availableLTs = ["aaa", "bbb", "ccc", "ABC"];
$: matchesSearch = availableLTs.filter((elem) =>{ return elem.includes(searchString); })
let selectedChart = 'bar';
let selectedVars = {X: { lts: [] }};
$: console.log(selectedVars)
$: schemaVars = schema.vars;
let searchString = "";
</script>
<main>
{#each schemaVars as {name}}
<h6>
{name}
<input type="text" bind:value={searchString} placeholder="Search..." />
</h6>
<Checkbox bind:value={selectedVars} {name} {matchesSearch}/>
{/each}
</main>
In Checkbox.Svelte
<script>
export let value, name, matchesSearch;
</script>
{#each matchesSearch as ele}
<div class="form-check">
<label>
<input
type="checkbox"
class="form-check-input"
bind:group={value[name].lts}
value={ele}
/>
{ele}
</label>
</div>
{/each}
You can check it in this repl
Upvotes: 1