LoginSignup
13
12

More than 5 years have passed since last update.

React v15でカレンダーを作ってみた

Last updated at Posted at 2017-01-14

React v15でカレンダーを作ってみた

仕事でもカレンダーをReactで作ることになったので、いろいろと参考にして作ってみた。
和暦の元号と年も表示します。
実際に作るのはCalendarというより、DatePickerですけどね。

表示はこんな感じです。

  平成29/2017年2月
 日  月  火  水  木  金  土
             1   2   3   4
 5   6   7   8   9  10  11
12  13  14  15  16  17  18
19  20  21  22  23  24  25
26  27  28              

ソース

ソースはCDNを使ってHTMLで記述しました。

<!DOCTYPE HTML>
<html lang="ja">
    <!-- http://qiita.com/LightSpeedC/items/8679c9d4069523b737ea -->
    <!-- http://qiita.com/ShibuyaKosuke/items/8c47ae51195ddc42ce67 -->
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
        html { font-family: 'MS Pゴシック'; font-size: 1.5em; }
        td { text-align: center; }
        </style>
        <script src="https://unpkg.com/react@15/dist/react.min.js"></script>
        <script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.38/browser.min.js"></script>
    </head>
    <body>

        <div id="$calendar1"></div>
        <hr/>
        <div id="$calendar2"></div>
        <hr/>
        <div id="$calendar3"></div>

        <script type="text/babel">

const WAREKI_LIST = [
    {from: new Date(2019,4,1),   gengo: '令和'},
    {from: new Date(1989,0,8),   gengo: '平成'},
    {from: new Date(1926,11,25), gengo: '昭和'},
    {from: new Date(1912,6,30),  gengo: '大正'},
    {from: new Date(1868,0,1),   gengo: '明治'},
];
function toWareki(date) {
    let year = date.getFullYear(), str = year;
    WAREKI_LIST.some(wareki => date >= wareki.from &&
            (str = wareki.gengo +
                (year === wareki.from.getFullYear() ? '' :
                year - wareki.from.getFullYear() + 1)));
    return str;
}

const DAY_OF_WEEKS = ['', '', '', '', '', '', ''];

// カレンダー
const Calendar = props => {
    const year = props.year || (new Date().getFullYear());
    const month = props.month || (new Date().getMonth() + 1);
    const start_dt = new Date(year, month - 1, 1);
    start_dt.setDate(start_dt.getDate() - start_dt.getDay() - 1);
    const end_dt = new Date(year, month, 0);
    end_dt.setDate(end_dt.getDate() - end_dt.getDay() + 6);
    const numOfWeeks = (end_dt - start_dt) / (24 * 3600 * 1000) / 7;

    return <table>
        <caption>{toWareki(new Date(year, month - 1, 1)) + '/' +
            year + '' + month + ''}</caption>
        <thead>
            <tr>{DAY_OF_WEEKS.map(dayOfWeek => <th>{dayOfWeek}</th>)}</tr>
        </thead>
        <tbody>
            {range(numOfWeeks).map(() => <tr>
                {range(7).map(() => <td>
                    {(start_dt.setDate(start_dt.getDate() + 1),
                    (start_dt.getMonth() === month - 1 ?
                        start_dt.getDate() : null))}
                </td>)}
            </tr>)}
        </tbody>
    </table>;
};

ReactDOM.render(<Calendar year={2016} month={12} />, $calendar1);
ReactDOM.render(<Calendar year={2017} month={1} />, $calendar2);
ReactDOM.render(<Calendar year={2017} month={2} />, $calendar3);

// range([from], to)
function range(from, to) {
    if (arguments.length === 1) to = from, from = 0;
    const arr = [];
    for (let i = from; i < to; ++i)
        arr.push(i);
    return arr;
}

        </script>
    </body>
</html>

参考

non-jQuery でカレンダー生成スクリプトを書いてみた - Qiita

wareki - npm, wareki - GitHub

13
12
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
13
12