All posts

How to validate form using javascript ?

form validation using json-msg library

2 min read

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

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

Have a project in mind?

I build and run web apps end to end.

Get in touch