Forms and inputs
A form collects data from the user: the task text, a priority, an "urgent" flag. In Solid a field's value is usually kept in a signal: the value attribute shows the signal, and the onInput handler writes what the user typed into it. Such a field is called controlled.
A controlled field
// src/components/TodoForm.jsx
import { createSignal } from 'solid-js';
export default function TodoForm() {
const [title, setTitle] = createSignal('');
return (
<div>
<input value={title()} onInput={(e) => setTitle(e.currentTarget.value)} />
<p>Characters: {title().length}</p>
</div>
);
}Render <TodoForm /> in src/App.jsx. The number under the field changes with each character. Calling setTitle('') clears the field.
Submitting the form
A form is submitted by a button with type="submit" or by the Enter key. The onSubmit handler must cancel the default page reload:
// src/components/TodoForm.jsx
import { createSignal } from 'solid-js';
export default function TodoForm(props) {
const [title, setTitle] = createSignal('');
const submit = (e) => {
e.preventDefault();
props.onAdd(title());
setTitle('');
};
return (
<form onSubmit={submit}>
<input value={title()} onInput={(e) => setTitle(e.currentTarget.value)} />
<button type="submit">Add</button>
</form>
);
}Connect the form to the store from the lesson on stores: <TodoForm onAdd={add} />. After Enter the task appears in the list and the field is cleared.
Checkbox and select
| Field | Value attribute | How to read |
|---|---|---|
Text, textarea | value | e.currentTarget.value |
| Checkbox | checked | e.currentTarget.checked |
select | value | e.currentTarget.value |
// src/components/TodoOptions.jsx
import { createSignal } from 'solid-js';
export default function TodoOptions() {
const [urgent, setUrgent] = createSignal(false);
const [priority, setPriority] = createSignal('normal');
return (
<div>
<label>
<input type="checkbox" checked={urgent()} onChange={(e) => setUrgent(e.currentTarget.checked)} />
Urgent
</label>
<select value={priority()} onChange={(e) => setPriority(e.currentTarget.value)}>
<option value="low">Low</option>
<option value="normal">Normal</option>
<option value="high">High</option>
</select>
<p>{urgent() ? 'Urgent' : 'Regular'}, priority: {priority()}</p>
</div>
);
}The paragraph at the bottom shows the chosen values right away. For a checkbox and select, onChange fits: it fires right after a choice is made.
Validation
A validation error is easy to describe with a derived function and show with Show:
// src/components/TodoForm.jsx
const error = () => (title().trim().length < 3 ? 'At least 3 characters' : '');
<Show when={error()}>
<p class="error">{error()}</p>
</Show>
<button type="submit" disabled={!!error()}>Add</button>While the field has fewer than three characters, a hint is shown under it and the button is disabled.
Common mistake
Forgetting e.preventDefault() in the onSubmit handler. The browser submits the form the usual way and reloads the page — all data in signals is lost, and the task never shows up in the list.