Written by: Geoffrey Callaghan

Forms with Solidjs

Forms With Solidjs

Creating forms with Solid.js involves using its reactive and declarative paradigms to manage form state and handle user interactions efficiently. Here’s a basic guide on how to create and handle forms in Solid.js:

1. Setting Up Solid.js

First, ensure you have a Solid.js project set up. If not, you can create one using the Solid.js template:

npx degit solidjs/templates/ts my-solid-app
cd my-solid-app
npm install
npm start

2. Basic Form Example

Step 1: Define State

Use Solid.js reactive primitives to create state variables to hold form data.

import { createSignal } from "solid-js";

function App() {
  const [name, setName] = createSignal("");
  const [email, setEmail] = createSignal("");

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log("Name:", name());
    console.log("Email:", email());
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label for="name">Name:</label>
        <input
          id="name"
          type="text"
          value={name()}
          onInput={(e) => setName(e.target.value)}
        />
      </div>
      <div>
        <label for="email">Email:</label>
        <input
          id="email"
          type="email"
          value={email()}
          onInput={(e) => setEmail(e.target.value)}
        />
      </div>
      <button type="submit">Submit</button>
    </form>
  );
}

export default App;

Step 2: Handle Input

In the above code, createSignal is used to create reactive state variables name and email. The onInput event handler updates these signals whenever the user types in the input fields.

Step 3: Handle Form Submission

The handleSubmit function prevents the default form submission behavior and logs the form data to the console.

3. Form Validation

Adding validation to a form is straightforward. You can use additional state variables to track validation errors.

import { createSignal } from "solid-js";

function App() {
  const [name, setName] = createSignal("");
  const [email, setEmail] = createSignal("");
  const [errors, setErrors] = createSignal({ name: "", email: "" });

  const validate = () => {
    let newErrors = { name: "", email: "" };
    if (!name()) newErrors.name = "Name is required";
    if (!email()) newErrors.email = "Email is required";
    else if (!/\S+@\S+\.\S+/.test(email())) newErrors.email = "Email is invalid";
    setErrors(newErrors);
    return !newErrors.name && !newErrors.email;
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    if (validate()) {
      console.log("Name:", name());
      console.log("Email:", email());
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label for="name">Name:</label>
        <input
          id="name"
          type="text"
          value={name()}
          onInput={(e) => setName(e.target.value)}
        />
        {errors().name && <span>{errors().name}</span>}
      </div>
      <div>
        <label for="email">Email:</label>
        <input
          id="email"
          type="email"
          value={email()}
          onInput={(e) => setEmail(e.target.value)}
        />
        {errors().email && <span>{errors().email}</span>}
      </div>
      <button type="submit">Submit</button>
    </form>
  );
}

export default App;

In this code, the validate function checks if the name and email are provided and if the email is in a valid format. The errors signal holds any validation error messages, which are displayed conditionally in the form.

4. Styling

You can style the form using standard CSS. For example:

form {
  display: flex;
  flex-direction: column;
  width: 300px;
  margin: auto;
}

div {
  margin-bottom: 15px;
}

label {
  margin-bottom: 5px;
}

input {
  padding: 8px;
  font-size: 1em;
}

span {
  color: red;
  font-size: 0.8em;
}

button {
  padding: 10px;
  font-size: 1em;
  background-color: #007bff;
  color: white;
  border: none;
  cursor: pointer;
}

button:hover {
  background-color: #0056b3;
}

Include this CSS in your project to apply basic styling to your form.

Conclusion

Solid.js makes it easy to create and manage forms with its reactive state management. By using createSignal for state and handling events declaratively, you can build responsive and interactive forms. Adding validation and styling ensures a better user experience.