DEV Community

Cover image for How to handle in forms in Svelte?
Ashutosh
Ashutosh

Posted on • Originally published at ashutosh.dev

How to handle in forms in Svelte?

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

<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>
Enter fullscreen mode Exit fullscreen mode

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.

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

<form on:submit|preventDefault={submitForm}>
    .....
 </form>
Enter fullscreen mode Exit fullscreen mode

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


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.

<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>
Enter fullscreen mode Exit fullscreen mode

img


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.

<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>
Enter fullscreen mode Exit fullscreen mode

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.

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

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

And also

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
            }
        }
    }
    ...
    ...
}
Enter fullscreen mode Exit fullscreen mode

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.

<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>
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (1)

Collapse
roblevintennis profile image
Rob Levin

While I definitely think it's a good exercise to do the validation like this "by hand", I don't think this will scale as you build a product. I recently used Vest and really liked it:
dev.to/roblevintennis/agnosticui-v...

Mine used Svelte, but you can use Vest with JavaScript / HTML5 forms, React, Vue, or really anything since it's just an orthogonal ES6 module. And even if you do want to "roll your own" it's certainly worth looking at their source code too.