Text inputs
<input bind:value={name}>
Two-way binding.
Numeric inputs
In the DOM, everything is a string. That's unhelpful when you're dealing with numeric inputs — type="number"
and type="range"
— as it means you have to remember to coerce input.value
before using it.
With bind:value
, Svelte takes care of it for you:
<input type="number" bind:value={a} min="0" max="10" />
<input type="range" bind:value={a} min="0" max="10" />
Checkbox inputs
Checkboxes are used for toggling between states. Instead of binding to input.value
, we bind to input.checked
:
<input type="checkbox" bind:checked={yes} />
Select bindings
We can also use bind:value with <select> elements:
<select
bind:value={selected}
on:change={() => (console.log(selected))}
>
{#each questions as question}
<option value={question}>
{question.text}
</option>
{/each}
</select>
Note that the <option>
values are objects rather than strings.
Group inputs
If you have multiple type="radio"
or type="checkbox"
inputs relating to the same value, you can use bind:group
along with the `value attribute. Radio inputs in the same group are mutually exclusive; checkbox inputs in the same group form an array of selected values.
<script>
let scoops = 1;
let flavours = [];
const formatter = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
</script>
<h2>Size</h2>
{#each [1, 2, 3] as number}
<label>
<input
type="radio"
name="scoops"
value={number}
bind:group={scoops}
/>
{number} {number === 1 ? 'scoop' : 'scoops'}
</label>
{/each}
<h2>Flavours</h2>
{#each ['cookies and cream', 'mint choc chip', 'raspberry ripple'] as flavour}
<label>
<input
type="checkbox"
name="flavours"
value={flavour}
bind:group={flavours}
/>
{flavour}
</label>
{/each}
{#if flavours.length === 0}
<p>Please select at least one flavour</p>
{:else if flavours.length > scoops}
<p>Can't order more flavours than scoops!</p>
{:else}
<p>
You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'}
of {formatter.format(flavours)}
</p>
{/if}
Select multiple
A <select>
element can have a multiple
attribute, in which case it will populate an array rather than selecting a single value.
Note that we're able to omit the value attribute on the <option>, since the value is identical to the element's contents.
<script>
let scoops = 1;
let flavours = [];
const formatter = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
</script>
<h2>Size</h2>
{#each [1, 2, 3] as number}
<label>
<input
type="radio"
name="scoops"
value={number}
bind:group={scoops}
/>
{number} {number === 1 ? 'scoop' : 'scoops'}
</label>
{/each}
<h2>Flavours</h2>
<select multiple bind:value={flavours}>
{#each ['cookies and cream', 'mint choc chip', 'raspberry ripple'] as flavour}
<option>{flavour}</option>
{/each}
</select>
{#if flavours.length === 0}
<p>Please select at least one flavour</p>
{:else if flavours.length > scoops}
<p>Can't order more flavours than scoops!</p>
{:else}
<p>
You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'}
of {formatter.format(flavours)}
</p>
{/if}
Press and hold the control
key (or the command
key on MacOS) to select multiple options.
Textarea inputs
The <textarea>
element behaves similarly to a text input in Svelte — use bind:value
:
<script>
import { marked } from 'marked';
let value = `Some words are *italic*, some are **bold**\n\n- lists\n- are\n- cool`;
</script>
<div class="grid">
input
<textarea bind:value></textarea>
output
<div>{@html marked(value)}</div>
</div>
<style>
.grid {
display: grid;
grid-template-columns: 5em 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 1em;
height: 100%;
}
textarea {
width: 500px;
resize: none;
}
</style>
网友评论