質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.83%

一つのページに独立した2つのフォームに、それぞれにバリデーションをつけたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,336

toto654

score 39

分からないこと

一つのページに2つフォームがそれぞれあり(<form></form> <form></form>),互いに独立してます。
片方のフォームを送信した際に、片方のフォームのバリデーションが機能しないようにしたいです。
また、フォームを送信時、片方のフォームの値だけを取得したい時にどのような方法が良いのか知りたいです。

<body>
<form>

...

</form>

<form>

...

</form>

</body>

知りたいこと

①2つのフォームがあった時に、postをした際に片方だけのフォームを送ることが可能なのか。その方法を知りたいです。
②2つのフォームがあった時に、postをした際に片方だけにバリデーションを行うことが可能なのか。その方法を知りたいです。

2つのフォームを用意するのではなく、1つのふぉーむにまとめる方がいいのか。等どのような方法が良いのか知りたいです。

ご教授のほどよろしくお願いします。

追記

<div class="check">
//一つ目のformです。
        <form action="{{ route('routeMyTeamMember') }}" method="post">
            @csrf
            <div class="item-2">
                <select name="leader" class="select">
                    <option class="option" value="0">選択しない</option>
                    @foreach($users as $user)
                    @if(!isset($user->leader))
                    <option value="{{ $user->id }}">{{ $user->user_name }}</option>
                    @endif
                    @endforeach
                </select>
            </div>
            <div class="item-5">
                <input type="submit" value="交代" class="btn">
            </div>
        </form>
    </div>

    <div class="member">
        <div class="item-1">
            <span class="name">メンバー</span>
        </div>
        @foreach($users as $user)
        @if(!isset($user->leader))
        <div class="item-2">
            <span class="select">{{ $user->user_name }}</span>
            <div class="delete">
                <span class="btn btn2" onclick="event.preventDefault();
                document.getElementById('leave{{ $user->id }}').submit();">脱退させる</span>
            </div>
            <form id="leave{{ $user->id }}" action="{{ route('routeMyTeamMember') }}" method="POST" style="display: none;">
                @csrf
                <input type="hidden" name="leave" value="{{ $user->id }}">
            </form>
        </div>
        @endif
        @endforeach
        <div class="member-btn-box">
            <span class="member-btn">メンバー招待</span>
        </div>
    </div>

    @if($errors->has("add_member"))
    <div class="error-pc">
        <small class="small">{{$errors->first("add_member")}}</small>
    </div>
    @endif
    <div class="plus">
        <div class="item-1">
            @if($errors->has("add_member"))
            <div class="error-mob">
                <small class="small">{{$errors->first("add_member")}}</small>
            </div>
            @endif
        </div>
//二つ目のフォームです。
        <form action="{{ route('routeMyTeamMember') }}" method="post">
            @csrf
            <div class="item-2">
                <input type="text" class="select" name="add_member">
            </div>
            <div class="item-5">
                <input type="submit" value="招待" class="btn">
            </div>
        </form>
    </div>
class MyTeamMemberRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'leader' => ['required', 'integer'],
            'add_member' => ["required", 'string', 'exists:users,user_name'],
        ];
    }
}

現在はコントローラーで
public function memberchange(MyTeamMemberRequest $request){}
と$requestを受け取る時にフォームリクエストが1つしか指定出来ないと思っているので、リクエストには2つのフォームのバリデーションをまとめて書いています。

問題点

片方のフォームを送信する際に両方とものバリデーションが行われてしまう。

これを独立した2つのフォームとして機能させたいです。

進捗状況

こちらの記事を参考にフォームが複数(ボタンが複数)あった際の分岐処理の方法を参考にしました。

また、ボタンに値を付けて判断するのはこちらの記事を参照させて頂きました。

public function change(Request $request)
    {
//一つ目のフォームのボタンの値があったら
        if (isset($request->btn_leader)) {
            $this->leader($request);
//二つ目のフォームのボタンの値があったら
        } elseif (isset($request->btn_member)) {
            $this->member($request->add_member);
        }
    }

一つ目のフォームの処理
public function leader(MyTeamMemberLeaderRequest $request)
    {
        //リーダー交代
        $leader_id = $request->leader;
        $leader = User::find($leader_id);
        $leader->leader = 0;
        $leader->save();
        $user = Auth::user();
        $user->leader = null;
        $user->save();

        return redirect('/myteam');
    }

一つ目のフォームのボタンの値があった際に$this->leader();を呼び出す際に

public function leader(Request $request)
    {
        //リーダー交代
        $leader_id = $request->leader;
        $leader = User::find($leader_id);
        $leader->leader = 0;
        $leader->save();
        $user = Auth::user();
        $user->leader = null;
        $user->save();

        return redirect('/myteam');
    }


このように引数にフォームリクエストを使用しないとエラーが出ませんが

public function leader(MyTeamMemberLeaderRequest $request)
    {
        //リーダー交代
        $leader_id = $request->leader;
        $leader = User::find($leader_id);
        $leader->leader = 0;
        $leader->save();
        $user = Auth::user();
        $user->leader = null;
        $user->save();

        return redirect('/myteam');
    }

このようにフォームリクエストを使用するとイメージ説明

このようなエラーが発生してしまいます。フォームリクエストを使用した際にもしっかりメソッドを使用出来るようにしたいです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

2つのフォームを用意するのではなく、1つのふぉーむにまとめる方がいいのか

要件次第。
そもそも「送信できるフォーム」は1つだけなので、2つにしている時点で1リクエストで処理するのは無理な話です。
JavaScriptからAjax叩く形にすれば1リクエストにまとめられなくはないですけど、それってそもそもフォームわける意味がないんじゃない?という気もするので。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/19 15:36

    質問欄にコードを書いてしまいすみません。再度 質問のランの中に進捗状況を追加させて頂きました。

    キャンセル

  • 2019/05/20 12:41 編集

    aro10さんの回答に確認事項書いていますが、その内容次第で手法が変わったりより良い手法を選択することになるのでしたら、今、急いで私の回答で解決済みにするのはaro10さんにも失礼かと思います。
    ベストアンサーは解除できますので、ご一考ください。

    キャンセル

  • 2019/05/20 12:46

    ありがとうございます。一度取消しさせて頂きました。最終結論が出たら改めて考えたいと思います。

    キャンセル

+2

複数のフォームのバリデーションを行う場合には、名前付きエラーバッグでどのフォームのエラーデータであるかを判別可能です。
Laravel5.8 名前付きエラーバッグ

フォームリクエストを使用している場合は、動的なバリデーション処理として、
条件に応じてrulesメソッドの戻り値を調整するか、withValidatorメソッドで追加のバリデーション処理を行うなどの方法がありますが、
一番シンプルな解決方法は、機能の違うform毎に受けるルート定義を分けることです。

<form action="{{ route('routeMyTeamMember1') }}" method="post">
<form action="{{ route('routeMyTeamMember2') }}" method="post">

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/20 10:59

    回答ありがとうございます。
    機能の違うform毎に受けるルート定義を分けることです。
    →ルーティングの際に1つのGETに対して2つのPOSTを設けてルート定義すると解釈してしまってますが、その場合片方のpostのルートがエラーを吐いてしまいます。
    Route [routeMyTeamLeader] not defined. (View:

    1つのpostでルート定義が出来るのでしょうか?それとも私のやり方が間違ってますか?tt

    キャンセル

  • 2019/05/21 00:32

    routeMyTeamLeaderのルート定義がないというエラーなので、
    不要となったrouteMyTeamLeaderのルートを呼び出している箇所が残ってないか確認してみてください。

    キャンセル

  • 2019/05/22 23:01

    解決しました; ありがとうございました!

    キャンセル

0

自己解決方法

フォームリクエストを使用するとどうしてもエラーが発生してしまうのでコントローラー内にバリデーションを書くことで解決しました。しかし、フォームリクエストを使用する場合の解決方法は分かりませんでした。

フォームが2つある際の条件分岐は https://teratail.com/questions/138594 こちらの記事のまんま

フォーム2つある際のフォームの見分け方は https://teratail.com/questions/138594 こちらの記事を

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.83%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る