Hacker0x01 / react-datepicker

A simple and reusable datepicker component for React
https://reactdatepicker.com/
MIT License
8.13k stars 2.24k forks source link

Date Range using input does not update date values on input update. #3906

Open w-gluza opened 1 year ago

w-gluza commented 1 year ago

Describe the bug Changing the range value inside the input does not update the value in the calendar. Please note input works when you set up a range for the first time, when updating the date, issues arise.

To Reproduce

  1. Create date range input using:
    () => {
    const [dateRange, setDateRange] = useState([null, null]);
    const [startDate, endDate] = dateRange;
    return (
    <DatePicker
      selectsRange={true}
      startDate={startDate}
      endDate={endDate}
      onChange={(update) => {
        setDateRange(update);
      }}
      isClearable={true}
    />
    );
    };
  2. Set up a date range either by input or calendar GUI.
  3. Try to change the date using the input field. The date does not update.

PS You can also see this bug in official docs under the: Date Range using input with clear button

Expected behavior Dates updates either if they are updated through calendar GUI or by typing inside the input field.

Desktop (please complete the following information):

galmeida12 commented 1 year ago

Any updates on this issue? It seems that the current "solution" for this is to revert to v3.

MichaelMakesGames commented 1 year ago

For others looking for an interim solution, you can use onChangeRaw prop with a function like the following:

    function onChangeRaw(raw: null | undefined | string) {
        if (selectsRange) {
            if (raw != null) {
                let rawStart = raw;
                let rawEnd = '';
                if (raw.includes(' - ')) {
                    rawStart = raw.split(' - ')[0];
                    rawEnd = raw.split(' - ')[1];
                }

                const referenceDate = new Date(new Date().getFullYear(), 0, 1);
                let startDate: null | Date = null;
                try {
                    startDate = parse(rawStart, standardizedDateFormat, referenceDate);
                } catch (e) {
                    console.error('Failed to parse start date', e);
                }

                let endDate: null | Date = null;
                try {
                    endDate = parse(rawEnd, standardizedDateFormat, referenceDate);
                } catch (e) {
                    console.error('Failed to parse end date', e);
                }

                onChange([
                    startDate && isValid(startDate) ? startDate : null,
                    endDate && isValid(endDate) ? endDate : null,
                ]);
            }
        }
    }

Note: parse and isValid are imported from date-fns. Maybe not the most robust solutions; but seems to be working fine for me.

jeffmang commented 1 year ago

MichaelMakesGames, yes I tried what you did and it works for me. I thought I would provide a little more code context to help others:

 import { parse, isValid } from "date-fns";

  const handleIncidentDateChange = (dateRange: DateRange) => {
    const [startDate, endDate] = dateRange;
    const updatedClaim = {
      ...claim,
        incidentDateBegin: startDate,
        incidentDateEnd: endDate
    };
    setClaim(updatedClaim);

  };

   const standardizedDateFormat = "MM/dd/yyyy";

    const handleIncidentDateChangeRaw = (event: React.FocusEvent<HTMLInputElement>) => {
        const raw:string = event.target.value;   
        if (raw != null) {
            if (typeof raw === "string" && raw.length >= 13) {
                let rawStart = raw;
                let rawEnd = '';
                if (raw.includes(' - ')) {
                    rawStart = raw.split(' - ')[0];
                    rawEnd = raw.split(' - ')[1];
                }

                const referenceDate = new Date(new Date().getFullYear(), 0, 1);
                let startDate: null | Date = null;
                try {
                    startDate = parse(rawStart, standardizedDateFormat, referenceDate);
                } catch (e) {
                    console.error('Failed to parse start date', e);
                }

                let endDate: null | Date = null;
                try {
                    endDate = parse(rawEnd, standardizedDateFormat, referenceDate);
                } catch (e) {
                    console.error('Failed to parse end date', e);
                }

                handleIncidentDateChange([
                    startDate && isValid(startDate) ? startDate : null,
                    endDate && isValid(endDate) ? endDate : null,
                ]);
            }
        }
    }

                        <DatePicker
                            selectsRange={true}
                            startDate={claim?.incidentDateBegin}
                            endDate={claim?.incidentDateEnd}
                            onChange={(update) => {
                            handleIncidentDateChange(update);
                            }}
                            isClearable={true}
                            dateFormat="MM/dd/yyyy"
                            className="mb-1  custom-datepicker"
                            onChangeRaw={handleIncidentDateChangeRaw}
                        />
github-actions[bot] commented 6 months ago

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 10 days.

ArturoDucasse commented 5 months ago

Any updates? 👀

laug commented 3 months ago

See also #3596 and #4002 which report the same issue.