I use react-dropdown-date component to select the date. It works well when the format is the following: year -> month -> day
but when I want to change the format for exmaple: day -> month -> year
then I got the issue. So, when I set the day and month the day value dissapears, clear out in the dropdown menu.
Code:
import ICustomField from '../../typings/ICostumField';
import React, {useEffect, useState} from 'react';
import {getInstanceError} from '../../utils/getInstanceError';
import {YearPicker, MonthPicker, DayPicker} from 'react-dropdown-date';
import { getUserDate } from '../../utils/utilsDate'; //getCorrectDate,
const formatDate = (date) => {
let d = new Date(date),
day = '' + d.getDate(),
month = '' + (d.getMonth() + 1),
year = d.getFullYear();
if (day.length < 2) day = '0' + day;
if (month.length < 2) month = '0' + month;
return [year, month, day].join('-');
}
const CustomField = ({register, errors, name, label, disabled, type = 'text', defaultValue = '', placeholder = '', styles = {}, setError, ...rest}: ICustomField) => {
const [touch, setTouch] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const [touchYear, setTouchYear] = useState(false);
const [touchMonth, setTouchMonth] = useState(false);
const [touchDay, setTouchDay] = useState(false);
const [selectDate, setSelectDate] = useState<any>(null);
const [year, setYear] = useState<any>();
const [month, setMonth] = useState<any>();
const [day, setDay] = useState<any>();
const minDate = new Date();
const maxDate = new Date();
minDate.setFullYear(maxDate.getFullYear() - 100);
maxDate.setFullYear(maxDate.getFullYear() + 3);
const {
getMessageError,
getClassError
} = getInstanceError(errors);
const handelBlur = () => {
setTouch(true);
};
useEffect(() => {
if (year && month && day) {
setSelectDate(new Date(year, month, day));
setIsOpen(false);
}
}, [year, month, day]);
const mes = getMessageError(name);
if (disabled) return null;
return (
<div className={getClassError(name, touch)}>
<label>{label}</label>
{type !== 'date' && (
<input
name={name}
ref={register}
type={type}
placeholder={placeholder}
onBlur={handelBlur}
defaultValue={defaultValue}
{...rest}
/>
)}
{type === 'date' && (
<>
<input
name={name}
ref={register}
value={selectDate ? getUserDate(selectDate) : ''}
onClick={() => setIsOpen(true)}
onBlur={handelBlur}
placeholder={placeholder}
readOnly={true}
/>
{isOpen &&
<div className='dateDropDown-container-modal'>
<div className='dateDropDown-close' onClick={() => setIsOpen(false)}>x</div>
<DayPicker
defaultValue={'День'}
year={year}
month={month}
endYearGiven
required={true}
value={day}
onChange={(day) => {
setDay(day);
setTouchDay(true);
}}
id={'day'}
name={'day'}
classes={touchDay ? 'dateDropDown-touch' : 'dateDropDown'}
optionClasses={'dateDropDown-option'}
/>
<MonthPicker
defaultValue={'Місяць'}
numeric
short
caps
endYearGiven
year={year}
required={true}
value={month}
onChange={(month) => {
setMonth(month);
setTouchMonth(true);
}}
id={'month'}
name={'month'}
classes={touchMonth ? 'dateDropDown-touch' : 'dateDropDown'}
optionClasses={'dateDropDown-option'}
/>
<YearPicker
defaultValue={'Рік'}
start={+formatDate(minDate).split('-')[0]}
end={+formatDate(maxDate).split('-')[0]}
reverse
required={true}
value={year}
onChange={(year) => {
setYear(year);
setTouchYear(true);
}}
id={'year'}
name={'year'}
classes={touchYear ? 'dateDropDown-touch' : 'dateDropDown'}
optionClasses={'dateDropDown-option'}
/>
</div>
}
</>
)}
{mes && <p>{mes}</p>}
</div>
)
};
export default CustomField;
Any ideas how to fix such issue? Thanks.
2
Answers
When properly debugging, I found out this issue could be releated to this component. Actually, days are calculating by
year
andmonth
ingetDaysInMonth
function. So, whenReact
code is translated toJS
, I got the following code:Code:
So, when I pick a day, it sets as
31
and when I pick a month, it sets days asNaN
because to calculate days usinggetDaysInMonth
it requires ayear
and amonth
as parameters:var days = month ? getDaysInMonth(year, month) : 31;
That is why it fails for me when I change the order/format to
day -> month -> year
. So, I decided to switch back to the previous format:year -> month -> day
. This issue is resolved. Thank you.Based on your code, it seems like the issue might be related to how the state is being managed for the day, month, and year values. Since the order of the dropdowns has changed, you need to adjust the state updates accordingly.
Here’s a modification to your onChange handlers in the DayPicker, MonthPicker, and YearPicker components to handle the change in the new order ("day -> month -> year"):
By checking if all three values (day, month, and year) are defined before updating the selectDate and closing the dropdown, you ensure that the date value is correctly updated when changing the format.
Remember to replace the respective parts of your existing code with these modified onChange handlers.
Additionally, make sure that the rest of your code, including CSS classes and styling, works well with the new format.