This showcases how to keep checkboxes in sync between two kinds of views. The views are
interchangeable via a radio selection and CSS. Server-side, submitted values would need to be deduplicated by their name.
Last active
July 26, 2024 03:30
-
-
Save theetrain/d05bb16ef92e5b09431b964472ff2f47 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!-- | |
| "Reacting to checkboxes" by Enrico | |
| https://github.com/theetrain | |
| Synchronizes checkbox state between two different views | |
| of checkboxes. | |
| --> | |
| <script> | |
| import Container from './Container.svelte' | |
| import Check from './Check.svelte' | |
| let items = $state([ | |
| { name: 'earth', checked: false }, | |
| { name: 'fire', checked: false }, | |
| { name: 'wind', checked: false } | |
| ]) | |
| </script> | |
| <pre>App items: {JSON.stringify(items.map(el => ({ [el.name]: el.checked })))}</pre> | |
| <Container bind:items> | |
| {#snippet tileSnippet(item, index)} | |
| <Check label={item.name} name={item.name} bind:checked={items[index].checked} /> | |
| {/snippet} | |
| </Container> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script> | |
| let { label, checked = $bindable(), ...rest } = $props() | |
| </script> | |
| <label>{label} | |
| <input type="checkbox" {...rest} bind:checked /> | |
| </label> | |
| <style> | |
| label { | |
| display: inline-block; | |
| padding: 1rem; | |
| background-color: #eee; | |
| border: 1px solid black; | |
| } | |
| :global(body.dark) label { | |
| background-color: black; | |
| border: 1px solid white; | |
| } | |
| </style> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script> | |
| let { items = $bindable(), tileSnippet } = $props() | |
| let count = $derived(items.filter(el => el.checked).length) | |
| let container | |
| </script> | |
| <pre>Container: {JSON.stringify(items.map(el => ({ [el.name]: el.checked })))}</pre> | |
| <p>Count {count}</p> | |
| <div bind:this={container} class="container"> | |
| <label>tile view<input type="radio" name="toggle" value="tile" checked /></label> | |
| <label>list view<input type="radio" name="toggle" value="list" /></label> | |
| <ul data-view="list"> | |
| {#each items as item,i} | |
| <li> | |
| <label>{item.name}<input type="checkbox" name={item.name} bind:checked={items[i].checked} /></label> | |
| </li> | |
| {/each} | |
| </ul> | |
| <div data-view="tile"> | |
| {#each items as item, index} | |
| {@render tileSnippet(item, index)} | |
| {/each} | |
| </div> | |
| </div> | |
| <style> | |
| .container { | |
| margin-top: 1rem; | |
| } | |
| .container:has([value="tile"]:checked) [data-view="list"] { | |
| display: none; | |
| } | |
| .container:has([value="list"]:checked) [data-view="tile"] { | |
| display: none; | |
| } | |
| </style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment