Reset ant design RangeSelect value after it closes

62 Views Asked by At

I open ant design range select and move to a previous date and then close it without selecting any date or year then I reopen it, but it still shows me the date that I navigated to.

I want to show the current date whenever I open range select unless a date is selected.

Here is my code

import { useState } from 'react';

import { LineOutlined } from '@ant-design/icons';
import { DatePicker, TimeRangePickerProps } from 'antd';
import { RangePickerProps } from 'antd/es/date-picker';
import dayjs, { Dayjs } from 'dayjs';
import { RangeValue } from 'rc-picker/lib/interface';

type PropType = { handleRangeSelect?: (arg1: MaybeNull<string[]>) => void };

export const CustomRageSelect = ({ handleRangeSelect }: PropType) => {
  const [dateRange, setDateRange] = useState<RangeValue<Dayjs> | undefined>(null);

  const { RangePicker } = DatePicker;
  const today = dayjs();
  const firstDayOfThisWeek = today.startOf('week').add(1, 'days');
  const lastDayOfThisWeek = today.endOf('day'); // Assuming the week ends on Saturday

  const firstDayOfLastWeek = firstDayOfThisWeek.subtract(1, 'week');

  const rangePresets: TimeRangePickerProps['presets'] = [
    { label: 'Today', value: [today, today] },
    { label: 'Yesterday', value: [today.subtract(1, 'day'), today] },
    { label: 'This Week', value: [firstDayOfThisWeek, lastDayOfThisWeek] },
    { label: 'Last Week', value: [firstDayOfLastWeek, firstDayOfLastWeek.add(6, 'days')] },
    { label: 'This Month', value: [today.startOf('month'), today] },
    { label: 'Last Month', value: [today.subtract(1, 'month').startOf('month'), today.subtract(1, 'month').endOf('month')] },
    { label: 'This Year', value: [today.startOf('year'), today] },
    { label: 'Last Year', value: [today.subtract(1, 'year').startOf('year'), today.subtract(1, 'year').endOf('year')] },
    { label: 'All Time', value: null as unknown as [dayjs.Dayjs, dayjs.Dayjs] },
  ];

  const onRangeChange = (dates: null | (Dayjs | null)[], dateStrings: string[]) => {
    if (dates) {
      setDateRange(dates as RangeValue<Dayjs>);
      handleRangeSelect && handleRangeSelect(dateStrings);
    } else {
      setDateRange(null);
      handleRangeSelect && handleRangeSelect(null);
    }
  };

  // const disabledDate: RangePickerProps['disabledDate'] = (current) => {
  //   return current !== null && dayjs(current).isAfter(dayjs(), 'day');
  // };
  const disabledDate: RangePickerProps['disabledDate'] = (current) => {
    const tenYearsAgo = dayjs().subtract(10, 'years');
    return (current !== null && dayjs(current).isAfter(dayjs(), 'day')) || dayjs(current).isBefore(tenYearsAgo, 'day');
  };

  return (
    <RangePicker
      presets={rangePresets}
      onChange={onRangeChange}
      value={dateRange}
      className="btn-style heading5 font-weight-600 font-size-14 "
      separator={<LineOutlined rotate={90} style={{ color: '#E0E0E0', maxWidth: '248px' }} />}
      style={{ minWidth: '240px', gap: '0' }}
      picker="date"
      disabledDate={disabledDate}
    />
  );
};
2

There are 2 best solutions below

1
Keyboard Corporation On

Reset the dateRange state to default value by using the useEffect with an empty dependency array.

import { useState, useEffect } from 'react'; // Add useEffect

import { LineOutlined } from '@ant-design/icons';
import { DatePicker, TimeRangePickerProps } from 'antd';
import { RangePickerProps } from 'antd/es/date-picker';
import dayjs, { Dayjs } from 'dayjs';
import { RangeValue } from 'rc-picker/lib/interface';

type PropType = { handleRangeSelect?: (arg1: MaybeNull<string[]>) => void };

export const CustomRageSelect = ({ handleRangeSelect }: PropType) => {
  const [dateRange, setDateRange] = useState<RangeValue<Dayjs> | undefined>(null);

  // Reset the date range to the current year and dates whenever the component is rendered
  useEffect(() => {
    const today = dayjs();
    setDateRange([today.startOf('year'), today]);
  }, []);

  const { RangePicker } = DatePicker;
  const today = dayjs();
  const firstDayOfThisWeek = today.startOf('week').add(1, 'days');
  const lastDayOfThisWeek = today.endOf('day'); // Assuming the week ends on Saturday

  const firstDayOfLastWeek = firstDayOfThisWeek.subtract(1, 'week');

  const rangePresets: TimeRangePickerProps['presets'] = [
    { label: 'Today', value: [today, today] },
    { label: 'Yesterday', value: [today.subtract(1, 'day'), today] },
    { label: 'This Week', value: [firstDayOfThisWeek, lastDayOfThisWeek] },
    { label: 'Last Week', value: [firstDayOfLastWeek, firstDayOfLastWeek.add(6, 'days')] },
    { label: 'This Month', value: [today.startOf('month'), today] },
    { label: 'Last Month', value: [today.subtract(1, 'month').startOf('month'), today.subtract(1, 'month').endOf('month')] },
    { label: 'This Year', value: [today.startOf('year'), today] },
    { label: 'Last Year', value: [today.subtract(1, 'year').startOf('year'), today.subtract(1, 'year').endOf('year')] },
    { label: 'All Time', value: null as unknown as [dayjs.Dayjs, dayjs.Dayjs] },
  ];

  const onRangeChange = (dates: null | (Dayjs | null)[], dateStrings: string[]) => {
    if (dates) {
      setDateRange(dates as RangeValue<Dayjs>);
      handleRangeSelect && handleRangeSelect(dateStrings);
    } else {
      setDateRange(null);
      handleRangeSelect && handleRangeSelect(null);
    }
  };

  // const disabledDate: RangePickerProps['disabledDate'] = (current) => {
  //   return current !== null && dayjs(current).isAfter(dayjs(), 'day');
  // };
  const disabledDate: RangePickerProps['disabledDate'] = (current) => {
    const tenYearsAgo = dayjs().subtract(10, 'years');
    return (current !== null && dayjs(current).isAfter(dayjs(), 'day')) || dayjs(current).isBefore(tenYearsAgo, 'day');
  };

return (
    <RangePicker
      presets={rangePresets}
      onChange={onRangeChange}
      value={dateRange}
      className="btn-style heading5 font-weight-600 font-size-14 "
      separator={<LineOutlined rotate={90} style={{ color: '#E0E0E0', maxWidth: '248px' }} />}
      style={{ minWidth: '240px', gap: '0' }}
      picker="date"
      disabledDate={disabledDate}
    />
  );
};


1
Nymeria On

You can use the onOpenChange prop. The documentation says onOpenChange is the callback function which can be executed whether the popup calendar is popped up or closed.

So you should listen for when the popup is closed and reset the calendar.

// add onOpenChange props to the RangePicker component
const onOpenChange = (isOpen) => {
  if(!isOpen) {
    const today = dayjs();
    setDateRange([today.startOf('year'), today]);
  }
}