フォームヘルパーのチェックボックスの取り扱い
CakePHPのフォームヘルパーでチェックボックスを出力したときのお話。
デフォルトの状態でチェックをつけておくには、、
第2引数の属性にチェックを入れればいいのだけど(↓こんな感じで)
echo $form->checkbox('test', array('checked' => 'checked'));
例えば、DBに登録されているデータから特定のチェックボックスにだけチェックを入れたい、みたいなとき。
これはつい先日実際にあったお話ですが(別にホラーじゃないよ)、学校検索のページを作ってて、検索用のワードと学校の情報をHABTMで紐付けたんすよ。で、キーワードの新規入力画面で該当する学校を一覧から複数、チェックボックスで指定すると、そんな感じです。
例えば、『テニスが強い』というキーワードに『青春学園』『立海大付属』『氷帝学園』を紐づける、みたいな感じです。
HABTMでアソシエーションして、このキーワードのデータを引っ張って来ると、もちろん上記の3校のデータも同時に引っ張って来れるわけですが、編集画面に行ったとき、この3校の部分にはあらかじめチェックが入っているのが望ましいっすよね。
HABTMってどうもデータの形が変則的で、だから引っ張って来たデータをそのまま$this->dataにぶっ込むだけだと、チェックがついてくれないみたいなんですね。青学不二の消えるサーブ並に「そのチェック、消えるよ」ってな具合です。
で、どうしよう……ってなりまして。
フォームヘルパーを読んでみたんですけど、checkboxのメソッドを見ると、こんなようなことが書いてありました。
$options = $this->_initInputField($fieldName, $options);
$value = current($this->value());
if (!isset($options['value']) || empty($options['value'])) {
$options['value'] = 1;
} elseif (!empty($value) && $value === $options['value']) {
$options['checked'] = 'checked';
}
まあ何のことやらよう分かりませんが、いろいろやってみたところ、どうやらチェックボックスのvalueとデータのvalueが完全に等しければ、デフォルトでチェックを入れてやるよこんにゃろうってことみたいです。
なので、まずはチェックボックスに適当なvalueを入れておく。
echo $form->checkbox('Model.school.1', array('value' => '1'));
echo $form->checkbox('Model.school.2', array('value' => '2'));
そしたらコントローラーとかで、valueと同じ値をデータに入れる。
$this->data['Model']['school'][1] = 1;
$this->data['Model']['school'][2] = 2;
よし、これでOK……?
と思ったそこのあなた。まだまだだね。
いや、俺もこれでできると最初は思ったんすけど、曲者なのがフォームヘルパーの中身の↓の部分。
$value === $options['value']
イコールが3つってことは型も一緒じゃないとダメよってことになりますが、上記のような書き方だと、チェックボックスの中のvalueはstring型になりますが、その下の、自分でvalueを入れている方はおそらくinteger型になります。なので、これをstring型で入れる必要がある。
$i = 1;
settype($i, 'string');
$this->data['Model']['school'][1] = $i;
settypeっていうのは、型を指定するときに使う関数だそうです。こんなん初めて使いましたわい。
まあ、こんなことしなくても多分
$this->data['Model']['school'][1] = '1';
みたいに書けば、string型になるような気もしますけれど……ってか、なるよね。
……と、こんな長ったらしい説明をしてはみましたが、これを書いたあとにいろいろとソースをいじってたら、何もしなくても$this->dataにデータを入れるだけで勝手に必要なところだけチェックがつくようになりました。何でだろ?
HABTMはよく分からないですね。たぶん、ツンデレとかいうやつなんだと思います。
まとめ
ちょこっと調べた限りでは、MySQLはデータを持って来るときに暗黙の型変換とかいうのがそこはかとなく行われているみたいで、int型のデータもstring型になっていたりするらしいのですが、その辺りはまだ調査不足なので、またいずれ。
ふと思ったんですけど、俺、解決したら書きますとかもうちょっと調べて何か分かったらいずれ追記しますとか言って、今まで実行したことないですよね……たぶん。
LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。