Skip to main content

We can also use bind:value with <select> elements:

App
<select
	bind:value={selected}
	onchange={() => answer = ''}
>

Note that the <option> values are objects rather than strings. Svelte doesn’t mind.

Because we haven’t set an initial value of selected, the binding will set it to the default value (the first in the list) automatically. Be careful though — until the binding is initialised, selected remains undefined, so we can’t blindly reference e.g. selected.id in the template.

Edit this page on GitHub

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<script>
	let questions = $state([
		{
			id: 1,
			text: `Where did you go to school?`
		},
		{
			id: 2,
			text: `What is your mother's name?`
		},
		{
			id: 3,
			text: `What is another personal fact that an attacker could easily find with Google?`
		}
	]);
 
	let selected = $state();
 
	let answer = $state('');
 
	function handleSubmit(e) {
		e.preventDefault();
 
		alert(
			`answered question ${selected.id} (${selected.text}) with "${answer}"`
		);
	}
</script>
 
<h2>Insecurity questions</h2>
 
<form onsubmit={handleSubmit}>
	<select
		value={selected}
		onchange={() => (answer = '')}
	>
		{#each questions as question}
			<option value={question}>
				{question.text}
			</option>
		{/each}
	</select>
 
	<input bind:value={answer} />
 
	<button disabled={!answer} type="submit">
		Submit
	</button>
</form>
 
<p>
	selected question {selected
		? selected.id
		: '[waiting...]'}
</p>