CodeLab技術ブログ

プログラミング技術まとめ

CakePHP3+Bootstrap3でチェックボックスとかラジオボタンを横並びでいい感じで表示する

CakePHP3+Bootstrap3でフォーム部品を表示させようとするのだけど、チェックボックスとかが縦並びになったりイマイチ感が半端ない。
とりあえず、手っ取り早く横並びでいい感じに表示させようと試みてみました。

スポンサードリンク

ソースコード

というわけでこんな感じにしてみました

<?php

$myTemplates = [
    //複数チェックボックスの設定(スタイルを追加)
    'checkboxWrapper' => '<div class="checkbox-inline" style="margin-left: 0px;margin-right: 20px;">{{label}}</div>',
    //ラジオボタンの設定(スタイルを追加)
    'radioWrapper' => '<div class="radio-inline" style="padding-left: 0px;margin-right: 10px;margin-left: 0px;">{{label}}</div>',
    //クラスとスタイルシートを設定できるようにした
    'inputContainer' => '<div class="input {{type}}{{required}} {{inputContainerClass}}" style="{{inputContainerStyle}}">{{content}}</div>',
];
$this->Form->setTemplates($myTemplates);
?>

ラジオボタン
<?=
$this->Form->control('radio',['type'=>'radio','options'=>$pres,'label'=>false,'class'=>'form-group']);
?>

チェックボックスを個別で出して横並びにする場合
<?php
$templateVars = [
    'inputContainerClass'=>'inline',
    'inputContainerStyle'=>'padding-right:10px;',
];
echo $this->Form->control('pres.1',['type'=>'checkbox','value'=>1,'label'=>"北海道",'class'=>'form-group','templateVars'=>$templateVars]);
echo $this->Form->control('pres.2',['type'=>'checkbox','value'=>2,'label'=>"青森",'class'=>'form-group','templateVars'=>$templateVars]);
echo $this->Form->control('pres.3',['type'=>'checkbox','value'=>3,'label'=>"秋田",'class'=>'form-group','templateVars'=>$templateVars]);
?>

チェックボックスの配列で出す場合
<?=
$this->Form->control('multiple_checkbox',['type'=>'select','multiple'=>'checkbox','options'=>$pres,'label'=>false,'class'=>'form-group']);
?>

解説

ラジオボタンに関しては、ラジオボタンのすぐ外枠のDIVに.radio-inlineを追加しました。
具体的にはradioWrapperのテンプレートでclassにradio-inlineを追加しています。
ただ、そのままだと表示がずれてしまうので、styleで少し調整しています。デザインが決まったらCSSファイルに持っていくとよいかと思います。

チェックボックスに関しては、個別で出す場合と、一括で出す場合の2パターン用意しました。

まず、個別で出す場合ですが、inputContainerのテンプレートがネックで、こいつのせいで横並びにできません。
Form::setTemplates()で設定変更してもいいのですが、共通のものなので元に戻さないと以降のフォームのデザインが崩れてしまいます。
こいつはどんな場合でも強制的に出てきてクラス指定などができず、しかも他のフォームパラメータと共通なのでいじれません。
実はForm::controlの$option[‘templates’]でテンプレートを渡せるので、一時的に変更して、戻ったら元にもでしてくれるのか!?と思いきや、残念ながらそういう仕様ではないようでした。

まぁ、外枠でくくってからCSSで内部のスタイルをいじっていけば何とかなりますが、そうするとかなり大がかりになってしまいます。
今回はbootstrapのCSSをなるべく流用すべく、inputContainerにクラスとstyleを追記できるように修正しました。
Form::controlの$option[‘templateVars’]でテンプレートに値を渡せるのでinputContainerのclassにinlineを追加して、微調整ようにstyleも渡せるようにしました。
これで、他のフォーム部品に影響なくinputContainerを変更できます。

次にチェックボックスの配列で出す場合ですが、ラジオボタンと同じようにcheckboxWrapperのClassにcheckbox-inlineを追加しました。
注意点としてはForm::controlの$option[‘type’]=’select’、$option[‘multiple’]=’checkbox’にしないとダメです。
checkboxなのにtypeがselect・・・。意味不明ですがそういう仕様です。

さて、チェックボックスのデータの保存ですが、これが悩ましい。
hasManyで個別にレコードを作って管理する場合と、配列をシリアル化なりJSONでテキストにして保存する場合の2パターンあるかと思います。

hasManyスタイルの場合は前者の個別で出すパターンが良いでしょう。
コードとしては・・・

スポンサードリンク
echo $this->Form->hidden('pres.1.id);
echo $this->Form->control('pres.1.checked',['type'=>'checkbox','value'=>1,'label'=>"北海道",'class'=>'form-group','templateVars'=>$templateVars]);

みたいな感じにすれば、コントローラーで一括で保存できる形になるかと思います。
チェックされた場合、pres.1.checkedにvalueの値が、されてない場合は0が入るはずです。

シリアル化して保存すする場合は後者の配列で出すパターンのほうがいいかなと思います。シリアル化、非シリアル化は別途自分でコードを書く必要はありますが。

なお、inline関連のパラメータは変更になったようで、radio-inlineやcheckbox-inlineはBootstrap4では廃止されたらしいですので、ご注意ください。

参考

https://book.cakephp.org/3.0/ja/views/helpers/form.html

https://api.cakephp.org/3.8/class-Cake.View.Helper.FormHelper.html#%24_defaultConfig

スポンサードリンク
スポンサードリンク

コメントは受け付けていません。