ページ

2012/08/26

HTML5で追加されたinput要素のtype属性の属性値dateを使ってみた

日付をフォームに入力させてJavaScriptでゴニョゴニョすることがあったのだけど
JavaScriptでnew Date()に渡すことのできる日付のフォーマットが
ブラウザごとに異なっていたのでサンプルページ作って試してみたら全部普通に動いた。

YYYY/MM/DD hh:mm:ss形式でDate生成できたのはChromeだけで
FirefoxはYYYY/MM/DD形式、IEはYYYY-MM-DD形式だった。ここまでは許せる。
Safariはアメリカ方式でMM/DD/YYYY形式じゃないとダメだったから
ガガッとサンプル作ったのに…。どういうことなの…。
参考:JavaScript new Date() Returning NaN in IE or Invalid Date in Safari | BIOSTALL

違いといえばその現象が起きたのでXHTMLで、サンプルはHTML5で作ったってことくらい。関係無さそう。謎。

ってことでブラウザ毎の差異は忘れて入力用に作ったフォームで使った<input type="date" (...) />について書く。
W3C:4.10.7.1 States of the type attribute — HTML5
WHATWG:4.10.7.1 States of the type attribute — HTML Standard
<input type="date">-HTML5タグリファレンス
仕様をちゃんと見なきゃと思うけどもなかなかきついのでHTML5リファレンスにお世話になる。

見てるとHTML5から追加されたアレコレが魅力的すぎて早く全部のブラウザで使えるようになって、
サイト制作に使えるようになってほしい。
type="date"は現在ChromeとOperaでしか使えないけど
他のブラウザではおそらくtype="text"を指定したとみなされて?普通のテキストフォームになるので
プログレッシブ・エンハンスメントとして使っちゃうこともできる。

少しショボイ方がOperaで、リッチな方がChrome。
年、月を変えるボタンとドロップダウンになってる年月表示。
自動で入るプレースホルダー(薄い字のヒント)もある。
いい加減コードとサンプルサイト晒します。HTML5 input date sample page
<section class="row center">
  <table class="center" role="presentation">
   <tr>
    <td><label for="begin">開始日</label></td>
    <td><input type="date" id="begin" name="begin" value="" /></td>
   </tr>
   <tr>
    <td><label for="end">終了日</label></td>
    <td><input type="date" id="end" name="end" value="" /></td>
   </tr>
   <tr>
    <td colspan="2">
     <input type="button" class="btn btn-primary" value="jQueryで計算" onclick="getPeriod_jQuery()" />
     <input type="button" class="btn btn-primary" value="JavaScriptで計算" onclick="getPeriod_JavaScript()" />
    </td>
   </tr>
   <tr>
    <td><label for="period">期間(日)</label></td>
    <td><input type="text" id="period" name="period" value="" /></td>
   </tr>
  </table>
  <script><!--
   function getPeriod_jQuery(){
    var begin = $('#begin').val();
    var end = $('#end').val();
    var beginDate = new Date(begin);
    var endDate = new Date(end);
    var period = ( endDate.getTime() - beginDate.getTime() ) / ( 1000 * 60 * 60 * 24 );
    $('#period').val(period);
   }
   function getPeriod_JavaScript(){
    var begin = document.getElementById('begin').value;
    var end = document.getElementById('end').value;
    var beginDate = new Date(begin);
    var endDate = new Date(end);
    var period = ( endDate.getTime() - beginDate.getTime() ) / ( 1000 * 60 * 60 * 24 );
    document.getElementById('period').value = period;
   }
  --></script>
 </section>
適当に日付を入力させて期間をJavaScriptで計算して出すだけの簡単なもの。
このときのnew Dateがブラウザ毎に受け取れる値が異なるから作ったのに普通にYYYY/MM/DDで全部できた。
動きが見たい人はサンプルページへどうぞ

tableタグのrole="presentation"という見慣れない文字列について

tableタグは表以外に(レイアウト目的で)使ってはいけないと思われているが別に禁止されていない(らしい)。
本当はCSSでレイアウトを調整することが推奨されているのだけど面倒なのでtableタグで実装した。
普通に組んだんじゃ良くないのでWAI-ARIAのrole="presentation"つけた。アクセシビリティ的にも良いらしい。
WAI-ARIA(ウェイ・アリア:Web Accessibility Initiative-Accessible Rich Internet Applications)って
流行らなそうだけど必要な人にはとことん必要なものなので知っておきたいですね。
4.9 Tabular data — HTML Standard
The Roles Model | Accessible Rich Internet Applications (WAI-ARIA) 1.0
HTML5のtable要素が表なのかレイアウト目的なのかを示す属性やら要素について調べてみた。
role="presentation"の役割は凄い。【WAI-ARIA】 - E-riverstyle Vanguard
レイアウトテーブルの使用は禁止されていない。 - E-riverstyle Vanguard
WAI-ARIA(日本語訳):日立のユニバーサルデザイン
HTML5 + WAI-ARIA: 入門篇 – terkel.jp
アクセシビリティを加速するWAI-ARIA

jQuery版とJavaScript版の日付差分取得

jQueryはいいね。ジョンの生み出した文化の極みだよ。
document.getElementByIdなんて長い文を書かなくていいんだ。
あとはJavaScript標準のDateオブジェクトを生成してgetTime()でUNIXTIMEからの経過時間をミリ秒を取得して
差分を日単位になるまで割ればオッケー☆フォームに代入しちゃおう♡

フォームにidを指定しなくてもいいんだ。そう、jQueryならね。

function getPeriod(){
 var begin = $('input[name="begin"]').val();
 var end = $('input[name="end"]').val();
 var beginDate = new Date(begin);
 var endDate = new Date(end);
 var period = ( endDate.getTime() - beginDate.getTime() ) / ( 1000 * 60 * 60 * 24 );
 $('input[name="period"]').val(period);
}
$('input[name="begin"]')はinput要素のname属性がbeginな要素を指定している。
だいたい同じ値をidとnameに指定していて、重複した感じが嫌だったのでこれは嬉しいね。

長々書いたけどサンプルページは試してみてくれたかな?大したものじゃないけどまだの人はぜひ!
HTML5 input date sample page