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>
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>
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
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>
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>
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 )
}
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
}
}
}
...
...
}
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>
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.
Top comments (1)
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.