Skip to content

An example of a form validation with a random password generator

Notifications You must be signed in to change notification settings

dking1342/form-validation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Form Validation

Prerequisites

Javascript

Introduction

This is an example of how you can create a validation for forms. It also includes an example of how you can make a random password generator and a button to toggle back and forth between an input with a password type and a text type. This is especially useful when implementing within a website that requires information from the user. This example only covers the front end of the validation. It does not cover the work that would be required to take in the POST request into Express.

Project Overview

HTML Markup

Open your code editor and make three files: one HTML5, one CSS3 and one Javascript. Make sure to link the Javascript and the CSS3 files within the HTML5 file through the link tag and the script tag.

The form will be wrapped in a div element with a class of container. Within the form you can make input fields for a variety of likely scenarios, but in this example we will be making an input field for a username, email, password, password check and a submit button. Although each will follow in the same format, they will be unique in the content that will be entered into it.

<div class="form-control ">
    <label for="username">Username</label>
    <input type="text" placeholder="Type here..." class="input-text" id="username">
    <i class="fas fa-check-circle"></i>
    <i class="fas fa-exclamation-circle"></i>
    <small></small>
</div>

Each section of the form will have a form-control container. This will keep all the important elements needed for each section which are the label, input, icon and small elements. The i elements are the tags typically used with Font Awesome. Font Awesome is a great service that provides icons which provide a graphical description of the content on your site. In this case, we will use the check and exclamation mark to denote a successful for unsuccessful attempt by the user.

You can add or remove attributes within each element as you see fit

CSS3 Styling

The styling will be done exclusively with a css stylesheet. Flexbox will be used extensively within the styling.

One clever styling tip when applying styles in different circumstances is making use of specificity. In this form, we want to have different styling when the user has successfully or unsuccessfully made an attempt at each input. By writing your css as seen below you'll see how this can be accomplished.

.form-control.success i.fa-check-circle{
  color:#229900;
  visibility: visible;  
}
.form-control.error input{
  border-color: #e74e36;
}
.form-control.error i.fa-exclamation-circle{
  color:#e74e36;
  visibility: visible;
}

This allows the icon to show red or green when the form-control container has a success or error class included. The addition or removal of the success and error class in the form-control container will be modified in the Javascript.

Javascript

State

The first step in the Javascript file is to create a 'state' for the form. State is typically a word used in React and generally means the data within the view or component. In this case, we will use this terminology to refer to the state object. You can add key/value or properties that you find applicable.

{
  field: 'username',
  output: '',
  regex: /^(?=.{8,12})(?![_.&*^%$#@!()?><;'"~`])(?![_.]{2})[a-zA-Z0-9]+(?<![_.])$/,
  empty: true,
  status: false,
  error: 'Invalid Username',
  success: 'Success',
}

This is an example of each state for the input fields.

  • Field is a way to identify each piece of state. There are other ways to identify each piece of state and that is typically done with an id property and an alphanumeric string that is either auto-generated by the backend service or a simple Math.random().
  • The output is the value that is inside the input field.
  • The regex, or Regular Expression, is a way of matching strings. This is the key tool when validating each input field. The regex depicts what is acceptable for each input field. This is up to you and how strict or easy you want the validation to be.
  • The empty property describes if the input field has text or no text.
  • The status reveals whether or not the user met the validation criteria as given in the regex property.
  • The error and success properties are template messages that will show in the HTML when a user has successfully or unsuccessfully met the validation criteria.

Events

Keyup

The next step is creating all the events that will be available. These events include a keyup, submit and a couple click.

The keyup event is triggered every time the user types in the input fields.

document.querySelectorAll('.input-text').forEach(item=>{
  item.addEventListener('keyup',(e)=>{

    pwChecker();

    // sets password check regex
    state.filter(item=> item.field === 'passwordCheck')[0].regex = new RegExp(`${document.querySelector('#password').value}`);

    // DOM elements for validation
    let identification = e.target.id;
    let text = e.target.value.trim();

    validator(e, identification, text, 'type');

  })
})

The pwChecker function will check the password and password check input fields to see if they match. This is a means of always ensuring that the password and password check input fields have the correct class applied to their form-control container.

const pwChecker = () => {
  let pass = document.querySelector('#password').value;
  let passCheck = document.querySelector('#passwordCheck').value;
  let errorMsg = state.filter(item=> item.field === 'passwordCheck')[0].error;
  let successMsg = state.filter(item=> item.field === 'passwordCheck')[0].success;

  if(pass !== passCheck){
    document.querySelector('#passwordCheck-container').className = 'form-control error';
    document.querySelector('#pwcheckSmall').textContent = errorMsg;
  } else {
    document.querySelector('#passwordCheck-container').className = 'form-control success';
    document.querySelector('#pwcheckSmall').textContent = successMsg;
  }
}    

The next piece of code will set the password check state to have the regex property equal the password output. This is the only regex that is dynamic as the password check is primarily there to ensure that it matches with the password.

The identification and text are updated based on the input field being used. The text will help the validator function know which input field is being used. The text will be dynamically entered into the respective state's output.

The validator function then takes these arguments and carries out the validation.

const validator = (e, identification, text, delivery) => {
  state
    .filter(item=> item.field == identification)
    .forEach(item=>{
      let { regex } = item;
      item.output = text;
      (item.output) ? item.empty = false : item.empty = true;
      (identification === 'passwordCheck' && delivery === 'click') ?
        item.status = true :
        item.status = regex.test(item.output);
      (!item.empty) ? styleVerify(e, item.status, item.success, item.error, delivery, identification) : resetInputField(e);
    }) 
}

The validation ends with two functions that will complete the styling for each input file. The styleVerify function will work as long as the input field has content entered by the user, while the resetInputField is called when the input field is empty.

const styleVerify = (e, status, success, error, delivery, identification ) => {

  if(status){
        
    if(delivery === 'type'){
      e.target.parentElement.className = 'form-control success';
      e.target.nextElementSibling.nextElementSibling.nextElementSibling.textContent = success;

    } else if(delivery === 'click') {

      if(identification === 'passwordCheck'){
        document.querySelector('#passwordCheck-container').className = 'form-control success';
        document.querySelector('#pwcheckSmall').textContent = success;
      }
  
      if(identification === 'password'){
        e.target.parentElement.className = 'form-control success';
        e.target.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.textContent = success;
      }
  
    } else {
      return null
    }

  } else if (!status) {
    
    if(delivery === 'type'){
      e.target.parentElement.className = 'form-control error';
      e.target.nextElementSibling.nextElementSibling.nextElementSibling.textContent = error;

    } else if(delivery === 'click') {

      if(identification === 'passwordCheck'){
        document.querySelector('#passwordCheck-container').className = 'form-control error';
        document.querySelector('#pwcheckSmall').textContent = error;
      }
  
      if(identification === 'password'){
        e.target.parentElement.className = 'form-control error';
        e.target.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.textContent = error;
      }

    } else {
      return null
    }
  
  } else {
    return null;
  }

}

You can adjust this as you see fit, but this will run through a series of conditional statements to apply the classes and styling.

resetInputField = (e) => {
  e.target.parentElement.className = 'form-control';
  e.target.nextElementSibling.nextElementSibling.nextElementSibling.textContent = '';
}

While the resetInputField function will do as it says... reset the styles and class name for the form-control container.

Submit

The submit button is the final validation for this form. It will check the state and ensure each status is set to true. If you have this connected to a backend service or to Express then this is where you can add an action and method which will be used accordingly.

form.addEventListener('submit',(e)=> (!state.every(item=> item.status === true)) ? e.preventDefault() : null)
Click

The first click event is the random password generator. There are a number of ways that you can make one of these. This example makes use of the char codes methods in Javascript. The keyboard has many different buttons and they all correspond to a number. This helps when placing inside an array and eventually randomly selecting an item from the array.

const randomPasswordGenerator = () => {
  
  // making random char array to select from
  let randNum = [...Array(10).keys()].map(x=> String.fromCharCode(x + 48));
  let randAlphaUpper = [...Array(26).keys()].map(x=> String.fromCharCode(x + 64));
  let randAlphaLower = [...Array(26).keys()].map(x=> String.fromCharCode(x + 97));
  let randSym = [...Array(3).keys()].map(x=> String.fromCharCode(x + 35));
  let randChars = [...randNum, ...randAlphaUpper, ...randAlphaLower, ...randSym];
  let randPassword = '';

  // loop that randomly selects password from random char array
  for (let index = 0; index < 20; index++) {
    let randPicker = Math.floor(Math.random() * randChars.length);
    randPassword += randChars[randPicker];
  }
    
  return randPassword;
}
document.querySelector('#rand-btn').addEventListener('click',(e)=>{
  e.preventDefault();

  // creates random password and populates password and passwordCheck input fields
  let randomPassword = randomPasswordGenerator();
  document.querySelector('#password').value = randomPassword;
  document.querySelector('#passwordCheck').value = randomPassword;

  validator(e, 'password', randomPassword, "click");
  validator(e, 'passwordCheck', randomPassword, "click")

})

The other click event is the toggle between the input attribute of type. It allows the user to see the password or have it be masked as applicable to the password and text type attributes.

document.querySelector('#visible-btn').addEventListener('click',(e)=>{
  e.preventDefault()
  if(e.target.className === 'pw'){
    document.querySelector('#password').type='text';
    e.target.classList.toggle('pw');
    document.querySelector('.fa-eye').classList.toggle('hide');
    document.querySelector('.fa-eye-slash').classList.toggle('hide');
  } else {
    document.querySelector('#password').type='password';
    e.target.classList.toggle('pw');
    document.querySelector('.fa-eye').classList.toggle('hide');
    document.querySelector('.fa-eye-slash').classList.toggle('hide');
  }
})

Conclusion

In conclusion, there are many different ways a form can be validated. This is one example that you can try and test out. It does take inspiration from React and other similar libraries with the idea of state. Please be sure to let me know if you found this useful and I hope it provides some measure of learning that can help move you forward the next time you make a form and need to create a validation for it.

About

An example of a form validation with a random password generator

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published