LoginSignup
9
10

More than 3 years have passed since last update.

Reactで日付入力にカレンダー(DatePicker)を使う ※年をプルダウンで指定して元号も表示する

Last updated at Posted at 2019-12-18

概要

Reactで日付入力にカレンダー(DatePicker)を使う。

実装

React Datepickerを使うと楽。

サンプル


年:プルダウン指定(元号付き)
月:プルダウン指定
<InputeDate /> で。

import getMonth from 'date-fns/getMonth';
import getYear from 'date-fns/getYear';
import ja from 'date-fns/locale/ja';
import React from "react";
import DatePicker, { registerLocale } from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";

// jaのロケールの設定が週頭が月曜始まりになっているので日曜始まりにする
ja.options.weekStartsOn = 0;
// ReactDatepickerのロケール登録
registerLocale('ja', ja);

class InputDate extends React.Component {
    state = {
        startDate: null
    };

    handleChange = date => {
        this.setState({
            startDate: date
        });
    };

    eraHandler = yearNow => {

        const generate = (era, startYear) => {
            let yearDsp = yearNow - startYear + 1;
            if (yearDsp === 1) {
                yearDsp = "";
            } else {
                yearDsp = ('00' + yearDsp).slice(-2);
            }
            return `${era}${yearDsp}年`;
        };

        if (yearNow >= 2019) {
            return generate('令和', 2019);
        }

        if (yearNow >= 1989) {
            return generate('平成', 1989);
        }

        if (yearNow >= 1926) {
            return generate('昭和', 1926);
        }

        if (yearNow >= 1912) {
            return generate('大正', 1912);
        }
    }

    render() {
        var startYear = 1912; // カレンダーに表示する最初の西暦(大正元年となる1912を指定)
        var futureListUp = 5; // カレンダーに表示する未来の年数
        var years = Array.from({ length: getYear(new Date()) - startYear + futureListUp }, (v, k) => k + startYear).reverse();
        const months = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];

        return (
            <React.Fragment>
                <DatePicker
                    locale='ja'
                    selected={this.state.startDate}
                    onChange={this.handleChange}
                    placeholderText="日付を選択してください"
                    dateFormat="yyyy/MM/dd"
                    isClearable
                    showMonthDropdown
                    showYearDropdown
                    todayButton="今日"
                    dropdownMode="select"
                    // カレンダーのヘッダ部分をカスタマイズする
                    renderCustomHeader={({
                        date,
                        changeYear,
                        changeMonth,
                        decreaseMonth,
                        increaseMonth,
                        prevMonthButtonDisabled,
                        nextMonthButtonDisabled
                    }) => {
                        return (
                            <div
                                style={{ margin: 10, display: "flex", justifyContent: "center" }}>

                                {/* 前月ボタン */}
                                <button onClick={decreaseMonth} disabled={prevMonthButtonDisabled}>{"<"}</button>

                                {/* 年の部分 */}
                                <select value={getYear(date)} onChange={({ target: { value } }) => changeYear(value)} >
                                    {years.map((option) => (
                                        // eraHandler()で年のプルダウンに元号を付ける
                                        <option key={option} value={option}>{option}年({this.eraHandler(option)}</option>
                                    ))}
                                </select>

                                {/* 月の部分 */}
                                <select value={months[getMonth(date)]} onChange={({ target: { value } }) => changeMonth(months.indexOf(value))} >
                                    {months.map(option => (
                                        <option key={option} value={option}> {option}</option>
                                    ))}
                                </select>

                                {/* 次月ボタン */}
                                <button onClick={increaseMonth} disabled={nextMonthButtonDisabled}>{">"}</button>
                            </div>
                        );
                    }
                    }
                />
            </React.Fragment>
        );
    }
}

参考

9
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10