Home > front end >  How to validate input[type="date] in React?
How to validate input[type="date] in React?

Time:05-01

There is a component:

import React, { useEffect, useState } from "react";
import { useParams } from "react-router";
import { NavLink } from "react-router-dom";

const EditIntern = () => {
  const { id } = useParams();
  const [intern, setIntern] = useState([]);
  const [name, inputName] = useState("");
  const [email, inputEmail] = useState("");
  const [start, inputStart] = useState("");
  const [end, inputEnd] = useState("");

  const [errorNameEmpty, isErrorNameEmpty] = useState(true);
  const [errorEmailEmpty, isErrorEmailEmpty] = useState(true);
  const [errorEmailValid, iserrorEmailValid] = useState(false);
  const [errorStartEmpty, isErrorStartEmpty] = useState(true);
  const [errorEndEmpty, isErrorEndEmpty] = useState(true);

  const validEmail = new RegExp(
    /(\w ([- .']\w )*@\w ([-.]\w )*\.\w ([-.]\w )*)/gm
  );

  const dateValidate = () => {
    if (start.value > end.value) {
      console.log("Start > end");
      console.log(start.valueAsNumber);
      console.log(end.valueAsNumber);
    } else {
      console.log("Ok");
      console.log(start.valueAsNumber);
      console.log(end.valueAsNumber);
    }
  };

  useEffect(() => {
    const fetchIntern = async () => {
      const response = await fetch(`http://localhost:3001/interns/${id}`);
      const intern = await response.json();
      setIntern(intern);
    };
    fetchIntern();
    console.log(`I want to get intern with id: ${id}!`);
  }, [id]);

  return (
    <div>
      <NavLink to="/">Back to list </NavLink>
      <form>
        <label>Name</label>
        <input
          type="text"
          name="name"
          value={name}
          onChange={(e) => {
            if (e.target.value === "") {
              isErrorNameEmpty(true);
            } else {
              isErrorNameEmpty(false);
            }
            inputName(e.target.value);
          }}
          onClick={(e) => {
            if (e.target.value === "") {
              isErrorNameEmpty(true);
            }
          }}
        />
        {errorNameEmpty ? <span>Name can't be empty</span> : <></>}

        <label>Email</label>
        <input
          type="text"
          name="email"
          value={email}
          onChange={(e) => {
            if (e.target.value === "") {
              isErrorEmailEmpty(true);
            } else if (!validEmail.test(e.target.value)) {
              iserrorEmailValid(true);
              isErrorEmailEmpty(false);
            } else {
              iserrorEmailValid(false);
              isErrorEmailEmpty(false);
            }
            inputEmail(e.target.value);
          }}
          onClick={(e) => {
            if (e.target.value === "") {
              isErrorEmailEmpty(true);
            }
          }}
        />
        {errorEmailEmpty ? <span>Email can't be empty</span> : <></>}
        {errorEmailValid ? <span>Example: [email protected]</span> : <></>}

        <label>Start date</label>
        <input
          type="date"
          name="email"
          value={start}
          onChange={(e) => {
            if (e.target.value === "") {
              isErrorStartEmpty(true);
            } else {
              isErrorStartEmpty(false);
            }
            inputStart(e.target.value);
          }}
          onClick={(e) => {
            if (e.target.value === "") {
              isErrorStartEmpty(true);
            }
          }}
        />
        {errorStartEmpty ? <span>Start date can't be empty</span> : <></>}

        <label>End date</label>
        <input
          type="date"
          name="email"
          value={end}
          onChange={(e) => {
            inputEnd(e.target.value);
            if (e.target.value === "") {
              isErrorEndEmpty(true);
            } else {
              isErrorEndEmpty(false);
            }
            dateValidate();
          }}
          onClick={(e) => {
            if (e.target.value === "") {
              isErrorEndEmpty(true);
            }
          }}
        />
        {errorEndEmpty ? <span>End date can't be empty</span> : <></>}

        <input type="submit" value="Submit" />
      </form>

      <h2>{intern.name}</h2>
      <h2>{intern.email}</h2>
      <h2>{intern.internshipStart}</h2>
      <h2>{intern.internshipEnd}</h2>
    </div>
  );
};

export default EditIntern;

It has two inputs of type date. The task is to check that the start date is not greater than the end date. I created a dateValidate function for this (which doesn't work as it should).

How can you solve this problem? (Perhaps my approach to form validation is generally not correct, I’ll be happy to read about my mistakes)

CodePudding user response:

transform start date and end date to milliseconds new Date(start date).getTime() than compare it (>, <, >=) to the end date also transformed into milliseconds

CodePudding user response:

first select right property

// inputEnd(e.target.value);
if (!isNaN(e.target.valueAsNumber)) inputStart(e.target.valueAsNumber);

// ...
//...

// inputEnd(e.target.value);
if (!isNaN(e.target.valueAsNumber)) inputEnd(e.target.valueAsNumber);

then validate

// ..when user submits start validation
const onFormSubmit = (e) => {
  e.preventDefault()
  // ... 
  
  if (start < end) { 
     // blah blah....
  }
}

or better add min and max value so you dont have to check all

    <input type="date" name="start" min="2017-01-01" max="2022-01-01">

also please dont use onChage with onClick event listeners its very bad practice use either one of them, in this case onChage is pretty good.

seems use are using onClick for validating, use useEffect for validating and keep separate state for errors (object).

and check more options here MDN docs and play around with devtools (right click on element, select use in console option and see what properties it holds)

  • Related