端くれプログラマの備忘録 CakePHP [CakePHP] セレクトボックスの選択肢をグループ化する

[CakePHP] セレクトボックスの選択肢をグループ化する

実装覚え書き。

例題

楽曲と歌手のテーブルがあるとして、楽曲ごとに歌手を選ばせたい。楽曲のページに歌手のセレクトボックスを配置したとして、歌手の数が多いと目的の歌手を見つけるのが面倒だ。そこで、歌手を「英字」「あ行」「か行」といったようにグループ化してリストしたい。

歌手データの前提

  • 歌手テーブルには「id」「名前」「ふりがな」のカラムがある
  • 外国人歌手は名前カラムに英語表記の名前が入っていて、ふりがなは空
    (例: 1/Michael Jackson/空)
  • 日本人歌手は名前カラムに日本語表記の名前が入っている
    (例: 2/松田聖子/まつだせいこ)

実装

Formヘルパーのセレクト要素のオプションに入れ子にした配列を渡すことで、セレクトボックスの選択肢がグループ化される。良く出来てるね、Formヘルパー。

コントローラ

$chars = array(
    '英字' => '^[a-zA-Z]',
    'あ行' => '^あ|^い|^う|^え|^お|^ア|^イ|^ウ|^エ|^オ',
    'か行' => '^か|^き|^く|^け|^こ|^カ|^キ|^ク|^ケ|^コ',
    'さ行' => '^さ|^し|^す|^せ|^そ|^サ|^シ|^ス|^セ|^ソ',
    'た行' => '^た|^ち|^つ|^て|^と|^タ|^チ|^ツ|^テ|^ト',
    'な行' => '^な|^に|^ぬ|^ね|^の|^ナ|^ニ|^ヌ|^ネ|^ノ',
    'は行' => '^は|^ひ|^ふ|^へ|^ほ|^ハ|^ヒ|^フ|^ヘ|^ホ',
    'ま行' => '^ま|^み|^む|^め|^も|^マ|^ミ|^ム|^メ|^モ',
    'や行' => '^や|^ゆ|^よ|^ヤ|^ユ|^ヨ',
    'ら行' => '^ら|^り|^る|^れ|^ろ|^ラ|^リ|^ル|^レ|^ロ',
    'わ行' => '^わ|^ワ',
);
foreach ($chars as $key => $value) {
    if ($key == '英字') {
        $singers[$key] = $this->Song->Singer->find('list', array(
            'fields' => array(
                'Singer.name',
            ),
            'conditions' => array(
                'Singer.name REGEXP' => $value,
            ),
            'order' => array(
                'Singer.name' => 'ASC'
            ),
        ));
    } else {
        $singers[$key] = $this->Song->Singer->find('list', array(
            'fields' => array(
                'Singer.name',
            ),
            'conditions' => array(
                'Singer.kana REGEXP' => $value,
            ),
            'order' => array(
                'Singer.kana' => 'ASC'
            ),
        ));
    }
}
$this->set(compact('song','singers'));

ビュー

echo $this->Form->input('singer', array(
    'type' => 'select',
    'options' => $singers,
    'empty' => true, //歌手不明ならば空白を許す
));