久々に早めの帰宅ができたので、ちょっくら走ってきました。やっぱり体動かすって気持ちいいね!
すっきり気分なので、久々にブログ書く。
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>
へ渡されることになります。