1

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 ?

sazzad rahman
  • 23
  • 2
  • 5

1 Answers1

1

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
  • thank you! the popups of 3 input fields are in different shapes. How can i make them same shape ? – sazzad rahman Mar 30 '22 at 17:23
  • the shape of DatePicker is depended on the content inside. in you case all DatePicker has different content hence they have different shape. Currently there are not direct properties given with which we can set Height and Width of DatePIcker. Try achieving this by overriding class. If your original question is answered then you can accept the answer – Shreekesh Murkar Mar 31 '22 at 04:50
  • Did above answer work? – Shreekesh Murkar Mar 31 '22 at 07:08