すでにHTMLフォームをMithrilでそのまま使う方法は紹介しました。今回は日付入力フォームです。
軽く調べただけなのでツッコミ募集中です。
日付入力は <input type="種類">
で使える入力フォームです。一昔前だとjQuery UIのdatePicker()とか使っていて表示していたような入力フォームです。HTML 5ではこれから紹介するうちのdateとtimeしかありませんが、HTML 5.1では定義が追加されています。
caniuseですべて調べられなかったのですが、Chrome/Edge/Operaで対応している一方、IE/Firefox/Safariでは対応していません。
日時入力フォームの種類一覧
日時フォーム
| タイプ | 書き方 |
|:-:|:-:|:-:|
| 年-月 | m('input[type=month]')
|
| 年-W週 | m('input[type=week]')
|
| 年-月-日 | m('input[type=date]')
|
| 時:分 | m('input[type=time]')
|
| 年-月-日T時:分 | m('input[type=datetime-local]')
|
Mithrilでの使い方
入力フォームが扱うのは、↑の表のようなフォーマットの文字列です。valueとして与えれば初期値として設定しできるので、仮想DOMと一緒に扱うことができます。
一番簡単なmonthで紹介します。一番シンプルな例です。
controller: function() {
this.month = m.prop(null);
},
view: () => {
return m('input[type=month]', {
onchange: m.withAttr('value', ctrl.month),
value: ctrl.month()
})
}
入力された値は文字列形式でプロパティctrl.monthに格納されます。フォームが出力される値と入力値のフォーマットは同じなので、これで最低限動きます。
ですが、モデル上はDate型として扱いたいですよね?入力値の文字列をパースしてDate型にし、また出力時に期待されるフォーマットに変換すればOKです。
1.0ではストリームになると思いますが、プロパティ互換のインタフェースを保ったまま、内部のデータをDateにするには次のようにします。
var _month = null;
this.month = function(str) {
if (arguments.length > 0) {
_month = new Date(str);
}
if (_month) {
return `${('000' + _month.getFullYear()).substr(-4)}-${('0' + (_month.getMonth() + 1)).substr(-2)}`;
}
return null;
};
2016-12みたいな文字列はDateのコンストラクタに渡せば解釈してくれるので、特に難しいことはありません。
返り値の文字列にするのがちょっと厄介で、toLocaleFormat()
が使えたらなぁ・・・でもこれ非標準でFireFoxじゃないと動かないし・・・という感じですね。6月(データ上は5)を表現する時は、1をたさないと行けないんですが、2016-6ではエラーになってしまうのでゼロをいれなければなりません。次のコードは0を頭につけた状態にするためのコードです。これで複雑に見えているだけでそんなに難しいことはしてません。
js```
('0' + (_month.getMonth() + 1)).substr(-2)
datetimeもサンプルをみてもらえればコードは見にくいけどまあやっていることは難しくないと思います。
Week
====
Weekはめんどうでやってないです。すみません。2016-W30という表記から、その週の先頭の月曜日を取得する必要があります。ちなみに、1/1が月曜日でない場合は、前年のW53となります。最初の月曜日から1週目が始まります。