Skip to main content

You can even bind to properties inside an each block.

App.svelte
{#each todos as todo}
	<li class:done={todo.done}>
		<input
			type="checkbox"
			bind:checked={todo.done}
		/>

		<input
			type="text"
			placeholder="What needs to be done?"
			bind:value={todo.text}
		/>
	</li>
{/each}

Note that interacting with these <input> elements will mutate the array. If you prefer to work with immutable data, you should avoid these bindings and use event handlers instead.

Next: Media elements

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<script>
	let todos = [
		{ done: false, text: 'finish Svelte tutorial' },
		{ done: false, text: 'build an app' },
		{ done: false, text: 'world domination' }
	];
 
	function add() {
		todos = todos.concat({
			done: false,
			text: ''
		});
	}
 
	function clear() {
		todos = todos.filter((t) => !t.done);
	}
 
	$: remaining = todos.filter((t) => !t.done).length;
</script>
 
<div class="centered">
	<h1>todos</h1>
 
	<ul class="todos">
		{#each todos as todo}
			<li class:done={todo.done}>
				<input
					type="checkbox"
					checked={todo.done}
				/>
 
				<input
					type="text"
					placeholder="What needs to be done?"
					value={todo.text}
				/>
			</li>
		{/each}
	</ul>
 
	<p>{remaining} remaining</p>
 
	<button on:click={add}>
		Add new
	</button>
 
	<button on:click={clear}>
		Clear completed
	</button>
</div>
 
<style>
	.centered {
		max-width: 20em;
		margin: 0 auto;
	}
 
	.done {
		opacity: 0.4;
	}
 
	li {
		display: flex;
	}
 
	input[type="text"] {
		flex: 1;
		padding: 0.5em;
		margin: -0.2em 0;
		border: none;
	}
</style>
 
initialising