Help Yourself By Helping Your Users: Forms with Bootstrap 5 and VueJS 3

Introduction:

Do you need to capture data from your users using a form on your webpage? In this article we will be going over ways to use Bootstrap 5 and VueJS 3 to help with client-side form validation, but first things first.

Here are a few things that you want to consider while creating your form:

  1. What information are you capturing?
  2. Which fields are required and which ones are optional?
  3. Where can the user make mistakes?
  4. How do you want the data you receive to be formatted?

This list is by no means exhaustive, but it is vital to think about all of these things when developing your forms. Users come from many different technical backgrounds so you need to assume that the data that they send you will have mistakes. However, there are ways to help keep the data you receive consistent and reliable through form validation.

Before Implementation:

It is critical to think about the fields that you will need from your users when you are first developing your forms. I recommend limiting the number of fields to the essentials. The need to fill out a long form is something that will discourage users from filling out the form in the first place.

Once you have decided what information you would like to capture from the user, determine if all the information that is in the form is necessary for the user to submit. Can we narrow it down even further from the last step? How are we going to be contacting our leads that submit the form on our page? For example, if you will be contacting your leads primarily through email then you can make any other contact information optional, such as a phone number.

Once you have figured out the fields needed in the form you can start to dive deeper into thinking about how your users are going to interact with the form. Where are they going to make mistakes? How can you help them give you the highest quality data? Mistakes here can range from a simple typo in a name to missing a digit in a numerical value like a zip code or a phone number making it invalid when you try to contact them.

Next comes formatting to try to mitigate those mistakes. The biggest mistake that you can make when developing a form is assuming that the users entering information will know how you want it to be formatted. Identifying and counteracting these edge cases is difficult. How do you safeguard against these?

In Your HTML

This tutorial assumes some experience with Bootstrap 5 and VueJS 3.

In the code snippet below you can see an example of a form label with an input using Bootstrap 5 classes such as “row” and “col” to position the input, as well as “form-label” and “form-control” to style the label and input field. Additionally, we provide a message to the user that is displayed when the user input is invalid which gets triggered on a submission of the form.

<div class="row mb-3">
  <div class="col">
    <label for="email" class="form-label mb-0">Email Address*</label>
    <input
         id="email"
         type="text"
         name="email"
         class="form-control"
         v-model="contact.email"
         pattern="\b[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,100}\b"
         required/>
	<div class="invalid-feedback">
         Please enter a valid email.
    </div>
  </div>
</div>

Below are examples of valid and invalid inputs based on the snippet above.

If the email address does not match the regex pattern it will show the invalid message, add a red border, and display the error prompt in the right of the input.

Below is an example of a phone input that is not required and still has a pattern for validation.

<div class="row mb-3">
<div class="col">
    <label for="phone" class="form-label mb-0">Phone</label>
    <input
        id="phone"
        type="text"
        name="phone"
        class="form-control"
        pattern="^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$"
        v-model="contact.phone"/>
    <div class="invalid-feedback">
        Please enter a valid phone number.
    </div>
</div>
</div>

Below are examples of valid and invalid inputs based on the snippet above.

This input only accepts an empty field or a ten digit phone number and provides an invalid message for any other type of input like the nine digit phone number in the screenshot above.

Once you have set up your form, to validate using VueJS 3 you need to add a call to the function defined in your application to the opening form tag like in the screenshot below, as well as the Bootstrap 5 needs-validation class and the novalidate attribute.

<form novalidate class="needs-validation" name="mainForm" @submit="submitForm"  method="post">

Now your form is ready to go from the HTML side.

VueJS 3

Here is an example of what would be housed inside of your VueJS application that has been set up within your HTML page. You will need this to use VueJS within your application. This is assuming that you have already installed VueJS using the cdn or by creating a VueJS project.

Below is an example of what the data and methods section of your VueJS application would look like. The submitForm method is linked to the submission of the form as we saw by the @submit="submitForm" attribute that we added to your opening form tag. This method first checks for the existence of the values that were submitted in the form. The v-model attribute in the form input maps the data submitted with the form to the Vue data object. They are then referenced with “this.contact.firstName” etc. to be used in the submit function.

data() {
          return {
            currentYear: new Date().getFullYear(),
            now: new Date().toISOString(),
            contact: {
                firstName: "",
                lastName: "",
                email: "",
                phone: "",
                companySize: "",
            },
          };
},
methods: {
    submitForm(e) {
        const isValid =
            this.contact.firstName &&
            this.contact.lastName &&
            this.contact.email &&
            this.validEmail(this.contact.email) &&
            (!this.contact.phone ||this.validPhone(this.contact.phone));
        e.target.classList.add("was-validated");
        if (!isValid) {
            e.preventDefault();
        }
    },
    validEmail: function (email) {
        const re = /\b[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,100}\b/;
        return re.test(email);
    },
    validPhone: function (phone) {
    	const re = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
            return re.test(phone);
    },
},

Within the submitForm() function you create a boolean constant that decides whether or not the form submission from the user was valid or not. The validEmail and validPhone functions are used to check if those respective fields are formatted correctly using the same regex pattern as in the HTML form. Adding the “was-validated” class to the form is what triggers the styling of the form in the screenshots above. If the isValid constant returns false then it stops the submission of the form and the invalid messages are displayed under the form inputs.

Recap and Conclusion

Here is a brief recap of what we went over in this article:

  • Things to think about before implementation
    • What information do you want to get from your users?
    • Which fields should be required?
    • How can the user make mistakes leading to bad data?
    • What can we do to minimize those mistakes?
  • HTML for your form using Bootstrap
    • Inputs that are required with pattern
    • Input that are not required with pattern
    • Bootstrap Classes in labels, inputs, and opening form tag
    • Calling Vue functions when the form is submitted
  • VueJS for your form
    • The submitForm function
    • The use of v-model and the data object within form inputs and Vue code
    • Adding classes to form tag
    • How to check formatting of inputs within submitForm using regex

Client side validation like this is essential for creating the best user experience possible on your website.