A Guide to Form Validation in Vue.js

Hello everyone, this is my first tutorial in this blog and I will try to explain in the best way this topic. I will assume that you already know what VueJS is and you have taken their first steps with this framework. I will also consider that you have some experience handling the new features of ES6, (if not, you can read this post and come back later) so i will skip certain things in order to focus on the topic of this post.

Performing client-side forms validation using Javascript improves the user experience by giving immediate feedback instead of having to complete a request to the server, thereby avoiding the time-out involved.

IMPORTANT: I want to make it clear, that this type of validation should never replace server-side validation. Client-side validation (with Vue or any other framework) should always be used as a complement, not a substitute.

As you probably know, many modern browsers have client-side validation built-in by using HTML attributes, as it is (but not limited to) required and minlength. For example, having the following form:

If you leave the input element empty and click Submit, your browser prevents form submission and warns you. This is how looks like in Firefox browser:

However, not all browsers support this and all of them behave differently. Let’s look at how to build our own form validation using Vue.js so it behaves the same in all modern browsers.

Scenario:

We going to build a typical contact form with three inputs:

  • Username
  • Email
  • Password

The three inputs are required. The email input should only allow emails.

Download the source code

You can download all of the associated files with this tutorial from here.

Setup

We have to start with this basic HTML file with the Bootstrap 3.3.7 stylesheet, a bootswatch theme (lumen) and VueJS.

Our form will be in the content area. Just to have a more beautiful design, we will put it inside a container. Each of these elements have classes that position them nicely.

Now, our three input elements and submit button will go inside the form.

You would normally use type=”email” for the second input, but i’m leaving it as text to demonstrate the validation we get with Vue.

Bootstrap provides validation classes. Let’s add those now.

On each of the inputs parent element, in addition to the form-group class, add another class has-error. This tells Bootstrap that when this input has an error, display error styles.

Also, Bootstrap gives us access to feedback elements. Let’s add one underneath each input.

At this point, our form should look like this.

 

 

Form complete

As you can see, the feedback elements will always be displayed, and that’s not the idea. Later, we will make sure they’re only shown if validation fails.

Building the logic

With the HTML code finished, now we will jump into the main.js file and start coding the logic for our form.

In our data object, there are seven variables:

  1. username — Will hold the value of the username input.
  2. email — Will hold the value of the email input.
  3. emailFeedback –Will provide us the feedback message for email input.
  4. password — Will hold the value of the password input.
  5. passwordFeedback — Will provide us the feedback message for password input.
  6. submition — A boolean that indicates whether the user has attempted to submit the form. We can use this to hide validation errors until after the user has tried to submit the form.

There are also three computed variables here:

  • wrongUsername — Will return true if username is empty.
  • wrongEmail — Will return true if email is empty or is not a valid email address. We will validate this using regex.
  • wrongPassword — Will return true if password is empty or is not minimum 8 characters.

Finally, there are a couple of methods:

  • isEmail — A utility function that checks to see if an input is an email.
  • validateForm — The main function that will be called when trying to submit.

As i mentioned above, there are three variables that hold the value of the inputs. We can wire those up using Vue models.

With our models wired up, we can use the computed variables to determine the status of each input. wrongUsername is easy. Return true if value is empty.

wrongEmail is a little more complex, but not bad at all. Return true if the value is empty or it’s not a valid email address. But first, we need to code the isEmail method because we will use it. I found a great solution on Stack Overflow. Here’s what it looks like.

And now, wrongEmail.

Here, we are changing the emailFeedback value, according to the situation. I mean, if the email input is empty, we will show to the user the message “This field is required” that is saved into required property of ERRORS constant. Or if the result of calling isEmail is false, we will show “This is not a valid email address” of the invalidEmail property of ERRORS.

wrongPassword is basically the same, first we check that password is not empty and if have minimum length of 8 characters.

We are actually done with the Javascript except for the actual validateForm method. For that one, we just want to tell our app the user attempted to submit the form and preven it from submitting if wrongUsername, wrongEmail or wrongPassword are true. Keep in mind you can keep adding computed variables here if you have more inputs that need to be validated.

Done with the Javascript code. Back in the HTML we need to do some changes. We need to fire the validatedForm() method when the form is submitted.

Then, add the (Boostrap) has-error class for each input. We only want to add it if:

  1. The user has attempted to submit the form, and
  2. Values are empty or not valid.

Finally, we only want the feedback elements to appear under those same circumstances:

The feedback message for email and password is according to the respective validation method. Now if we re-load the page, our form looks like:

If you try to submit with empty values:

Validation works Try filling the inputs but you use an invalid email address.

Invalid email addressAnd this occurs when you fill with a short password.

Short passwordMaybe you are thinking that it is not something different that if you use only vanilla Javascript, so, what’s the point to use Vue? Well, Vue provide us reactivity, this is the nice part, when the user correct their mistake, the warning goes away inmediately. You could remove checks for submition if you want to display the warnings on load (and have them go away inmediately when corrected), but i think it’s bad UX to show errors before the user has even started typing.

Here is the full code:

index.html

main.js

 

Finally, I will give you a brief explanation about how to validate a select type input.
This I did not put it directly in the tutorial, since the example was a contact form and would not make much sense.

First it is necessary that we have an input of this type ready:

A simple select type input, right?
We are going to use Vue to make it more dynamic. We create an array with the language options that we will handle (this options could be provided from an API) and setting the default option for the select:

Now, we modify the HTML code of our select.

And we are ready to create our validation method. We will use the same tutorial code structure. First, we add a computed variable to handle changes in our language variable.

I know, this is exactly as our wrongUsername() method from before. This is a good chance for you to practice optimizing the code.

Well, for finish this, we will modify the validateForm method, and the HTML code for our select as follows.

And now, our form looks something like this:

I hope this tutorial is useful for you, and that you have been able to understand how Vue reactivity works and how we can apply it to the task of validating our forms on the client-side. Again I point out to you that this should never replace server-side validation.

Until next time.

Share this article

Leave a Reply

1 Comment on "A Guide to Form Validation in Vue.js"

Notify of
avatar
Sort by:   newest | oldest | most voted
Steven
Guest

Nice write up. Thanks for sharing your approach.

wpDiscuz