Bootstrapテーマを採用したフォーム作成後、ビューの各フォームインプットパーツに class=form-control
など Bootstrapスタイルクラスを指定していれば、フォームエラーの場合でも問題なくBootstrapのテーマが有効になります。
ですが、フォームの数や画面がたくさんある場合、つどクラス名を指定しなければいけないので非常に非効率です。
わざわざBootstrapクラスを指定せずとも、汎用的にフォームヘルパーのテンプレートをカスタマイズすることで便利に利用できます。Cakephp公式にあるように config/app_form.php
に フォームヘルパーの出力テンプレートの定義をして、それを利用する方法が考えられるでしょう。
ここで問題になってくるのが今回の本題です。
フォームリクエスト時に、バリデーションか何かで引っかかった場合、エラー時にインプットフィールドのクラス名が上書きされてしまいます。※デフォルトだとclass="form-error"
となり、Boostrapクラスの form-control が上書きされる。
対処としては、Cakephp4 の FormHelper の defaultConfigメンバ変数 を、AppView内でヘルパーロード時に form-control クラスを追記することで、Bootstrapのテーマを引き続き指定することが可能です。
上記リンクは Cakephp4の本体コード です。デフォルトの状態だと、'errorClass' => 'form-error' なので、フォームリクエストにエラーがあった場合、さきほども書きましたが、インプットフィールドのクラス名が form-error のみになってしまい、bootstrapテーマが有効にならないです。
Cakephp4: フォームエラーの際にもBootstrapスタイルクラスを指定する方法
・src/View/AppView.php
// initialize内に定義 $this->loadHelper('Form', [ 'errorClass' => 'form-control form-error', // form-cotnrol を追記した 'templates' => 'app_form', ]);
・config/app_form.php
<?php return [ 'inputContainer' => '<div class="form-group {{type}}{{required}}">{{content}}</div>', 'input' => '<input type="{{type}}" name="{{name}}"{{attrs}} class="form-control"/>', 'label' => false, 'select' => '<select name="{{name}}"{{attrs}} class="form-control">{{content}}</select>', 'textarea' => '<textarea name="{{name}}"{{attrs}} class="form-control">{{value}}</textarea>', 'submitContainer' => '{{content}}', 'inputContainerError' => '<div class="input {{type}}{{required}} error form-group has-error">{{content}}{{error}}</div>', 'error' => '<span class="help-block text-danger" id="{{id}}">{{content}}</span>', ];
上記コードで注目する箇所は、inputContainerError キーのテンプレートです。エラーのインプットフィールドの div コンテナーにform-group と has-error を付与し、Bootstrapテーマを有効にしています。
app_form
のテンプレートカスタマイズについては、Bootstrapのバージョンにもよる(クラス名を合わせる必要がある)し、出力されたいタブなども各アプリケーションによって変わると思います。そのあたりは任意で変更していただければと思います。
ちなみにフォームヘルパー出力されるテンプレートを自由にカスタマイズする関連記事はこちらです。
追記: Formのエラー時にBootstrapクラス属性を適用させたくない場合
逆にerrorClass
プロパティに form-control
を付与することによって、全てのフォームパーツのエラー時に class=form-control
として付与されます。デメリットとしてはBootstrapテーマを適用させたくない場合もフォームパーツの中に存在するかもしれません。
$this->Form->control()
のオプションにて個別に errorClass
プロパティを設定できそうかな?と思って調べてみると、そんなプロパティはないんですね。なので、結果としては今のところ JQuery
を利用して、クラス属性を問答無用に打ち消す方法が一つ考えられます。(調べ漏れは全然可能性あるのでご了承を)
// 任意のFormパーツにID属性などを付与しておくこと <script> $('#Hoge').removeClass('form-control'); </script>
うーん、でもやっぱし Cakephp 内で解決したいなー