Svelte: Handling Forms and User Input

Svelte: Handling Forms and User Input

·

3 min read

Overview

Forms are a fundamental part of web applications, and Svelte provides an intuitive way to manage user input and handle forms. In this article, we’ll cover how to create forms, validate inputs, and manage form submissions in Svelte.

Creating a Simple Form

To create a form in Svelte, you can use standard HTML form elements, and Svelte will automatically manage their state.

Example: Basic Form

<script>
  let name = '';
  let email = '';

  function handleSubmit() {
    alert(`Name: ${name}, Email: ${email}`);
  }
</script>

<form on:submit|preventDefault={handleSubmit}>
  <label for="name">Name:</label>
  <input type="text" id="name" bind:value={name} required>

  <label for="email">Email:</label>
  <input type="email" id="email" bind:value={email} required>

  <button type="submit">Submit</button>
</form>

Explanation:

  • Two-Way Binding: The bind:value directive binds the input value to the corresponding variable. Any changes in the input field automatically update the variable and vice versa.

  • Preventing Default Behavior: The |preventDefault modifier stops the form from submitting in the traditional way, allowing you to handle it with JavaScript.

Validating Form Inputs

Input validation is essential to ensure data integrity. Svelte makes it easy to implement validation logic.

Example: Simple Validation

<script>
  let name = '';
  let email = '';
  let errorMessage = '';

  function validate() {
    errorMessage = '';
    if (!name) {
      errorMessage = 'Name is required.';
    } else if (!/\S+@\S+\.\S+/.test(email)) {
      errorMessage = 'Please enter a valid email address.';
    }
  }

  function handleSubmit() {
    validate();
    if (!errorMessage) {
      alert(`Name: ${name}, Email: ${email}`);
    }
  }
</script>

<form on:submit|preventDefault={handleSubmit}>
  <label for="name">Name:</label>
  <input type="text" id="name" bind:value={name} required>

  <label for="email">Email:</label>
  <input type="email" id="email" bind:value={email} required>

  {#if errorMessage}
    <p style="color: red;">{errorMessage}</p>
  {/if}

  <button type="submit">Submit</button>
</form>

Explanation:

  • Error Handling: An error message is displayed if validation fails, using Svelte's {#if} block to conditionally render the message.

Managing Multiple Inputs

When dealing with forms that have multiple inputs, you can store the form data in an object for better organization.

Example: Using an Object for Form Data

<script>
  let formData = {
    name: '',
    email: '',
    password: ''
  };

  function handleSubmit() {
    alert(`Name: ${formData.name}, Email: ${formData.email}`);
  }
</script>

<form on:submit|preventDefault={handleSubmit}>
  <label for="name">Name:</label>
  <input type="text" id="name" bind:value={formData.name} required>

  <label for="email">Email:</label>
  <input type="email" id="email" bind:value={formData.email} required>

  <label for="password">Password:</label>
  <input type="password" id="password" bind:value={formData.password} required>

  <button type="submit">Submit</button>
</form>

Explanation:

  • Organizing Form Data: All inputs are stored in the formData object, making it easier to manage and submit.

Using Form Libraries

For more complex forms, you can integrate third-party libraries such as svelte-forms-lib or svelte-forms to simplify form handling, validation, and submission.

Example: Using svelte-forms-lib

  1. Install the library:

     npm install svelte-forms-lib
    
  2. Implementing with the Library:

     <script>
       import { createForm } from 'svelte-forms-lib';
    
       const { form, fields } = createForm({
         initialValues: { name: '', email: '' },
         onSubmit: values => alert(JSON.stringify(values))
       });
     </script>
    
     <form on:submit={form.handleSubmit}>
       <label for="name">Name:</label>
       <input id="name" bind:value={fields.name.value} required>
       {#if fields.name.error}
         <p style="color: red;">{fields.name.error}</p>
       {/if}
    
       <label for="email">Email:</label>
       <input id="email" bind:value={fields.email.value} required>
       {#if fields.email.error}
         <p style="color: red;">{fields.email.error}</p>
       {/if}
    
       <button type="submit">Submit</button>
     </form>