Validating Input Value

Starting from version 4, date validation can be performed using the second parameter passed to the onChange method. This parameter is an object containing the following properties:

isTyping

input

validatedValue

The isTyping property indicates whether the onChange method was called due to the user typing or not. If it is true, it means that the method was called as a result of the user typing in the input field. If it is false, it means that the method was called due to date selection from the calendar component.

The input property is a reference to the input element. If you are not using a custom input, the input value is equal to the internal input reference of the date picker (HTMLInputElement). If you are using a custom input, it is equal to a div that contains your custom component (HTMLDivElement).

The validatedValue property is a string that represents the value to be displayed in the input field.

It is important to note that returning false from the onChange method will prevent the internal state of the date picker from being set. Therefore, if you consider the input date to be invalid, you should return false.

import DatePicker from 'react-multi-date-picker'
.
.
.
const [value, setValue] = useState();

<DatePicker
  value={value}
  onChange={(date, { input, isTyping }) => {
    if (!isTyping) return setValue(date); // user selects the date from the calendar and no needs for validation.

    const strings = input.value.split("/");
    const numbers = strings.map(Number);
    const [year, month, day] = numbers;

    if (input.value && numbers.some((number) => isNaN(number))) {
      return false; //in case user enter something other than digits
    }

    if (month > 12 || month < 0) return false; //month < 0 in case user want to type 01
    if (day < 0 || (date && day > date.day)) return false;
    if (strings.some((val) => val.startsWith("00"))) return false;

    setValue(date);
  }}
/>
    

Validating Range of Dates

This example demonstrates how to validate a range of dates in the DatePicker component. In this example, the goal is to reserve a room for a certain date range. The Calendar component is used with multiple and range props to allow selecting multiple ranges of dates. The initial values for reserved and in-service dates are defined in two arrays named reserved and inService.

The isReserved and isInService functions check whether a given date falls within the reserved or in-service ranges.

The mapDays prop is used to apply a class to the date elements to indicate whether they are reserved or in-service.

import React, { useState } from "react";
import { Calendar, DateObject } from "react-multi-date-picker";

const reserved = [
  [new DateObject().setDay(1).format(), new DateObject().setDay(5).format()],
  [new DateObject().setDay(7).format(), new DateObject().setDay(8).format()],
];

const inService = [
  [new DateObject().setDay(12).format(), new DateObject().setDay(13).format()],
  [new DateObject().setDay(27).format(), new DateObject().setDay(27).format()],
];

const initialValue = [...reserved, ...inService];

function isReserved(strDate) {
  return reserved.some(([start, end]) => strDate >= start && strDate <= end);
}

function isInService(strDate) {
  return inService.some(([start, end]) => strDate >= start && strDate <= end);
}

export default function Example() {
  const [values, setValues] = useState(initialValue);

  return (
    <div>
      <h5>Room reservation</h5>
      <p>Please select the date range you want to book</p>

      <div style={{ margin: "10px " }}>
        <div className="un-availble">
          <div className="reserved" />
          <p>Already reserved</p>
        </div>
        <div className="un-availble">
          <div className="in-service" />
          <p>In service</p>
        </div>
      </div>

      <Calendar
        multiple
        range
        value={values}
        onChange={(ranges) => {
          const isClickedOutsideUnAvailbleDates = initialValue.every(
            ([start, end]) => ranges.some((range) => range[0]?.format?.() === start && range[1]?.format?.() === end)
          );
          
          if (!isClickedOutsideUnAvailbleDates) return false;
          
          setValues(ranges);
        }}
        mapDays={({ date }) => {
          let className;
          const strDate = date.format();
        
          if (isReserved(strDate)) className = "reserved";
          if (isInService(strDate)) className = "in-service";
          if (className) return { className };
        }}
      />
    </div>
  )
Room reservation

Please select the date range you want to book

Already reserved

In service

style.css :

.rmdp-range:has(.reserved) {
  background-color: #8fb4f9;
}

.rmdp-range:has(.in-service) {
  background-color: #cc0303;
}

div.reserved {
  background-color: #8fb4f9;
  width: 20px;
  height: 20px;
  border-radius: 50%;
}

div.in-service {
  background-color: #cc0303;
  width: 20px;
  height: 20px;
  border-radius: 50%;
}

.un-availble {
  display: flex;
  align-items: center;
  column-gap: 10px;
}

.un-availble p {
  margin: 0;
}