CakePHPでJavaScriptを使う
以前の記事(CakePHPでjQueryのDatePickerを使う - yokkongの日記)で、こんなコードを書いていた。
<?php $this->Html->scriptStart(array('inline' => false)); echo <<< END function test(){ alert("クリックしました"); } END; $this->Html->scriptEnd(); ?>
これはこれで間違ってはいないのだけれど、JavaScriptの中でCakePHPの値を使うときにどう書いていいのか分からなかった。
そこで、
<?php $this->Html->scriptStart(array('inline' => false)); ?> function test(){ alert("クリックしました"); } <?php $this->Html->scriptEnd(); ?>
とすることで、JavaScriptの中でCakePHPの値を使えるようにした。
<?php $this->Html->scriptStart(array('inline' => false)); ?> $(function() { $( "#search" ) .button() .click(function() { $.ajax({ url:'<?php echo $this->Html->url('/users/search'); ?>', ...(以下略) }); }); }); <?php $this->Html->scriptEnd(); ?>
こんな感じ。
CakePHPでSearchプラグインを使ってみた
CakePHPで検索機能を作るにはどうすればいいのかな?と思いGoogle検索してみると、Searchプラグインなるものを発見。
さっそく試してみた。
参考にしたサイト
Searchプラグインを使ってCakePHPに検索を実装する | mawatari.jp
その他、「CakePHP Search Plugin」でググってヒットするいろいろなサイトを参考にさせていただきました。
Searchプラグインの導入
まず、GitHubからCakeDC/Searchをダウンロードする。
https://github.com/CakeDC/search
ダウンロードしたsearch-master.zipを解凍し、search-masterフォルダをSearchにリネームしてapp/Pluginにコピーする。
app/core/bootstrap.phpに以下を追加する。
CakePlugin::load('Search');
これでSearchプラグインが使えるようになった。
Searchプラグインを使う
Searchプラグインの使用例は上記サイトをはじめいろいろなところで紹介されているのでそちらを見た方が分かりやすい。
ここでは検索条件にラジオボタンを使った場合について書いておくことにする。
例えばusersテーブルにgender(varchar(1))というフィールドがあって、m=男性、w=女性だとする。
検索条件として『○すべて ○男性 ○女性』みたいなラジオボタンのグループを作り、『男性/女性』が選択された場合はその条件で検索、『すべて』が選択された場合は検索条件に含めない、というようなことをやりたい。
検索画面のHTMLはこんな感じ
<input type="radio" name="data[User][gender]" id="UsergenderNone" class="rental" value="none" />すべて <input type="radio" name="data[User][gender]" id="UsergenderW" class="rental" value="w" />女性 <input type="radio" name="data[User][gender]" id="UsergenderM" class="rental" value="m" />男性
モデル
<?php class User extends AppModel{ // ビヘイビアの定義 public $actsAs = array('Search.Searchable'); // 検索フィルタの定義 public $filterArgs = array( // 独自のフィルタを定義 'gender' => array('type' => 'query', 'method' => 'searchGender'), ); // 検索用フィルタ function searchGender($data = array()){ $filter = $data['gender']; // 「すべて」選択時は条件無し if (($filter=='m') || ($filter=='w')){ $conditions = array('gender' => $filter); } else { $conditions = array(); } return $conditions; } } ?>
まず、モデルでSearchビヘイビアを使用するためにactAsを定義する。
次に実際の検索条件を設定するためにfilterArgsを定義する。
検索パターンにはいろいろなものが用意されていて、例えば『'type' => 'value'』なら完全一致、『'type' => 'like'』なら部分一致という具合。
その中で『'type' => 'query'』とすると、『'method' => 'メソッド名'』で定義したメソッドを使用して独自の検索条件を定義できる。
今回の場合、「m:男性/w:女性」が選択された場合はその条件を定義して返し、それ以外の場合は空の配列を返すようにした。
実際には『array('m' => '男性', 'w' => '女性')』みたいなのをapp/Configに定義してbootstrap.phpで『Configure::load('xxx')』としておき、その配列に存在するか?みたいな判定方法がいいのかもしれない。
とりあえずこのqueryを使うとたいていの検索処理は実装できそう。
CakePHPでDatepickerの続き
CakePHPでjQueryのDatePickerを使う - yokkongの日記
先日の記事の続き。
とりあえずDatepickerヘルパーを作成して日付のカレンダー表示ができるようになったわけだけれども、一つのHTMLで複数のDatepickerヘルパーを使用した場合(例えば検索画面で日付の範囲指定など)、次のようなコードが出力されていた。
<link rel="stylesheet" type="text/css" href="/wendy/css/jquery-ui-1.10.3.custom.css" /> <link rel="stylesheet" type="text/css" href="/wendy/css/jquery-ui-1.10.3.custom.css" /> <script type="text/javascript" src="/wendy/js/jquery-1.9.1.js"></script> <script type="text/javascript" src="/wendy/js/jquery-ui-1.10.3.custom.js"></script> <script type="text/javascript" src="/wendy/js/jquery.ui.datepicker-ja.js"></script> <script type="text/javascript"> //<![CDATA[ jQuery(function($){$("#fromdate").datepicker({changeMonth: true,changeYear: true, yearRange:"1900:2023"});}); //]]> </script> <script type="text/javascript"> //<![CDATA[ jQuery(function($){$("#todate").datepicker({changeMonth: true,changeYear: true, yearRange:"1900:2023"});}); //]]> </script>
なぜかJavascriptは一つしか出ていないのにCSSは重複してしまう。
これでも問題無いのだろうが、とりあえずjQueryの読み込みはヘルパーでなくビュー側で行うようにした。
個別のビューに書くかレイアウトに書くかは使用頻度に寄るのかな?
個別のビューに書く場合は、
$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));
レイアウトに書く場合は
内にecho $this->Html->script('jquery-1.9.1'); echo $this->Html->script('jquery-ui-1.10.3.custom'); echo $this->Html->script('jquery.ui.datepicker-ja'); echo $this->Html->css('jquery-ui-1.10.3.custom');
注意点としては、
内の『echo $this->fetch('script');』よりも前に書くこと。あとはdatepickerを参照している部分、例えば上記の場合だと
<script type="text/javascript"> //<![CDATA[ jQuery(function($){$("#fromdate").datepicker({changeMonth: true,changeYear: true, yearRange:"1900:2023"});}); //]]> </script> <script type="text/javascript"> //<![CDATA[ jQuery(function($){$("#todate").datepicker({changeMonth: true,changeYear: true, yearRange:"1900:2023"});}); //]]> </script>
この部分も
<script type="text/javascript"> //<![CDATA[ jQuery(function($){$("#fromdate, #todate").datepicker({changeMonth: true,changeYear: true, yearRange:"1900:2023"});}); //]]> </script>
と書くこともできるのだが、それをCakePHPで実装できるのかどうかは分からないのでとりあえずはこのまま。
CakePHPでjQueryのDatePickerを使う
CakePHPでDATE型のフィールドをViewに表示するとき、
echo $this->Form->input('birthday');
と書くと年、月、日それぞれがSELECTタグとして出力される。
最近jQueryを使い始めて、jQuery UIの中にDatePickerというカレンダー形式で日付を入力できるものがあると知ったので、それを使えないか色々試してみた。
CakePHPでJavaScriptを使う
まずはJavaScriptをCakePHPで使う方法について。
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));
と記述する。
CakePHPでjQueryを使う
のちほど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を使う画面が多くなってきた場合を考えると、レイアウトの中に書いたほうがいいのかもしれない。
CakePHPでjQuery 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>";
CakePHPでjQuery 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);
としたほうがいいのかもしれない。
まだ日付チェックなどが残っているが、とりあえずカレンダー形式で日付を入力できるようになった。
CakePHP+NetBeans+xdebugでデバッグ
「NetBeansとxdebug使うとPHPのデバッグが捗る」と聞いたのでインストールしてみた。
これまでVB開発、Android開発をやってきた自分としては、Visual Studio、Eclipseと同じようなデバッグができて大変便利。
しかし、CakePHPで作ったアプリをデバッグしようと思い、NetBeansからデバッグ実行してみると何故かブレークポイントを設定した位置で止まってくれない。それだけでなくコメント行で止まっていたりする。ただのPHPだと何も問題無かったのに・・・と思いいろいろ調べてみると、実行構成の開始ファイルは「index.php」ではなく「app/webroot/index.php」にしないといけないらしい。
というわけで実行構成を変更してデバッグ実行したところ、きちんとブレークポイントを設定した場所で止まってくれた。
CakePHPのリクエストデータの編集
リクエストデータの値を編集しようとしたとき、1だと
$this->data['Hoge']['Moge'] = '何かの値';
としていたけれど、2では
$this->request->data['Hoge']['Moge'] = '何かの値';
こうなる。$this->dataはreadonlyらしい。
参考:http://pugiemonn.blog6.fc2.com/blog-entry-1372.html
CakePHPメモ
CakePHP勉強中
仕事でCakePHPを使うことになったのでいろいろ勉強中。
自分で使うのは初めてなので、過去に会社の人が作ったソースを参考に・・・
と思ったらそのソース、CakePHPのバージョンが1.2で2.xとはだいぶ作りが違う。
おまけにPHPのバージョンも違うのでそのまま動かそうとするとうまくいかないケースが多い。
というわけで、初めてCakePHPを使うに当たりいろいろと気付いた点、はまった点などをメモしていく予定。
CakePHPの概要を押さえるには公式のチュートリアルが一番分かりやすいと思う。
http://book.cakephp.org/2.0/ja/tutorials-and-examples/blog/blog.html
あともう1つ参考にしたサイト
初心者のためのCakePHP2 プログラミング入門 - libro
ネットにはCakePHPに関する情報はたくさんあるのだけれど、バージョン1.xをベースに書かれていることも多く、
そのまま自分の環境で試そうとするとうまくいかないこともしばしば。
なので、2.xからCakePHPを使う人も移行ガイドに目を通しておくといろいろ役に立つのかもしれない。
http://book.cakephp.org/2.0/ja/appendices/2-0-migration-guide.html
使用環境について
自分の環境は以下の通り。
Windows 7 Professional SP1 CakePHP 2.3.5 XAMPP 1.8.1 Apache 2.4.3 PHP 5.4.7 MySQL 5.5.27
参考サイト
http://cakephp.jp/
http://www.apachefriends.org/jp/xampp.html