Date Range Picker Example using React Date Range [Customized]

Date Range Picker Example using React Date Range [Customized]


import “react-date-range/dist/styles.css”; // main css file

import “react-date-range/dist/theme/default.css”; // theme css file

import { DateRange } from “react-date-range”;

import { Box, TextField, ClickAwayListener } from “@mui/material”;

import moment from “moment”;

import { useState, useEffect, useRef } from “react”;

 

const PickDates = () => {

  const pickerStyles = {

    boxShadow: “0px 2px 10px rgba(0, 0, 0, 0.15)”,

    //TO HIDE MONTH AND YEAR DROPDOWN

    “.rdrMonthAndYearPickers”: {

      display: “none”

    },

 

    //TO HIDE THE DEFAULT DATE TEXT FIELDS PROVIDED BY THIS PACKAGE

    “.rdrDateDisplayWrapper”: {

      display: “none”

    },

    //TO ALIGN MONTH ARROW WITH MONTH NAME

    “.rdrMonthAndYearWrapper”: {

      alignItems: “unset”,

      height: “0px”,

      paddingTop: “20px”

    },

 

    //TO ALIGN CENTER MONTH AND YEAR NAME

    “.rdrMonthName”: {

      textAlign: “center”,

      fontSize: “16px”

    },

 

    “.rdrWeekDays”: {

      fontSize: “14px”

    },

 

    //TO CHANGE THE RANGE BACKGROUND COLOR

    “.rdrInRange”: {

      backgroundColor: “#3C4F5D”

    },

    //FOR RESPONSIVE DESIGN(SMALL DEVICES)

    “@media (max-width: 600px)”: {

      “.rdrMonth,.rdrCalendarWrapper”: {

        width: “100%”,

        padding: 0

      },

      “.rdrWeekDays”: {

        marginTop: “24px”

      },

      width: “100%”

    }

  };

 

  const [range, setRange] = useState({

    startDate: null,

    endDate: new Date(“”), // This is required to overcome the bug of auto-range-selection

    key: “selection”

  });

 

  const [showCalendar, setCalendarStatus] = useState(false);

  const [startDate, setStartDate] = useState(“”);

  const [endDate, setEndDate] = useState(“”);

  const startDateRef = useRef(null);

  const endDateRef = useRef(null);

  const [dateIdentifier, setDateIdentifier] = useState(null);

 

  useEffect(() => {

    setStartDate(

      moment(range.startDate).format(“YYYY-MM-DD”) === “Invalid date”

        ? “”

        : moment(range.startDate).format(“YYYY-MM-DD”)

    );

    setEndDate(

      moment(range.endDate).format(“YYYY-MM-DD”) === “Invalid date”

        ? “”

        : moment(range.endDate).format(“YYYY-MM-DD”)

    );

  }, [range]);

 

  const handleChange = (item) => {

    const { startDate, endDate } = item.selection;

    if (dateIdentifier === “startDate”) {

      //IF USER TRIES TO SELECT START DATE GREATER THAN END DATE

      if (range.endDate && startDate > range.endDate) {

        setRange((prev) => ({

          ...prev,

          startDate: startDate,

          endDate: new Date(“”)

        }));

        const newStartDate =

          item.selection.startDate !== “Invalid date”

            ? moment(item.selection.startDate).format(“YYYY-MM-DD”)

            : null;

 

        setStartDate(newStartDate);

        setEndDate(“”);

        setDateIdentifier(“endDate”);

        if (endDateRef.current) {

          endDateRef.current.focus();

        }

      } else {

        setRange((prev) => ({ ...prev, startDate: startDate }));

        const newStartDate =

          item.selection.startDate !== “Invalid date”

            ? moment(item.selection.startDate).format(“YYYY-MM-DD”)

            : null;

 

        setStartDate(newStartDate);

        setDateIdentifier(“endDate”);

        if (endDateRef.current) {

          endDateRef.current.focus();

        }

      }

    } else if (dateIdentifier === “endDate”) {

      if (range.startDate === startDate) {

        //IF USER SELECTS THE END DATE EARLIER THAN START DATE

        if (range.startDate && endDate < range.startDate) {

          setRange((prev) => ({

            ...prev,

            startDate: endDate,

            endDate: new Date(“”)

          }));

          const newStartDate =

            item.selection.endDate !== “Invalid Date”

              ? moment(item.selection.endDate).format(“YYYY-MM-DD”)

              : null;

 

          setStartDate(newStartDate);

          setEndDate(“”);

          if (endDateRef.current) {

            endDateRef.current.focus();

          }

        } else {

          setRange((prev) => ({ ...prev, endDate: endDate }));

          const newEndDate =

            item.selection.endDate !== “Invalid Date”

              ? moment(item.selection.endDate).format(“YYYY-MM-DD”)

              : null;

          setEndDate(newEndDate);

          setCalendarStatus(false);

        }

      } else {

        // USER CLICKS ON THE END DATE FIELD TO CHANGE THE DATE BUT UPDATED DATE IS COMING IN START DATE FROM PACKAGE

        if (range.startDate && startDate < range.startDate) {

          setRange((prev) => ({

            ...prev,

            startDate: startDate,

            endDate: new Date(“”)

          }));

          const newStartDate =

            item.selection.startDate !== “Invalid Date”

              ? moment(item.selection.startDate).format(“YYYY-MM-DD”)

              : null;

 

          setStartDate(newStartDate);

          setEndDate(“”);

          if (endDateRef.current) {

            endDateRef.current.focus();

          }

        } else {

          setRange((prev) => ({ ...prev, endDate: startDate }));

          const newEndDate =

            item.selection.startDate !== “Invalid Date”

              ? moment(item.selection.startDate).format(“YYYY-MM-DD”)

              : null;

          setEndDate(newEndDate);

        }

      }

    }

  };

 

  const handleClickAway = () => {

    setCalendarStatus(false);

  };

 

  return (

    <ClickAwayListener onClickAway={handleClickAway}>

      <Box

        sx={{

          display: “flex”,

          flexDirection: “column”,

          alignItems: “center”,

          justifyContent: “center”

        }}

      >

        <Box

          sx={{

            display: “flex”,

            flexDirection: “row”,

            alignItems: “center”,

            justifyContent: “center”

          }}

        >

          <TextField

            inputRef={startDateRef}

            margin=“dense”

            label=“Start Date”

            value={startDate}

            size=“small”

            onClick={() => {

              setCalendarStatus(true);

              setDateIdentifier(“startDate”);

            }}

            InputProps={{

              readOnly: true

            }}

          />

 

          <TextField

            inputRef={endDateRef}

            margin=“dense”

            label=“End Date”

            value={endDate}

            size=“small”

            InputProps={{

              readOnly: true

            }}

            onClick={() => {

              setCalendarStatus(true);

              if (startDate !== “”) {

                setDateIdentifier(“endDate”);

              } else {

                setDateIdentifier(“startDate”);

                if (startDateRef.current) {

                  startDateRef.current.focus();

                }

              }

            }}

          />

        </Box>

        {showCalendar && (

          <Box sx={pickerStyles}>

            <DateRange

              ranges={[range]}

              onChange={(item) => handleChange(item)}

              months={2} // CALENDAR WILL SHOW 2 MONTHS VIEW

              direction={window.innerWidth <= 600 ? “vertical” : “horizontal”} // FOR SMALL DEVICES CALENDAR WILL BE SHOWN VERTICAL

              scroll={{ enabled: window.innerWidth <= 600 ? true : false }}

              minDate={new Date()} //USER CANNOT SELECT DATE PRIOR TO TODAY’S DATE

              maxDate={moment().add(12, “months”).toDate()} //USER WILL BE ABLE TO SELECT END DATE MAX WITHIN 1 YEAR.

            />

          </Box>

        )}

      </Box>

    </ClickAwayListener>

  );

};

 

export default PickDates;



Cloud Software

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *