0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【画像あり】「どちらか一方は入力必須」のvalidationをCakePHP3.8で行う

Last updated at Posted at 2020-07-24
1 / 23

今回のお題


CakePHP3.8を使って実装を進めた際に起きました。
調べてみても意外にヒットしなかったので、自分なりの対処方法を残しておきます。


環境

PHP: 5.6.40
CakePHP: 3.8
OS: CentOS7.2
DB: MySQL5.7.21

今さらPHP5.6かよ、というのは置いておき。。


画面イメージ


よくあるこのような画面です。

image.png

今回は身長か体重のどちらかは入力必須(両方入力されていてもOK)というお話です。


CakePHP3実装


model


Usersモデルに以下のカラムがある、という前提で進めます。
身長: height
体重: weight

src/Model/Table/UsersTable.php
    public function validationDefault(Validator $validator)
    {
        $validator
            ->notEmptyString('height', '身長か体重のいずれかを入力してください。', function ($context) {
                return (bool) (!$context['data']['height']) && (!$context['data']['weight']);
            });

        return $validator;
    }

カスタムバリデーションで function($value, $context) を使いますが
$valueは当該の項目、$contextはリクエスト全体をそれぞれ定義します。
今回は$contextを使ってどちらの項目もチェックする、ということをしています。


view


src/Template/Users/edit.ctp
    <dt class="title">身長/体重<br>いずれか必須<span class="must">必須</span></dt>
    <dd class="input">
        <?= $this->Form->control('height', [
            'type' => 'text',
            'label' => false,
            'required' => false,
        ]) ?> cm
        <?= $this->Form->control('weight', [
            'type' => 'text',
            'label' => false,
            'required' => false,
        ]) ?> kg
    </dd>

こちらでは特に変わったことはしていませんね。


結果イメージ


image.png

身長のエラーとして表示されることがわかります。


おまけ


さらに身長・体重にそれぞれバリデーションをかける場合も一緒に記載します。

前提条件
・身長・体重のどちらかは入力必須。
・どちらも半角数字での入力しか認めない。


modelにルールを追加


src/Model/Table/UsersTable.php
    public function validationDefault(Validator $validator)
    {
        $validator
            ->notEmptyString('height', '身長か体重のいずれかを入力してください。', function ($context) {
                return (bool) (!$context['data']['height']) && (!$context['data']['weight']);
            })
            ->numeric('height', '身長は半角数字で入力してください。');

        $validator
            ->allowEmptyString('weight', null)
            ->numeric('weight', '体重は半角数字で入力してください。');

        return $validator;
    }

heightにnumericのvalidationルールを
weightにはallowEmptyStringとnumericのルールを追加しました。


実行


先ほどのviewをそのまま使うと以下のようになってしまいます。

image.png

validationメッセージが表示されると、全体的にレイアウトが崩れてしまいました。
まあ、これはviewの書き方が悪い、とも言えますが。。。


対応策


viewを以下のように変更します。

src/Template/Users/edit.ctp
    <dt class="title">身長/体重<br>いずれか必須<span class="must">必須</span></dt>
    <dd class="input">
        <?= $this->Form->control('height', [
            'type' => 'text',
            'label' => false,
            'required' => false,
            'error' => false,
        ]) ?> cm
        <?= $this->Form->control('weight', [
            'type' => 'text',
            'label' => false,
            'required' => false,
            'error' => false,
        ]) ?> kg
        <?= $this->Form->error('height') ?>
        <?= $this->Form->error('weight') ?>
    </dd>

フォームではエラー表示をオフにし、別のところでエラーを出すようにしました。


結果


image.png

崩れていたレイアウトもスッキリしましたね。

まだ需要があるかはわかりませんが、どなたかのお役に立てたのなら嬉しいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?