Search code examples
javascriptreactjscalendarreact-dates

How to add a select for a year in react-dates?


It's a pain to swipe months right until I get to the right year with react-dates, is it possible to add some select for the year/month?


Solution

  • Yes, it is possible since version react-dates@17.0.0! (relevant pull request).

    1. npm install react-dates@latest
    2. You will likely need to update a few things as per the docs, because of the breaking changes (for me it was css mostly).
    3. Then utilize the newly introduced renderMonthElement prop to write your custom month&year selectors, for example:

      import React from 'react';
      import moment from 'moment';
      import { SingleDatePicker } from 'react-dates';
      
      class Main extends React.Component {
        state = {
          date: moment(),
          focused: true
        }
      
        renderMonthElement = ({ month, onMonthSelect, onYearSelect }) =>
          <div style={{ display: 'flex', justifyContent: 'center' }}>
            <div>
              <select
                value={month.month()}
                onChange={(e) => onMonthSelect(month, e.target.value)}
              >
                {moment.months().map((label, value) => (
                  <option value={value}>{label}</option>
                ))}
              </select>
            </div>
            <div>
              <select value={month.year()} onChange={(e) => onYearSelect(month, e.target.value)}>
                <option value={moment().year() - 1}>Last year</option>
                <option value={moment().year()}>{moment().year()}</option>
                <option value={moment().year() + 1}>Next year</option>
              </select>
            </div>
          </div>
      
        render = () =>
          <SingleDatePicker
            date={this.state.date}
            onDateChange={(date) => this.setState({ date })}
      
            focused={this.state.focused}
            onFocusChange={({ focused }) => this.setState({ focused })}
      
            renderMonthElement={this.renderMonthElement}
          />
      }