Validating HTML forms using BULMA and vanilla JavaScript

by Tibor Kopca Date: 31-12-2020 HTML Forms Bulma JavaScript Webdev web development data validation


Today we are going to write about contact forms and how to validate them using JavaScript.


The contact form seems to be one of the top features of every basic home page. It is a great way to encourage your visitors to make contact with you, by adding a form which is nice to look at, simple to use and easy to submit. A good web form should to some extent follow the well-known, popular usual style so that your users already have knowledge on how to fill out its input fields and never have to think twice about what kind of data is required and where. We mean the user should never wonder which field is required and which is optional and how to fill them out correctly and how to submit the form successfully.

Form creation rules


Before starting to create the form itself, it is a good practice to take the time and think about what kind of information you are going to ask your user. And also, which fields are going to be required and which can be submitted empty? Are there any restrictions when it comes to the format of the data that he/she enters?
A HTML form’s complexity may range from a plain and simple contact form where we only ask the user to fill out his name, email, phone and a message or it may be a more elaborate form as is the case with new user registration, for example.
We want to make our form better by giving the user interactive real time feedback about if he is filling out the input fields correctly, and let him know if there is a field missing or if it is incorrect.

Data validation


Another aspect is the question of data validation. Every time you need to work with input generated by some user, you MUST validate that the data he is submitting is in accordance with your expectations. This means there are conditions, like for example an email input field should definitely contain the @ sign and then a . followed by the domain name. Or a phone number should consist of the + sign and numbers exclusively. Also, you might wish to check that the length of the word that the user has entered is greater than a certain number of characters, so for example you might not want people submitting words shorter than let’s say 3 characters as the message’s body.

Another interesting effect of validating your data in the front-end part of your website’s code is the added advantage of protection against cyber attacks. Always think that if there are input fields in your page, a malicious agent such as a bot might come and attack your site’s code, integrity or availability and thus try and hack your web. Best way of preventing things like this from happening is by double hacker-proofing your code by using front end validation mechanisms like JavaScript validation as well as back end, server-side data validation. These two should make a protection-duo to make it as much difficult as possible for attackers to infiltrate your site.

Contact form accessibility


When designing a contact form, it is of great usefulness to make use of special HTML attributes to make your form more accessible. By this we mean to assign correctly the order of the input fields so that the form can be easily navigated by using keyboard only. You can also improve the ease of use by using the label element, so that input fields are focused upon clicking on the title assigned in the label.

Bulma integration


How can we make use of BULMA in the case of designing html contact forms?
Bulma is a framework, a library similar to Bootstrap which if you learn to use can simplify the css part of your job when designing a web page. We will especially make use of the Bulma’s form section. It’s based on flexbox so we make use of it to position our elements on the screen - specifically our icons. In our little example, the classes will be the modifiers that will tell the icons where to shift or how to look like and that’ll make our life a bit easier.

Has-icons-right, has-icons-left, is-danger, is-small, is-right, etc.

Bulma_form_example

We aim to create a simple contact form, in which will be using the following HTML mark-up:

<section class="section" id="contact">
      <div class="container is-max-desktop">
        <h2 class="title">CONTACT</h2>
        <h3>If you wish to get in touch with Majka, send her a message</h3>
        <form accept-charset="utf-8" action="sendmail.php" method="post" enctype="multipart/form-data">
        </form>
      </div>
</section>

Now this alone will not be sufficient, we also want to have input fields and some buttons, so we add inside element <form> the following - name, email, phone number and message fields and a submit button.

<!--Name field-->
<div class="field">
<label class="label" for="name">Your Name</label>
<div class="control has-icons-right">
            <input class="input needs-validation inputNameField" type="text" name="name" placeholder="name maximum 20 characters" value="" id='inputName' />
            <span class="icon is-small is-right">
                <i id='nameCheckIcon' class="fas fa-exclamation-triangle"></i>
            </span>
     </div>
</div>
 
<!--Email field-->
<div class="field">
     <label class="label" for="email">Email</label>
     <div class="control has-icons-left has-icons-right">
            <input class="input needs-validation inputEmailField" type="email" name="email" placeholder="[email protected]" value="" id='inputEmailField' />
            <span class="icon is-small is-left">
                <i class="fas fa-envelope"></i>
            </span>
            <span class="icon is-small is-right">
                <i id='emailCheckIcon' class="fas fa-exclamation-triangle"></i>
            </span>
     </div>
     <p id="emailActionHint" class="help is-danger nezobrazovat">Please enter a valid email so Majka can reach you</p>
</div>
 
<!--Phone number field-->
<div class="field">
     <label class="label" for="number">Phone Number</label>
     <div class="control has-icons-left has-icons-right">
            <input class="input is-warning" type="text" name="number" placeholder="" value="" />
            <span class="icon is-small is-left">
                <i class="fas fa-phone"></i>
            </span>
            <span class="icon is-small is-right">
                <i class="fas fa-exclamation-triangle"></i>
            </span>
      </div>
</div>
 
<!--Message field-->
<div class="field">
     <label class="label">Your Message</label>
     <div class="control">
           <textarea class="textarea" name="message" placeholder=""></textarea>
     </div>
</div>
 
<!--Submit checkbox-->
<div class="field">
     <div class="control">
             <label class="checkbox">
                  <input type="checkbox" />
                I agree to the <a href="#">terms and conditions</a>
           </label>
</div>
</div>
 
<!--Submit button-->
<div class="field is-grouped">
     <div class="control">
         <button class="button is-light" id="submitButton" disabled="true">Submit</button>
     </div>
</div>

As you can see, we have four different input fields:
Contact_form_basic

This line we add to the end of the body, but before closing element </body>. This will do that the javascript will be loaded after the HTML code is executed, or we can add “async defer” property to the <script>, which will do the trick and then your script could be placed anywhere on the page and still the script will run at the end like we want.

<script src="js/main.js?v6" async defer></script>

Note: If you're asking what is “?v6” behind the .js file, that's the version of the JS code, when you need your code editor would read the latest non cached code, you just raise the number of the version and it will load your latest changes to the code.


And now let’s set up the most interesting part – the JavaScript code to check the fields’ content and validate their state:
First we can define constants which will represent our elements we want to work with.

const ourParallax = document.getElementById('parallax')
const parallaxInstance = new Parallax(ourParallax)
const submit = document.getElementById('submitButton')
const inputName = document.getElementById('inputName')
const inputEmail = document.getElementById('inputEmailField')
const iconName = document.getElementById('nameCheckIcon')
const iconEmail = document.getElementById('emailCheckIcon')
const MAXCHARNAMEFIELD = 20
const MINCHARNAMEFIELD = 3

Note: If you need to read about how to select different DOM elements for your JS code, we have excellent article about the topic here : https://www.ma-no.org/en/programming/javascript/first-steps-into-javascript-modifying-the-DOM.
But let's continue. We now set up Event Listeners which will be waiting for some specific action to be happening.

// EVENT LISTENERS
document.addEventListener('change', event => {   
 
  if (event.target.matches('.inputNameField')) {
    validateName()
  } else if (event.target.matches('.inputEmailField')) {
    validateEmail(event.target.value)
  } else {
    //nothing
  }
}, false)

To describe it further - on the whole page we have one listener and when something will change - like its defined inside the parentheses is set on what event -> on ‘change’, it will execute the arrow function. Inside the arrow function we have an IF statement to resolve if the event happened on some of the next elements we have.


For example, if there is some ‘change’ event - we write something in the HTML element input field which has CSS class .inputNameField, IF statement will be true and the next code will be executed. And the code which we have on execution is function validateName() - it's time to describe its code now :


Name Validation

function validateName() {
  var regexString = /w?s?w/g; //words separated by space
 
  const iconName = document.getElementById('nameCheckIcon')
  const conditions =
    (inputName.value.length > MINCHARNAMEFIELD) &&
    (inputName.value.length < MAXCHARNAMEFIELD) &&
    (inputName.value != null) &&
    (regexString.test(inputName.value))  //test for regex string
  console.log(regexString.test(inputName.value))
 
  if (conditions) {
    // input box color
    inputName.classList.remove('is-danger')
    inputName.classList.add('is-success')
    // icon type
    iconName.classList.remove('fa-exclamation-triangle')
    iconName.classList.add('fa-check')
    // console.log("icon :" + icon.classList.value)
 
    //now we call submit button test
    nameValidated = true
    submitCheck()
  } else {
    // input box color
    inputName.classList.remove('is-sucess')
    inputName.classList.add('is-danger')
    // icon type
    iconName.classList.remove('fa-check')
    iconName.classList.add('fa-exclamation-triangle')
 
    nameValidated = false
  }
}

We define variable with regular expression first.
Also we add two constants to the definition of the variables at the start, which will represent the minimum and maximum characters we want our input field to have. This is the right way to do it, this way you won't have any undescribed constants in your conditionals, so called ‘magic numbers’.

const MAXCHARNAMEFIELD = 20
const MINCHARNAMEFIELD = 3

We make new variable to the icon we would be working with, so far the icon which belongs to the Name input field has Bulma class ‘fa-exclamation-triangle’, and we will change it when the input field is correctly filled.


Next we have series of conditions we want to be checked - input will be checked against all of them and when all are boolean true, for the element set to the variable inputName = document.getElementById('inputName') -declared earlier, we remove the class ‘is-danger’ and we add class ‘is-success’. This will change the color of the field to green. Similarly, to the icon we remove ‘fa-exclamation-triangle’ and add ‘fa-check’, which will make that check icon is displayed.


We declare new variables with default state = false ,added to the start of the file where we have other variables.

var nameValidated = false
var emailValidated = false

Also we want to set a new variable when the input field for the name is correctly filled to ‘true’. This will be useful when we come to the submit button later. The last thing is to call the function submitCheck() every time the change happens to the form. It will execute that function but so far we can ignore it until later. Allright, we should have this:


Forms_validation_input_name

Email Validation


Next we have validateEmail(value) function, which will be called when some ‘change’ event happens on this HTML element, remember?

else if (event.target.matches('.inputEmailField'))

This function also uses regular expressions to evaluate if the input is in accordance with the usual email. We pass the value of the input field when filled by a user to the function upon calling it.

validateEmail(event.target.value)

function validateEmail(value) {
  const iconEmail = document.getElementById('emailCheckIcon')
  const emailParagraph = document.getElementById('emailActionHint')
 
  if (validateRegexString(value)) {
    // input box color
    inputEmail.classList.remove('is-danger')
    inputEmail.classList.add('is-success')
    // icon type
    iconEmail.classList.remove('fa-exclamation-triangle')
    iconEmail.classList.add('fa-check')
    emailParagraph.style = 'display:none'
 
    emailValidated = true
    submitCheck()
  } else {
    // input box color
    inputEmail.classList.remove('is-sucess')
    inputEmail.classList.add('is-danger')
    // icon type
    iconEmail.classList.remove('fa-check')
    iconEmail.classList.add('fa-exclamation-triangle')
    emailParagraph.style = 'display:block'
 
    emailValidated = false
  }
}

Let's describe the function.
We declare as variable two elements, icon and paragraph with text we want to show, this paragraph is momentarily hidden (CSS style display:none) so by the load of the page by default there is no text shown.
Next we have a condition where we have called yet another function added to the code - validateRegexString(value), which returns true when the string entered into the input is validated by this function.

function validateRegexString(email) {
  const regexString = /^(([^<>()[].,;:[email protected]"]+(.[^<>()[].,;:[email protected]"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/
    return regexString.test(String(email).toLowerCase()) // true|false
}

Well if the condition is fulfilled and we for example have a valid email, valid in the sense of the characters entered are looking as an email address, the code will remove red color from the input field, add green color (Bulma classes), from icon removes exclamation triangle and adds check pictogram. Also it keeps from displaying any warning text we have prepared in the element <p> with id = ‘emailParagraph’.

Form_validation_input_email
At the end like in the previous validateName() function we have added emailValidated = true and call to the submitCheck() function.

Submit Button


The next and the last element we will be showing is how to make the submit button disabled and only be enabled after the data we want are filled in. So for example we can make the button unclickable unless there is a filled input field name and email, but not the phone and text message, which could be empty. Let's get to the code.


Form_validation_submit_button_disabled
Remember that we have two variables defined by default, nameValidated and emailValidated, and we can use them in the condition to the function submitCheck() - it will be called every time when the input field for name and email is successfully validated. When both are validated and in our variables value is now set to true, the button would be unblocked by removing the attribute ‘disabled’ which has by default.

function submitCheck() {
  const emailParagraph = document.getElementById('emailActionHint')
  console.log(nameValidated, emailValidated)
  if (nameValidated && emailValidated) {
 
    submit.disabled = false;              //button is no longer no-clickable
    submit.removeAttribute("disabled");   //detto
  } else {
    emailParagraph.style = 'display:block'  //email warning shows up
  }
}

Form_validation_submit_button_enabled

Conclusion


And that’s it! We successfully designed a simple contact form which can be (and in some form should be) used on any web page. The HTML markup makes correct use of accessibility enhancing attributes. Thanks to the Bulma CSS framework, our form has a neat and elegant look, with icons and colors providing the user with feedback on if the form is filled out correctly. The validation part is possible thanks to our simple vanilla JS script, which uses regular expressions and simple mathematical functions to confirm the data entered is valid.

 
by Tibor Kopca Date: 31-12-2020 HTML Forms Bulma JavaScript Webdev web development data validation hits : 7674  
 
Tibor Kopca

Tibor Kopca

From tinkering with computers as a teenager, through a career in datacenter he stepped into web development with full force and started coding. Absorbs all information like a sponge.
Fan of aerospace, engineering, information technologies and watches.

 
 
 

Related Posts

Dates in local format with Javascript

In the articles we have about dates in JavaScript we were missing one about how to create dates in local format with JavaScript. That is to say, being able to…

Formatting hours in Javascript

Continuing with the set of articles that talk about internationalisation elements, like the previous one where we talked about relative dates in JavaScript, we will see in this one how…

Request data with prompt in JavaScript

After having published several articles about how to manipulate arrays and dates, today I will publish a post that some of you will find too basic and others will find…

Relative dates in JavaScript

One of the interesting things about the internationalisation library represented in the Int object is the handling of relative dates in Javascript. This handling allows us to represent a date…

How to access webcam and grab an image using HTML5 and Javascript

We often use webcams to broadcast video in real time via our computer. This broadcast can be viewed, saved and even shared via the Internet. As a rule, we need…

The JavaScript forEach loop

We have already talked about how to handle some of loops  types in Javascript including for, for-in and for-off loops. In the case of today we are going to see how…

What are React Hooks and what problems they solve

Working with React, - and before the release of Hooks in version 16.8 -  there was always the possibility to create components in three different ways based on a number of…

Flattening arrays in JavaScript

When we are handling arrays that are arrays or have multiple dimensions it can be very useful to know how to flatten arrays in JavaScript. That is to say, to…

How to populate an array with random numbers in JavaScript

Some of you might think that what we explained in the article on how to populate an array with numbers, apart from the didactic part, would not have much applicability…

How to populate an array with numbers in JavaScript

Populate an array with numbers in JavaScript The first step is to initialise the array. So today we are going to see a simple way to do it and see how…

Top Javascript Libraries and Frameworks Part 2

What are JavaScript frameworks?   JavaScript frameworks are application frameworks that allow developers to manipulate code to meet their particular needs. Web application development is like building a house. You have the option…

How to Send Email from an HTML Contact Form

In today’s article we will write about how to make a working form that upon hitting that submit button will be functional and send the email (to you as a…

We use our own and third-party cookies to improve our services, compile statistical information and analyze your browsing habits. This allows us to personalize the content we offer and to show you advertisements related to your preferences. By clicking "Accept all" you agree to the storage of cookies on your device to improve website navigation, analyse traffic and assist our marketing activities. You can also select "System Cookies Only" to accept only the cookies required for the website to function, or you can select the cookies you wish to activate by clicking on "settings".

Accept All Only sistem cookies Configuration