How to validate form using javascript ?

form validation using json-msg library

Cris Fandino Jr. on Jan 26, 2021

Form validation is very important in web development but in can be very messy if you will validate all the inputs and it can lead to a bunch if/else statement and that's not what we want.Now, I am going to show you how you can easily validate form on javascript.

Package that you need to install

I use my own package called json-msg you can visit the documentation if you want to learn more about it. If you are familiar of joi validation this might be easier to you.

Installation

$ npm i json-msg

Usage

First, you need to design a schema.

import jm from 'json-msg'

const schema = {
  username: jm.str({ min: 4, max: 255 }),
  password: jm.str({ min: 8, max: 50 }),
  confirmPass: jm.sameAs('password'),
}

const data = {
  username: 'xxx',
  password: '12345',
  confirmPass: 'asdfg',
}

  // to validate it
jm.validate(data,schema, {abortEarly: false});

// result
{
  username: "username characters length must be greater than 4",
  password: "password characters length must be greater than 8",
  confirmPass: "confirmPass must be the same as password"
}

As you can see you validating the object is easier when using json-msg, you just need to define a schema of your data and pass data to validate it. You can use this on the backend and front-end if you are validating data before sending it on the database.

How to use it in React ?

You need the form to be a controlled component by using state to store the value of the input in state

If you need a live example try to go to my Contact page and type anything anything on the input and you will see the error messages;

This is how I do it

import React, { useState } from 'react'
import jm from 'json-msg'

const Contact = () => {
  const [data, setData] = useState({
    name: '',
    email: '',
    message: '',
  })
  const [error, setError] = useState({})

  const dataSchema = {
    name: jm.str({ min: 4, max: 20, alphanum: true }),
    email: jm.str({ email: true, max: 50 }),
    message: jm.str({ min: 10, max: 255 }),
  }

  function handleChange({ target }) {
    const value = target.value
    setData((prevData) => {
      const cloneData = { ...prevData }
      cloneData[target.name] = value
      return cloneData
    })
    const error = jm.validate(value, dataSchema[target.name])
    setError((prevError) => {
      prevError[target.name] = error
      return prevError
    })
  }
  async function handleSubmit(e) {
    e.preventDefault()
    const errors = jm.validate(data, dataSchema, { abortEarly: false })
    if (errors) return setError(errors)
    setError({})
    setData({ name: '', email: '', message: '' })
  }

  return (
    <form onSubmit={handleSubmit}>
      <h1>Contact</h1>
      <div className="input">
        <input onChange={handleChange} value={data.name} name="name" />
        {error.name && <div className="alert alert-error"> {error.name} </div>}
      </div>
      <div className="input">
        <input onChange={handleChange} value={data.email} name="email" />
        {error.email && (
          <div className="alert alert-error"> {error.email} </div>
        )}
      </div>
      <div className="input">
        <textarea
          value={data.message}
          onChange={handleChange}
          name="message"
        ></textarea>
        {error.message && (
          <div className="alert alert-error"> {error.message} </div>
        )}
      </div>

      <button>Send</button>
    </form>
  )
}

export default Contact