#svelte
#javascript
#frontend
Day 5: The Magic of Bindings
Welcome to Day 5. Usually, data flows down. But in forms, we need data to flow back up from the input to our state.
bind:value
Instead of writing an oninput handler to update state, use bind:value.
<script lang="ts">
let name = $state('Svelte');
</script>
<input bind:value={name} />
<p>Hello {name}!</p>
This works for <input>, <textarea>, and <select>.
bind:checked
For checkboxes.
<script>
let acceptsTerms = $state(false);
</script>
<label>
<input type="checkbox" bind:checked={acceptsTerms} />
I accept the terms
</label>
<button disabled={!acceptsTerms}>Submit</button>
bind:group
For radio buttons or multiple checkboxes sharing the same array!
<script>
let flavor = $state('Vanilla');
</script>
<label>
<input type="radio" bind:group={flavor} value="Vanilla"> Vanilla
</label>
<label>
<input type="radio" bind:group={flavor} value="Chocolate"> Chocolate
</label>
<label>
<input type="radio" bind:group={flavor} value="Strawberry"> Strawberry
</label>
<p>You picked: {flavor}</p>
bind:this
Need direct access to the DOM element? (e.g., to focus it, or draw on a canvas).
<script>
let myInput; // no initial value needed
function focusInput() {
myInput.focus();
}
</script>
<input bind:this={myInput} />
<button onclick={focusInput}>Focus It</button>
Challenge for Day 5
- Create a specialized form.
- Input:
price(type number, range 0-100). - Range Slider: Also bound to
price(so they sync!). - Checkbox:
isTaxed. - Derived:
total(price * 1.2 if taxed, else just price).
Solution:
<script lang="ts">
let price = $state(50);
let isTaxed = $state(false);
let total = $derived(isTaxed ? price * 1.2 : price);
</script>
<input type="number" bind:value={price} />
<input type="range" bind:value={price} min="0" max="100" />
<label>
<input type="checkbox" bind:checked={isTaxed} />
Add 20% Tax
</label>
<h2>Total to Pay: ${total.toFixed(2)}</h2>
Everything stays in sync automatically. That is the beauty of Svelte. Tomorrow: Components!