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


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