How to easily submit a form in Next.js


A form is a document that can contain input field in which you can write, or/and a select to choose from a drop down list, and then a submit button where you can click and submit all the typed data
In this tutorial, we are going to show how to submit a form using next.js, and how to highlight input if expected data is not matching the one typed by the user.
Create the input text
We are going first to create our input component which will have:
- Title
- Required label to mention next to each input form whether it is required or not
- Description to help the user understand what to type in the input
- Default value if there is some default value to set
- onChange method for handling change in form
- a boolean validate to determine whether or not to start validation, this is useful to highlight missing fields only after the user clicked on submit
Now, go ahead and create components folder in your next.js root project, under that folder create setupcomponents.js
export function InputWithText({ title, required, description, defaultValue, onChange, validate=false }) {
// title description input field
const className= validate ? "border-2 border-red-200 rounded w-full py-1 px-2 text-black leading-tight focus:outline-double focus:border-gray-200"
:"border-2 border-gray-200 rounded w-full py-1 px-2 text-black leading-tight focus:outline-double focus:border-gray-200"
return (
<div className="mb-4 mx-2">
<label className="font-bold text-xs"> {title} </label>{required ? "(required)" : ""}
<br />
<span className="text-sm">{description}</span>
<div>
<input className={className} id="inline-full-name" type="text" defaultValue={defaultValue}
onChange={onChange} />
{validate ? <span className="text-red-500">{title} is mandatory</span> :<></>}
</div>
</div>
)
}
Styling for the component above has been done using tailwindcss, you can follow this guide to install it or you can use any styling that you feel comfortable with
Build the form
Now, let's build the form example with reusing the InputWithText, and creating the submit button
Create pages/form.js
import { InputWithText } from "../components/setupcomponents";
import { useState } from "react";
import isEmail from 'validator/lib/isEmail';
import Head from "next/head";
export default function FormValidation() {
const [candidat, setCandidat] = useState({ lastName: '', firstName: '', email: '', phone_number: '' })
const [startValidation, setValidation] = useState(false)
const onClick = () => {
setValidation(true)
if (candidat.lastName === '' || candidat.firstName === '' || candidat.email === '' || !isEmail(candidat.email)) return
alert('validation OK')
}
return (<div className=" display-block flex flex-col justify-center items-center overflow-hidden">
<Head>
<title> Next.js submit form</title>
</Head>
<div className="flex flex-col mt-6 w-3/4 justify-center">
<div className="flex w-full p-3 mt-4 border-2 flex-col border-gray-300 rounded-md mb-4 md:w-3/4">
<span className="font-bold text-2xl mb-4">Apply here</span>
<InputWithText title={"Last Name"} required={true} onChange={() => { setCandidat({ ...candidat, lastName: event.target.value }) }} validate={startValidation ? candidat.lastName === '' : false} />
<InputWithText title={"First Name"} required={true} onChange={() => { setCandidat({ ...candidat, firstName: event.target.value }) }} validate={startValidation ? candidat.firstName === '' : false} />
<InputWithText title={"Email address"} required={true} onChange={() => { setCandidat({ ...candidat, email: event.target.value }) }} validate={startValidation ? candidat.email === '' || !isEmail(candidat.email) : false} />
<InputWithText title={"Phone number"} required={true} onChange={() => { setCandidat({ ...candidat, phone_number: event.target.value }) }} validate={startValidation ? candidat.phone_number === '' : false} />
<InputWithText title={"Location"} />
<div className="m-2">
<button className="bg-black hover:bg-slate-800 text-white text-sm font-medium p-2 rounded " type="button" onClick={onClick} >
<>Submit</>
</button>
</div>
</div>
</div>
</div>)
}
The form has:
- React state for candidate which will hold lastname, firstname, phone number and email address which are required, and location input field as optional
- InputWithText component which contain the input, its label and the classname that color the border in red to notify the user that the typed text is not what it is expected
- next/Head to specify the page name
- startValidation flag to start validation only after the user hits the submit button
- onChange method which added the typed parameter by the user to the global state
Validate email address with validator
We have also use an email validator that checks for arobase, a dot and a valid email address before accepting user input, you can install it by using npm i validator, and use the method isEmail to check if the email is valid or not
import isEmail from 'validator/lib/isEmail';
const email='ali.ben@gmail.com'
const isValidEmail = isEmail(email) // => return true
Test the configuration
Now let's run our server and run http://localhost:3000/form and you will be able to see the form page
Now try to hit the submit button and you will notice that mandatory input fields are borderd with red color to indicate that they are mandatory as the image below is showing
Now try to type in some text in the mandatory field and the red border will disappear instantly
Conclusion
We have seen how to easily create a form using next.js and how to validate it, as well as to warn the user if anything is missing or that our expectation for a field is not what he/she actually typed.
If you are looking to submit your form data to an api, i recommend to check my article in this link.
Additionaly, you can check how to send a data form to an external api in this link