Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

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

FieldValue attributeHow to read
Text, textareavaluee.currentTarget.value
Checkboxcheckede.currentTarget.checked
selectvaluee.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.

Thanks for reading!

Donate to the site — we work hard for you.