Search code examples
reactjsreact-datepicker

Link Year, Month and Day input fields in a date picker


I am trying to customize React Datepicker for my React application following this document - https://reactdatepicker.com/

I have 3 input fields for choosing the date - Year, Month and Day. Now I need to link those fields to make sure if the user chooses February month, the Day field should show 28 days and if the user chooses a leap year in the Year field, the Day field should show 29 days.

I have following codes for the input fields:

const year = 2022; 
const month = 2; 
const date = 24;

const [myMonth, setMyMonth] = useState(new Date()); 
const [myYear, setMyYear] = useState(new Date()); 
const [myDay, setMyDay] = useState(new Date(year, month, date));

const minDate = new Date(year, month, 1); 
const maxDate = new Date(year, month + 1 , 0);

return ( 
    <div className="container"> 
       <div className="input-container"> 
         <div> 
           <label>Year</label> 
           <DatePicker 
             selected={myYear} 
             onChange={(date) => setMyYear(date)} 
             showYearPicker dateFormat="yyyy" 
           /> 
        </div> 
        <div> 
        <label>Month</label> 
        <DatePicker 
          showMonthYearPicker 
          dateFormat = "MMMM" 
          renderCustomHeader = {({date}) => (<div></div>)} 
          selected = {myMonth} 
          onChange = {(date) => setMyMonth(date)} 
        /> 
      </div> 
      <div> 
        <label>Day</label> 
        <DatePicker 
          dateFormat = "dd" 
          renderCustomHeader = {({date}) => (<div></div>)} 
          selected = {myDay} 
          minDate = {minDate} 
          maxDate = {maxDate} 
          onChange = {(date) => setMyDay(date)} 
        /> 
     </div>
);

Can anyone tell me how to link those 3 fields so that the user can consistently select a date from the above date picker ?


Solution

  • You can use following code to achieve this. Note: you must import and use useEffect hook of react

      const currentDate = new Date();
    
      const [myMonth, setMyMonth] = useState(currentDate);
      const [myYear, setMyYear] = useState(currentDate);
      const [myDay, setMyDay] = useState(currentDate);
    
      const minDate = new Date(myYear.getFullYear(), myMonth.getMonth(), 1);
      const maxDate = new Date(myYear.getFullYear(), myMonth.getMonth() + 1, 0);
    
      useEffect(() => {
        setMyDay(new Date(myYear.getFullYear(), myMonth.getMonth(), 1));
      }, [myMonth, myYear, setMyDay]);
    
      const renderDayContents = (day, date) => {
        if (date < minDate || date > maxDate) {
          return <span></span>;
        }
        return <span>{date.getDate()}</span>;
      };
    
      return (
        <div>
          <div className="container">
            <div className="input-container">
              <div>
                <label>Year</label>
                <DatePicker
                  selected={myYear}
                  onChange={(date) => setMyYear(date)}
                  showYearPicker
                  dateFormat="yyyy"
                />
              </div>
            </div>
            <label>Month</label>
            <DatePicker
              showMonthYearPicker
              dateFormat="MMMM"
              renderCustomHeader={({ date }) => <div></div>}
              selected={myMonth}
              onChange={(date) => setMyMonth(date)}
            />
          </div>
          <div>
            <label>Day</label>
            <DatePicker
              dateFormat="dd"
              renderCustomHeader={({ date }) => <div></div>}
              selected={myDay}
              renderDayContents={renderDayContents}
              onChange={(date) => setMyDay(date)}
            />
          </div>
        </div>
      );
    

    Explanation:

    1. If we want to change something if something else changes we must use userEffect hook of react. Here we are changing days that can be selected once year and month changes
    2. We are using renderDayContents property of DatePicker to dynamically populate days that can be selected depending upon selection of year and month.
    3. Default date is kept as 1st after year and month changes