How to handle in forms in Svelte?
Tags: svelte, javascript, beginners, webdev
Published: 2022-01-02 06:45:48

Forms! Forms! Forms!

Forms are an integral part of any web application. We can't imagine an application without forms. Generally, we use forms for

- User registration
- User login
- Subscription
- Contact Form
- Adding/Updating/Removing any kind data to or from the database

In this article, we learn how to create an HTML form.  And we also go through how to handle the form validation. This article will not cover the backend APIs required to Post the data into the application. It'll only cover the frontend part.

Lets take a look at this code quickly

```html
<script>

</script>

<main>

    <form>
        <label for="first_name"> <strong> First Name </strong> </label>
        <input id="first_name" name="first_name" type="text"  />

        <label for="last_name"> <strong> Last Name </strong> </label>
        <input id="last_name" name="last_name" type="text"  />

        <label for="email"> <strong> Email ID </strong> </label>
        <input id="email" name="email" type="email"  />

        <br />
        <button type="submit">Save</button>
    </form>

</main>


<style>
	main {
		text-align: center;
		padding: 1em;
		max-width: 240px;
		margin: 0 auto;
	}


	@media (min-width: 640px) {
		main {
			max-width: none;
		}
	}
</style>
```

Most of the code above is already familiar to anyone familiar with HTML. Currently, our form is doing nothing. In case if we click on the `Save` button. It'll merely submit the form without checking or validating any input parameters.

Let's handle the submit event first.

```javascript
<script>
    const submitForm = () => alert('You submit the Form.');
</script>

<form on:submit|preventDefault={submitForm}>
    .....
 </form>
```

Take a look at this line,`<form on:submit|preventDefault={submitForm}>`. We bind the form with the `on:submit` handler.

We bind the form with the on:submit handler.

Now, what happens if we submit the form?
It'll show an alert, `You submit the form`

![img](https://ashutosh.dev/content/images/2021/12/Screenshot-2021-12-16-at-10.38.21-AM.png)

------

Please note, the event modifier `|preventDefault`. This is equivalent to adding the Event `preventDefault` method in the handler.

Let's add some validation on input parameters.

### Validation

We have three fields in our Html form:

- First Name
- Last Name
- Email Id

And here are the following validation rules:

- First name, Last name, and Email cannot be null
- First names and last names can only have alphabets.

We'll start with the null validations, eventually we'll add other validations. Let's add the following under the `script` tag.

```javascript
<script>

    function isRequired(value) {
        return value != null && value !== ""
    }

    const submitForm = (event) => {
        const formData = new FormData(event.target)

        let error = false;

        for ( let field of formData ) {
            const [key, value] = field;

            if( !isRequired(value) ) {
                alert('Field ' + key + ' is required')
                error = true
            }

        }


        if ( !error ) {
            alert('You submit the form.')
        }

    };



</script>
```

![img](https://ashutosh.dev/content/images/2021/12/Svelte_form_1.gif)

------

At present, our application is showing the alerts whenever it caught the exceptions. This is not the correct way of displaying errors. We need to display the errors under the fields.

```javascript
<script>

    let errors = {};

    function isRequired(value) {
        return value != null && value !== ""
    }

    const submitForm = (event) => {
        const formData = new FormData(event.target)

        let error_flag = false;

        for ( let field of formData ) {
            const [key, value] = field;

            if( !isRequired(value) ) {
                errors[key] = key + ' is required'
                error_flag = true
            }

        }

        if ( !error_flag ) {
            alert('You submit the form.')
        }

    };



</script>

<main>

    <form on:submit|preventDefault={submitForm}>
        <label for="first_name"> <strong> First Name </strong> </label>
        <input id="first_name" name="first_name" type="text"  />
        {#if errors.first_name}
            <p><small style="color: red"> { errors.first_name } </small></p>
        {/if}

        <label for="last_name"> <strong> Last Name </strong> </label>
        <input id="last_name" name="last_name" type="text"  />
        {#if errors.last_name}
            <p><small style="color: red"> { errors.last_name } </small></p>
        {/if}

        <label for="email"> <strong> Email ID </strong> </label>
        <input id="email" name="email" type="email"  />
        {#if errors.email}
            <p><small style="color: red"> { errors.email } </small></p>
        {/if}

        <br />
        <button type="submit">Save</button>
    </form>

</main>

<style>
	main {
		text-align: center;
		padding: 1em;
		max-width: 240px;
		margin: 0 auto;
	}


	@media (min-width: 640px) {
		main {
			max-width: none;
		}
	}
</style>
```

So far so good. Let's add the validation for valid first_name, last_name and email. We need to create two functions `isNameValid()` and `isEmailValid()`.  

Add the following functions under the `script`.

```javascript
function isNameValid( value ) {
    return /^[a-zA-Z]$/.test( value )
}

function isEmailValid( value ) {
    return /^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$/.test( value )
}
```

And also

```javascript
const submitForm = (event) => {
    const formData = new FormData(event.target)

    let error_flag = false;

    for ( let field of formData ) {
        ...
        ...
        
    // Validate First name and Last_name
        if ( key === 'first_name' || key === 'last_name' ) {
            if ( !isNameValid( value ) ) {
                errors[key] = key + ' can only have alphabets'
                error_flag = true
            }
        }

        // Valid Email
        if ( key === 'email' ) {
            if ( !isEmailValid( value ) ) {
                errors[key] = 'Invalid Email Id'
                error_flag = true
            }
        }
    }
    ...
    ...
}
```

If we notice carefully, then we found the regex we put can handle the null fields. So it is safe to remove the the `isRequired()` function. Let's refactor the code.

```javascript
<script>

    let errors = {};

    function isNameValid( value ) {
        return /^[a-zA-Z]$/.test( value )
    }

    function isEmailValid( value ) {
        return /^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$/.test( value )
    }

    const submitForm = (event) => {
        errors = {}
        const formData = new FormData(event.target)

        let error_flag = false;

        for ( let field of formData ) {
            const [key, value] = field;

            // Validate First name and Last_name
            if ( key === 'first_name' || key === 'last_name' ) {
                if ( !isNameValid( value ) ) {
                    errors[key] = key + ' can only have alphabets'
                    error_flag = true
                }
            }

            // Valid Email
            if ( key === 'email' ) {
                if ( !isEmailValid( value ) ) {
                    errors[key] = 'Invalid Email Id'
                    error_flag = true
                }
            }

        }

        if ( !error_flag ) {
            alert('You submit the form.')
        }

    };


</script>

<main>

    <form on:submit|preventDefault={submitForm}>
        <label for="first_name"> <strong> First Name </strong> </label>
        <input id="first_name" name="first_name" type="text"  />
        {#if errors.first_name}
            <p><small style="color: red"> { errors.first_name } </small></p>
        {/if}

        <label for="last_name"> <strong> Last Name </strong> </label>
        <input id="last_name" name="last_name" type="text"  />
        {#if errors.last_name}
            <p><small style="color: red"> { errors.last_name } </small></p>
        {/if}

        <label for="email"> <strong> Email ID </strong> </label>
        <input id="email" name="email" type="email"  />
        {#if errors.email}
            <p><small style="color: red"> { errors.email } </small></p>
        {/if}

        <br />
        <button type="submit">Save</button>
    </form>

</main>

<style>
	main {
		text-align: center;
		padding: 1em;
		max-width: 240px;
		margin: 0 auto;
	}


	@media (min-width: 640px) {
		main {
			max-width: none;
		}
	}
</style>
```

Now, if you try to submit the form with all valid parameters, then you'll get an alert `alert('You submit the form.')` on your screen.

Thats all for this post. In our next post, we'll discuss other ways of handling forms in Svelte.