admin管理员组

文章数量:1122832

Im using antd 5.6.3 version , RangePicker.

I'm trying to allow date range after and before 3 days from Startdate(first selected date). It needs to disable dates right away when user select start date. so i used 'disabledDate' and 'onCalendarChange' like below code, but i doesn't work. It just disabled before startdates whatever i sets 'disabledDate' option.

I can't change antd version because of other package's dependencies. Please give me any comment. Thank you.

I want to disabled date after and before 'maxDays' from startdate.

import { DatePicker } from 'antd';
import type { RangePickerProps } from 'antd/es/date-picker';
import { useState } from 'react';
import type { Dayjs } from 'dayjs';

interface Props {
  format?: string;
  maxDays?: number; // 최대 조회 기간 (일 단위)
  value?: [Dayjs | null, Dayjs | null] | null;
  onChange?: (dates: [Dayjs | null, Dayjs | null]) => void;
}

const { RangePicker } = DatePicker;

const Calendar = (props: Props) => {
  const [startDate, setStartDate] = useState<Dayjs | null>(null);
  const [selectedDates, setSelectedDates] = useState<[Dayjs | null, Dayjs | null] | null>(null);
  const [isSelectingStart, setIsSelectingStart] = useState<boolean>(true);
  const maxDays = props.maxDays || 3; // 기본 최대 조회 기간은 3일

  const disabledDate: RangePickerProps['disabledDate'] = (currentDate) => {
    if (isSelectingStart) {
      // 시작일을 선택 중일 때는 모든 날짜를 활성화
      return false;
    }

    if (!startDate) {
      // 시작일이 선택되지 않았을 때는 모든 날짜를 활성화
      return false;
    }
    // 시작일을 기준으로 -maxDays ~ +maxDays 범위 내의 날짜만 활성화
    const tooEarly = currentDate.isBefore(startDate.subtract(maxDays, 'days'), 'day');
    const tooLate = currentDate.isAfter(startDate.add(maxDays, 'days'), 'day');
    return tooEarly || tooLate;
  };

  const handleChange: RangePickerProps['onCalendarChange'] = (dates, dateStrings, info) => {
    if (dates && dates[0] && !dates[1]) {
      // 시작일이 선택되었을 때
      setStartDate(dates[0]);
    } else if (dates && dates[0] && dates[1]) {
      // 날짜 범위가 모두 선택되었을 때
      setStartDate(null); // 시작일 재선택을 위해 초기화
    }
    setSelectedDates(dates);
    setIsSelectingStart(info.range === 'start');

    if(props.onChange) {
      props.onChange(dates as [Dayjs | null, Dayjs | null]);
    }
  };


  return (
    <RangePicker
      format={props.format}
      disabledDate={disabledDate}
      onCalendarChange={handleChange}
      value={selectedDates}
    />
  );
};

export default Calendar;

Im using antd 5.6.3 version , RangePicker.

I'm trying to allow date range after and before 3 days from Startdate(first selected date). It needs to disable dates right away when user select start date. so i used 'disabledDate' and 'onCalendarChange' like below code, but i doesn't work. It just disabled before startdates whatever i sets 'disabledDate' option.

I can't change antd version because of other package's dependencies. Please give me any comment. Thank you.

I want to disabled date after and before 'maxDays' from startdate.

import { DatePicker } from 'antd';
import type { RangePickerProps } from 'antd/es/date-picker';
import { useState } from 'react';
import type { Dayjs } from 'dayjs';

interface Props {
  format?: string;
  maxDays?: number; // 최대 조회 기간 (일 단위)
  value?: [Dayjs | null, Dayjs | null] | null;
  onChange?: (dates: [Dayjs | null, Dayjs | null]) => void;
}

const { RangePicker } = DatePicker;

const Calendar = (props: Props) => {
  const [startDate, setStartDate] = useState<Dayjs | null>(null);
  const [selectedDates, setSelectedDates] = useState<[Dayjs | null, Dayjs | null] | null>(null);
  const [isSelectingStart, setIsSelectingStart] = useState<boolean>(true);
  const maxDays = props.maxDays || 3; // 기본 최대 조회 기간은 3일

  const disabledDate: RangePickerProps['disabledDate'] = (currentDate) => {
    if (isSelectingStart) {
      // 시작일을 선택 중일 때는 모든 날짜를 활성화
      return false;
    }

    if (!startDate) {
      // 시작일이 선택되지 않았을 때는 모든 날짜를 활성화
      return false;
    }
    // 시작일을 기준으로 -maxDays ~ +maxDays 범위 내의 날짜만 활성화
    const tooEarly = currentDate.isBefore(startDate.subtract(maxDays, 'days'), 'day');
    const tooLate = currentDate.isAfter(startDate.add(maxDays, 'days'), 'day');
    return tooEarly || tooLate;
  };

  const handleChange: RangePickerProps['onCalendarChange'] = (dates, dateStrings, info) => {
    if (dates && dates[0] && !dates[1]) {
      // 시작일이 선택되었을 때
      setStartDate(dates[0]);
    } else if (dates && dates[0] && dates[1]) {
      // 날짜 범위가 모두 선택되었을 때
      setStartDate(null); // 시작일 재선택을 위해 초기화
    }
    setSelectedDates(dates);
    setIsSelectingStart(info.range === 'start');

    if(props.onChange) {
      props.onChange(dates as [Dayjs | null, Dayjs | null]);
    }
  };


  return (
    <RangePicker
      format={props.format}
      disabledDate={disabledDate}
      onCalendarChange={handleChange}
      value={selectedDates}
    />
  );
};

export default Calendar;

Share Improve this question edited Nov 22, 2024 at 3:42 Sihyeon Lee asked Nov 22, 2024 at 3:38 Sihyeon LeeSihyeon Lee 112 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

You can use one state to disable date before/after the first selected date (start date) rather than using 3 states. Here's the complete code.

[email protected]

import { DatePicker } from 'antd';
import type { RangePickerProps } from 'antd/es/date-picker';
import type { Dayjs } from 'dayjs';
import { useState } from 'react';

interface Props {
    format?: string;
    maxDays?: number;
    value?: [Dayjs | null, Dayjs | null] | null;
    onChange?: (dates: [Dayjs | null, Dayjs | null]) => void;
}

const { RangePicker } = DatePicker;

const Calendar = (props: Props) => {
    const maxDays = props.maxDays || 3;

    const [selectedDates, setSelectedDates] = useState<[Dayjs | null, Dayjs | null] | null>(props.value || null);
    const value = props.value || selectedDates;

    const disabledDate: RangePickerProps['disabledDate'] = (currentDate) => {
        if (value?.[0]) {
            return currentDate.isBefore(value[0].subtract(maxDays, 'days'), 'day') || currentDate.isAfter(value[0].add(maxDays, 'days'), 'day');
        }

        return false;
    };

    const handleChange: RangePickerProps['onCalendarChange'] = (dates) => {
        setSelectedDates(dates as [Dayjs | null, Dayjs | null]);

        if (dates?.[0] && dates?.[1]) {
            props.onChange?.(dates as [Dayjs | null, Dayjs | null]);
        }
    };

    return <RangePicker format={props.format} disabledDate={disabledDate} onCalendarChange={handleChange} value={selectedDates} />;
};

export default Calendar;

In future, if you upgrade antd to latest version, disabledDate prop has second parameter info which contains from? and type field introduce in [email protected]. By using from field, you can disable the date cells without using handleChange function.

[email protected] or later

import { DatePicker } from 'antd';
import type { RangePickerProps } from 'antd/es/date-picker';
import type { Dayjs } from 'dayjs';
import { useState } from 'react';

type ValueType = [Dayjs | null, Dayjs | null] | null;
type DatesType = [Dayjs | null, Dayjs | null];

interface Props {
    format?: string;
    maxDays?: number;
    value?: ValueType;
    onChange?: (dates: DatesType) => void;
}

const { RangePicker } = DatePicker;

const Calendar = (props: Props) => {
    const { value, onChange } = props;
    const maxDays = props.maxDays || 3;

    const disabledDate: RangePickerProps['disabledDate'] = (date, info) => {
        const startDate = info.from || value?.[0];

        if (!startDate) {
            return false;
        }

        return date.isBefore(startDate.subtract(maxDays, 'days'), 'day') || date.isAfter(startDate.add(maxDays, 'days'), 'day');
    };

    return <RangePicker format={props.format} disabledDate={disabledDate} value={value} onChange={(dates) => onChange?.(dates as DatesType)} />;
};

const App = () => {
    const [value, setValue] = useState<ValueType>(null);

    return <Calendar value={value} onChange={setValue} />;
};

export default App;

Make sure Calendar component is stateful otherwise when opening the range picker after making the first selection, cells will not be disabled.

本文标签: reactjsUsing antd RangePicker ver 563 and i want to set disable date range but i can39tStack Overflow