Cakephp PHP WEB開発

【Cakephp4】フォームエラー時でもBootstrapテーマを有効にする方法

※本サイトはPR表記を含みます。

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 内で解決したいなー

-Cakephp, PHP, WEB開発
-