CakePHPでjQueryのDatePickerを使う

CakePHPでDATE型のフィールドをViewに表示するとき、

echo $this->Form->input('birthday');

と書くと年、月、日それぞれがSELECTタグとして出力される。

最近jQueryを使い始めて、jQuery UIの中にDatePickerというカレンダー形式で日付を入力できるものがあると知ったので、それを使えないか色々試してみた。

CakePHPJavaScriptを使う

まずはJavaScriptCakePHPで使う方法について。
Viewの中で$this->Html->scriptStart()と$this->Html->scriptEnd()の間にJavaScriptのコードを書く。

$this->Html->scriptStart(array('inline' => false));
echo <<< END
function test(){
    alert("クリックしました");
}
END;
$this->Html->scriptEnd();
echo $this->Form->button('押してください', array('type' => 'button', 'onClick'=>'test();'));

scriptStart()の引数に何も指定しないと記述した場所にコードが生成されるが、『array('inline' => false)』を指定するとヘッダーの中にコードが生成される。
ちなみに外部のファイルを読み込む場合は、

$this->Html->script('test', array('inline' => false));

と記述する。

CakePHPjQueryを使う

のちほどDatePickerを使うので、jQuery UIのサイトからファイルをダウンロードする。
http://jqueryui.com/
Downloadページに行くと必要なライブラリやデザインを選べるようになっている。
とりあえず今回はライブラリは全部、デザインは『No Theme』にした。
ダウンロードしたjquery-ui-1.10.3.custom.zipを解凍し、

をwebroot\jsに、

をwebroot/cssにコピーする。
Viewは以下のようになる。

$this->Html->script('jquery-1.9.1', array('inline' => false));
$this->Html->script('jquery-ui-1.10.3.custom', array('inline' => false));
$this->Html->css('jquery-ui-1.10.3.custom', null, array('inline' => false));
$this->Html->scriptStart(array('inline' => false));
echo <<< END
$(document).ready( function() {
    $("button#button1").click(function(){
        alert('クリックしました');
    });
});
END;
$this->Html->scriptEnd();
echo $this->Form->button('押してください', array('type' => 'button', 'id'=>'button1'));

jQueryの読み込みについてはとりあえず個別のViewの中に書いてみたが、jQueryを使う画面が多くなってきた場合を考えると、レイアウトの中に書いたほうがいいのかもしれない。

CakePHPjQuery UIのDatePickerを使う

DatePickerを使う前に日本語対応する。
解凍したjQuery UIフォルダの中に『development-bundle\ui\i18n\jquery.ui.datepicker-ja.js』というファイルがあるのでこれをwebroot\jsにコピーする。

$this->Html->script('jquery-1.9.1', array('inline' => false));
$this->Html->script('jquery-ui-1.10.3.custom', array('inline' => false));
$this->Html->script('jquery.ui.datepicker-ja', array('inline' => false));
$this->Html->css('jquery-ui-1.10.3.custom', null, array('inline' => false));
$this->Html->scriptStart(array('inline' => false));
echo <<< END
$(document).ready( function() {
    $( "#datepicker" ).datepicker();
});
END;
$this->Html->scriptEnd();
echo "<div>Birthday: <input type='text' id='datepicker' /></div>";

これでテキストボックスをクリックすると日付選択のカレンダーが表示されるようになった。

CakePHPjQuery UIのDatePickerを使うヘルパーを作成してみる

DatePickerの使い方が分かったので、Viewで使いやすいようにヘルパーを作ってみる。
こちらのサイトを参考にさせていただきました。
jqueryのdataPickerを使って日付をカレンダーから入力する - わんコロ餅。
ただし、こちらで書かれているのはCakePHP1.2のコードなので、2.Xに合わせていろいろ修正。

app\View\Helper\DatePickerHelper.php

<?php
    class DatepickerHelper extends AppHelper{
    //ヘルパー
    var $helpers = array("Form","Html");

    function datepicker($fieldName, $options = array()){
        //外部ファイル
        $ext = $this->Html->script('jquery-1.9.1', array('inline' => false))
            . $this->Html->script('jquery-ui-1.10.3.custom', array('inline' => false))
            . $this->Html->script('jquery.ui.datepicker-ja', array('inline' => false))
            . $this->Html->css('jquery-ui-1.10.3.custom', null, array('inline' => false));

        //テキストボックスのhtml
        $ext .= $this->Form->input($fieldName, $options);

        //テキストボックスのID
        if(isset($options["id"])) {
            $id = $options["id"];
        } else {
            $id = $this->Form->domId(array(), "for");
        }
        //スクリプト部分
        $script =
            "jQuery(function($){".
            "$(\"#".$id["for"]."\").datepicker({changeMonth: true,changeYear: true});".
            "});";

        return $ext . $this->Html->scriptBlock($script, array('inline' => false)); }
    }
?>

DatePickerのオプションについてはこちらのサイトを参考にさせていただきました。
Datepicker | jQuery UI 1.10 日本語リファレンス | js STUDIO
例えば、datepicker({changeMonth: true,changeYear: true})とすればカレンダーの上部に年、月を選択する領域が表示される。

ビューでヘルパーを使うために、コントローラーの$helpersにヘルパーの名前を書く。

var $helpers = array("DatePicker");

ビューでの書き方は次のようになる。

echo $this->Datepicker->datepicker('Birthday');

CakePHPでDATE型のフィールドをDatePicker対応のテキストに表示する

id(INT)、name(VARCHAR)、birthday(DATE)を持つテーブルUsersがあったとして、これを表示しようとすると、

echo $this->Form->create('User');
echo $this->Form->input('name');
echo $this->Form->input('birthday');
echo $this->Form->input('id', array('type' => 'hidden')); 
echo $this->Form->end('更新');

という感じのビューになる(はず)。

このままだとbirthdayは年、月、日のSELECTで表示されるので、ここをDatePickerヘルパーに置き換えてみる。

echo $this->Form->create('User');
echo $this->Form->input('name');
echo $this->Datepicker->datepicker('birthday', array('type' => 'text'));
echo $this->Form->input('id', array('type' => 'hidden')); 
echo $this->Form->end('更新');

『array('type' => 'text')』がポイントで、これが無いとテキストボックスを表示してくれない。
もっとも一つのシステム内で日付の入力形式がバラバラなのも問題なので、ヘルパー側で

$options = array_merge(array('type' => 'text'), $options);

としたほうがいいのかもしれない。
まだ日付チェックなどが残っているが、とりあえずカレンダー形式で日付を入力できるようになった。