JSのカレンダー(デートピッカー)ライブラリは何かに依存している物が多く、有名どころだとdatepickerでjQueryに依存しています。
軽量でシンプルなPikadayは、日付を簡単にコントロールするためにMoment.jsを入れる必要があります。一応頑張ればライブラリを入れなくても作れますが、コード量が多くなるのでメンテナンス性が悪くて困ります。
そんなこんなで探し回ったところ、flatpickrなら依存無しで使えるようなので試してみました。バージョンは4.6.13です。
使い方
サクッと試したいのでCDN(cdnjs)を利用します。
npmなどでインストールする場合は公式サイトを参照してください。
インストール
flatpickr本体と日本語のプラグインを入れます。
integrityなどはセキュリティのために書いてますが削除しても動作します。詳しく知りたい方はMDN Web Docsを参照してください。
<script src="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/flatpickr.min.js" integrity="sha256-Huqxy3eUcaCwqqk92RwusapTfWlvAasF6p2rxV6FJaE=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/l10n/ja.js" integrity="sha256-us400PA8+wpkgAkYwnKn7ueJbkk00UuwAcqrHqLGQJw=" crossorigin="anonymous"></script>
次にflatpickr本体のcssとテーマを入れます。
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/flatpickr.min.css" integrity="sha256-GzSkJVLJbxDk36qko2cnawOGiqz/Y8GsQv/jMTUrx1Q=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/themes/material_blue.css" integrity="sha256-vxrocMyy3+x+gmiNuoCS5Iv5rEurStwP6vnN5Mr1PfA=" crossorigin="anonymous">
これでインストールは完了です。
ここから先は公式サイトのサンプルと似たり寄ったりです。
カレンダーを表示
オプション無しで一番シンプルな方法が以下で、第1引数にセレクターやIDを指定します。
第2引数のオブジェクトにlocale:'ja'
を設定すると日本語になります。
<input type="input" id="basic">
<script>
flatpickr('#basic', {
locale: 'ja'
});
</script>
カレンダーをいくつも設置する場合はデフォルト設定に記述しておくと楽です。
同時にフォーマットを入れると手間が省けます。
flatpickr.defaultConfig = {
locale: 'ja',
dateFormat: 'Y-m-d'
}
カレンダーの日付をY-m-d
ではなく、分かりやすい形式で表示することもできます。
この場合は送信用にinput type="hidden"
要素が自動的に作成されます。
以下のaltFormat
が表示用、dateFormat
が送信用になります。
flatpickr('#human-friendly-dates', {
altInput: true,
altFormat: 'Y年n月j日',
dateFormat: 'Y-m-d'
});
選択できる日付を制限
制限方法は様々で、指定日付、範囲、関数で制限など色々あります。
本日、2日後、4日後を選択不可にします。
flatpickr('#disabling-dates', {
disable: [new Date(), new Date().fp_incr(2), new Date().fp_incr(4)]
});
本日から7日間だけ選択できるようにします。
flatpickr('#mindate-and-maxdate', {
minDate: 'today',
maxDate: new Date().fp_incr(7)
});
関数で土日を選択不可にします。
flatpickr('#disabling-function', {
disable: [
function(date){
return (date.getDay() === 0 || date.getDay() === 6);
}
]
});
from, toを使った制限で、Min Max制限と同じ動きが作れます。こちらの方が読みやすいと思います。
本日から14日間だけ選択できるようにします。
flatpickr('#enabling-dates', {
enable: [{
from: 'today',
to: new Date().fp_incr(14)
}]
});
日付と時刻
enableTime: true
でカレンダーと同時に時刻を表示できます。
時刻選択が少しわかりにくいです。
flatpickr('#datetime', {
enableTime: true,
dateFormat: 'Y-m-d H:i',
});
時刻
enableTime: true
とnoCalendar: true
で時刻のみ表示できます。time_24hr: true
にすると24hで表示されます。
flatpickr('#time', {
enableTime: true,
noCalendar: true,
dateFormat: 'H:i',
time_24hr: false
});
flatpickr('#time', {
enableTime: true,
noCalendar: true,
dateFormat: 'H:i',
time_24hr: true
});
時刻 | |
時刻24H |
時刻も制限ができます。
flatpickr('#timelimit', {
enableTime: true,
noCalendar: true,
dateFormat: 'H:i',
time_24hr: true,
minTime: '12:00',
maxTime: '17:30',
});
終わりに
flatpickrの全てをテストしたわけではありませんが、非常に短いコードと分かりやすい記述方法でカレンダーが実装できるのでオススメだと思います。
また、スマホなどで表示した場合は自動的に端末機能を優先する作りになっていて、日付の制限を行った場合はflatpickrで表示されたりと気が利いた作りです。
ただ時刻に関しては挙動が怪しい部分があるので細かい調整は必要のようです。
コピペで試せるソースコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/flatpickr.min.css" integrity="sha256-GzSkJVLJbxDk36qko2cnawOGiqz/Y8GsQv/jMTUrx1Q=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/themes/material_blue.css" integrity="sha256-vxrocMyy3+x+gmiNuoCS5Iv5rEurStwP6vnN5Mr1PfA=" crossorigin="anonymous">
<style>
body{
line-height: 1.6;
}
h2 {
margin: 2em 0 0;
}
pre {
background: #EEE;
padding: 1em;
}
input {
padding: 0.5em;
}
</style>
</head>
<body>
<h2>基本</h2>
<input type="input" id="basic">
<pre>
flatpickr('#basic');
</pre>
<h2>日付:分かりやすい形式で表示</h2>
<input type="input" id="human-friendly-dates">
<p>表示用inputフィールドが自動で作成される</p>
<p>表示用input = altFormat<br>データ送信用input(hidden) = dataFormat</p>
<pre>
flatpickr('#human-friendly-dates', {
altInput: true,
altFormat: 'Y年n月j日',
dateFormat: 'Y-m-d',
});
</pre>
<h2>日付:選択不可</h2>
<input type="input" id="disabling-dates">
<pre>
flatpickr('#disabling-dates', {
disable: [new Date(), new Date().fp_incr(2), new Date().fp_incr(4)]
});
</pre>
<h2>日付:MIN MAX 制限</h2>
<input type="input" id="mindate-and-maxdate">
<p>1週間だけ選択可</p>
<pre>
flatpickr('#mindate-and-maxdate', {
minDate: 'today',
maxDate: new Date().fp_incr(7)
});
</pre>
<h2>日付:選択不可範囲</h2>
<input type="input" id="disabling-ranges">
<pre>
flatpickr('#disabling-ranges', {
disable: [
{
from: new Date(),
to: new Date().fp_incr(2)
},
{
from: new Date().fp_incr(10),
to: new Date().fp_incr(11)
}
]
});
</pre>
<h2>日付:選択不可 関数</h2>
<p>土日は選択不可</p>
<input type="input" id="disabling-function">
<pre>
flatpickr('#disabling-function', {
disable: [
function(date){
return (date.getDay() === 0 || date.getDay() === 6);
}
]
});
</pre>
<h2>日付:選択可</h2>
<p>1週間だけ選択可</p>
<input type="input" id="enabling-dates">
<pre>
flatpickr('#enabling-dates', {
enable: [
{
from: 'today',
to: new Date().fp_incr(7)
}
]
});
</pre>
<h2>日時</h2>
<input type="input" id="datetime">
<pre>
flatpickr('#datetime', {
enableTime: true,
dateFormat: 'Y-m-d H:i',
});
</pre>
<h2>時刻</h2>
<input type="input" id="time">
<pre>
flatpickr('#time', {
enableTime: true,
noCalendar: true,
dateFormat: 'H:i',
time_24hr: false
});
</pre>
<h2>時刻:24h</h2>
<input type="input" id="time24">
<pre>
flatpickr('#time24', {
enableTime: true,
noCalendar: true,
dateFormat: 'H:i',
time_24hr: true
});
</pre>
<h2>時刻:制限</h2>
<input type="input" id="timelimit">
<pre>
flatpickr('#timelimit', {
enableTime: true,
noCalendar: true,
dateFormat: 'H:i',
time_24hr: true,
minTime: '12:00',
maxTime: '17:30',
});
</pre>
<h2>インライン</h2>
<input type="input" id="inline">
<pre>
flatpickr('#inline', {
inline: true
});
</pre>
<script src="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/flatpickr.min.js" integrity="sha256-Huqxy3eUcaCwqqk92RwusapTfWlvAasF6p2rxV6FJaE=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/l10n/ja.js" integrity="sha256-us400PA8+wpkgAkYwnKn7ueJbkk00UuwAcqrHqLGQJw=" crossorigin="anonymous"></script>
<script>
/* Localization */
//- Browser Environment
// html script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/l10n/ja.min.js"
// flatpickr('#Basic', {
// locale: 'ja'
// });
//- ES module
// import flatpickr from 'flatpickr'
// import { ja } from 'flatpickr/dist/l10n/ja.js'
// flatpickr('#Basic', {
// locale: 'ja'
// });
flatpickr.defaultConfig = {
locale: 'ja',
dateFormat: 'Y-m-d'
}
flatpickr('#basic');
flatpickr('#human-friendly-dates', {
altInput: true,
altFormat: 'Y年n月j日',
dateFormat: 'Y-m-d',
});
flatpickr('#disabling-dates', {
disable: [new Date(), new Date().fp_incr(2), new Date().fp_incr(4)]
});
flatpickr('#mindate-and-maxdate', {
minDate: 'today',
maxDate: new Date().fp_incr(7)
});
flatpickr('#disabling-ranges', {
disable: [
{
from: new Date(),
to: new Date().fp_incr(2)
},
{
from: new Date().fp_incr(10),
to: new Date().fp_incr(11)
}
]
});
flatpickr('#disabling-function', {
disable: [
function(date){
return (date.getDay() === 0 || date.getDay() === 6);
}
]
});
flatpickr('#enabling-dates', {
enable: [
{
from: 'today',
to: new Date().fp_incr(7)
}
]
});
flatpickr('#datetime', {
enableTime: true,
dateFormat: 'Y-m-d H:i',
});
flatpickr('#time', {
enableTime: true,
noCalendar: true,
dateFormat: 'H:i',
time_24hr: false
});
flatpickr('#time24', {
enableTime: true,
noCalendar: true,
dateFormat: 'H:i',
time_24hr: true
});
flatpickr('#timelimit', {
enableTime: true,
noCalendar: true,
dateFormat: 'H:i',
time_24hr: true,
minTime: '12:00',
maxTime: '17:30',
});
flatpickr('#inline', {
inline: true
});
</script>
</body>
</html>
コメント