久々に早めの帰宅ができたので、ちょっくら走ってきました。やっぱり体動かすって気持ちいいね!
すっきり気分なので、久々にブログ書く。
FormHelperでselect boxの中のoptionタグにattributeを指定したいとき
CakePHPのFormHelperでselect boxを出力したいとき
<?php ... $this->Form->input('select_field', [ 'type' => 'select', 'options' => $result ])
こんな感じですよね。このとき、$resultの中身は
<?php ... $result = [ $id => $value, $id2 => $value2, $id3 => $value3, ];
こんな感じのリストが並んでいると思います。これを実行すると
<select name="data[select_field]"> <option value="$id">$value</option> <option value="$id2">$value2</option> <option value="$id3">$value3</option> </select>
とまぁ。こうなりますよね。
さて、今回やりたかったことは、この<option>のタグに属性(attribute)を持たせたいとき、どうするか。
こうしました。
<?php ... /** * @return array|null */ public function getDataForSelectList() { $data = $this->find('all', [ 'order' => ['User.created' => 'ASC'] ]); $result = []; foreach($data as $k => $v) { $pack = [ 'name' => $v['User']['users_name'], // <option>ここの値</option> 'value' => $v['User']['id'], // <option value="ここの値"></option> 'data-email' => $v['User']['email'] // <option data-email="ここの値"></option> ]; $result[$k] = $pack; } return $result; }
連想配列で、複数keyをもたせればそれが属性になるらしいです。ただし、nameとvalueは忘れないようにですね。これでうまく動かすことが出来ました。しかしよく出来ているねぇ。
せっかくだからFormHelperのその箇所を読んでみる
- lib/Cake/View/Helper/FormHelper.php:2775
<?php ... protected function _selectOptions($elements = array(), $parents = array(), $showParents = null, $attributes = array()) { $select = array(); $attributes = array_merge( array('escape' => true, 'style' => null, 'value' => null, 'class' => null), $attributes );
このメソッドの中にありました。まずは2809行目
- lib/Cake/View/Helper/FormHelper.php:2809
<?php $htmlOptions = array(); // ここは2786行目 if (is_array($title) && (!isset($title['name']) || !isset($title['value']))) { ... } elseif (is_array($title)) { $htmlOptions = $title; $name = $title['value']; $title = $title['name']; unset($htmlOptions['name'], $htmlOptions['value']); }
見た感じ。nameとvalueがセットされているなら、2809行目から処理されると思います。んで、ここでvalueを$name(<option>でいうvalue属性)へ、nameを$title(<option>タグでいうテキスト)へ値を渡して、unsetしています。
ということは先ほどのコードを実行してここの中を確認すると$htmlOptionsの中には'data-email' => $v['User']['email']の値がまだ残っています。
これが属性の値として渡されるのはここ2873行目
- lib/Cake/View/Helper/FormHelper.php:2869
<?php ... } else { if ($attributes['escape']) { $name = h($name); } $select[] = $this->Html->useTag('selectoption', $name, $htmlOptions, $title); // 2873行目 }
この$this->Html->useTag()は渡される引数$name、$htmlOptions、$titleをそれぞれ配列かどうか確認して、配列であれば属性としてタグに設置して値をかえしてくれます。つまりは先ほどのunset処理から値が残った$htmlOptionsの中身にある'data-email' => $v['User']['email']が、そのまま属性として<option>へ渡されることになります。