pub const CODE_WEB_TODO: &str = r##"# To-Do — add, finish, remove
`State:` holds an ordinary list of records. Each row is keyed by its id, so removing
one leaves the others' elements where they are. `left` is derived: it recomputes
whenever `todos` changes.
## A Todo has:
an id, which is Int.
a text, which is Text.
a done, which is Bool.
## To openCount (todos: Seq of Todo) -> Int:
Let mutable n be 0.
Repeat for t in todos:
If t's done is equal to false:
Set n to n + 1.
Return n.
## Page /
State:
Let todos be a new Seq of Todo.
Let draft be "".
Let nextId be 1.
Let left always be openCount(todos).
Actions:
To add:
If draft is equal to "":
Return.
Push (a new Todo with id nextId and text draft and done false) to todos.
Set nextId to nextId + 1.
Set draft to "".
To toggle (id: Int):
Let mutable next be a new Seq of Todo.
Repeat for t in todos:
If t's id is equal to id:
Push (a new Todo with id t's id and text t's text and done (not t's done)) to next.
Otherwise:
Push t to next.
Set todos to next.
To remove (id: Int):
Let mutable kept be a new Seq of Todo.
Repeat for t in todos:
If t's id is not equal to id:
Push t to kept.
Set todos to kept.
View:
<h1>To-Do</h1>
<form id="add" on-submit.prevent={add}>
<input id="draft" type="text" aria-label="New task" bind={draft} placeholder="What needs doing?">
<button type="submit">Add</button>
</form>
<ul>
{for each t in todos, keyed by t's id:}
<li class="todo" class:done={t's done}>
<button id="toggle-{t's id}" on-click={toggle(t's id)}>{t's text}</button>
<button id="remove-{t's id}" on-click={remove(t's id)}>remove</button>
</li>
{else:}
<li class="empty">Nothing to do.</li>
{end}
</ul>
<p id="left">{left} left</p>
Style:
.done button:first-child { text-decoration: line-through; opacity: .6; }
## Test: todos are added, finished and removed
Type "milk" into "#draft".
Submit "#add".
Type "bread" into "#draft".
Submit "#add".
Expect that the count of ".todo" is equal to 2.
Click "#toggle-1".
Expect that the text of "#left" is equal to "1 left".
Click "#remove-1".
Expect that the count of ".todo" is equal to 1.
Expect that the text of "#toggle-2" is equal to "bread".
"##;Expand description
Web page: a to-do list you add to, tick off and remove from — records in State:, a form
with .prevent, a keyed {for each} with an empty arm, and a derived count.