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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Q&A

解決済

3回答

8718閲覧

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

toto654

総合スコア39

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

0グッド

0クリップ

投稿2019/05/18 09:21

編集2019/05/19 06:33

分からないこと

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

html

1<body> 2<form> 3 4... 5 6</form> 7 8<form> 9 10... 11 12</form> 13 14</body>

知りたいこと

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

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

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

追記

laravel

1 2<div class="check"> 3//一つ目のformです。 4 <form action="{{ route('routeMyTeamMember') }}" method="post"> 5 @csrf 6 <div class="item-2"> 7 <select name="leader" class="select"> 8 <option class="option" value="0">選択しない</option> 9 @foreach($users as $user) 10 @if(!isset($user->leader)) 11 <option value="{{ $user->id }}">{{ $user->user_name }}</option> 12 @endif 13 @endforeach 14 </select> 15 </div> 16 <div class="item-5"> 17 <input type="submit" value="交代" class="btn"> 18 </div> 19 </form> 20 </div> 21 22 <div class="member"> 23 <div class="item-1"> 24 <span class="name">メンバー</span> 25 </div> 26 @foreach($users as $user) 27 @if(!isset($user->leader)) 28 <div class="item-2"> 29 <span class="select">{{ $user->user_name }}</span> 30 <div class="delete"> 31 <span class="btn btn2" onclick="event.preventDefault(); 32 document.getElementById('leave{{ $user->id }}').submit();">脱退させる</span> 33 </div> 34 <form id="leave{{ $user->id }}" action="{{ route('routeMyTeamMember') }}" method="POST" style="display: none;"> 35 @csrf 36 <input type="hidden" name="leave" value="{{ $user->id }}"> 37 </form> 38 </div> 39 @endif 40 @endforeach 41 <div class="member-btn-box"> 42 <span class="member-btn">メンバー招待</span> 43 </div> 44 </div> 45 46 @if($errors->has("add_member")) 47 <div class="error-pc"> 48 <small class="small">※{{$errors->first("add_member")}}</small> 49 </div> 50 @endif 51 <div class="plus"> 52 <div class="item-1"> 53 @if($errors->has("add_member")) 54 <div class="error-mob"> 55 <small class="small">※{{$errors->first("add_member")}}</small> 56 </div> 57 @endif 58 </div> 59//二つ目のフォームです。 60 <form action="{{ route('routeMyTeamMember') }}" method="post"> 61 @csrf 62 <div class="item-2"> 63 <input type="text" class="select" name="add_member"> 64 </div> 65 <div class="item-5"> 66 <input type="submit" value="招待" class="btn"> 67 </div> 68 </form> 69 </div>

request

1class MyTeamMemberRequest extends FormRequest 2{ 3 /** 4 * Determine if the user is authorized to make this request. 5 * 6 * @return bool 7 */ 8 public function authorize() 9 { 10 return true; 11 } 12 13 /** 14 * Get the validation rules that apply to the request. 15 * 16 * @return array 17 */ 18 public function rules() 19 { 20 return [ 21 'leader' => ['required', 'integer'], 22 'add_member' => ["required", 'string', 'exists:users,user_name'], 23 ]; 24 } 25}

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

問題点

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

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

進捗状況

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

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

controller

1public function change(Request $request) 2 { 3//一つ目のフォームのボタンの値があったら 4 if (isset($request->btn_leader)) { 5 $this->leader($request); 6//二つ目のフォームのボタンの値があったら 7 } elseif (isset($request->btn_member)) { 8 $this->member($request->add_member); 9 } 10 } 11 12一つ目のフォームの処理 13public function leader(MyTeamMemberLeaderRequest $request) 14 { 15 //リーダー交代 16 $leader_id = $request->leader; 17 $leader = User::find($leader_id); 18 $leader->leader = 0; 19 $leader->save(); 20 $user = Auth::user(); 21 $user->leader = null; 22 $user->save(); 23 24 return redirect('/myteam'); 25 }

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

leader

1public function leader(Request $request) 2 { 3 //リーダー交代 4 $leader_id = $request->leader; 5 $leader = User::find($leader_id); 6 $leader->leader = 0; 7 $leader->save(); 8 $user = Auth::user(); 9 $user->leader = null; 10 $user->save(); 11 12 return redirect('/myteam'); 13 }

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

leader

1public function leader(MyTeamMemberLeaderRequest $request) 2 { 3 //リーダー交代 4 $leader_id = $request->leader; 5 $leader = User::find($leader_id); 6 $leader->leader = 0; 7 $leader->save(); 8 $user = Auth::user(); 9 $user->leader = null; 10 $user->save(); 11 12 return redirect('/myteam'); 13 }

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

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

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

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

投稿2019/05/20 00:42

aro10

総合スコア4106

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toto654

2019/05/20 01:59

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

2019/05/20 15:32

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

2019/05/22 14:01

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

0

ベストアンサー

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

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

投稿2019/05/18 09:56

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toto654

2019/05/18 13:21

そもそも「送信できるフォーム」は1つだけなので →つまり、フォームが2つあった際に片方だけにバリデーションを付与、片方だけの値の取得が可能ってことですか?
toto654

2019/05/18 13:39

現在は一つのフォームを送信しようとすると、送信しようとしていない方のフォームのバリデーションも適応されてしまいます。これを解決したいです。その際にバリデーションを2つ用意して public function change(Change1Request $request1 Change2Request $request2) {} のようにするのも違いますか?
m.ts10806

2019/05/18 21:18

現在の状況を再現できるコードをご提示ください。組んだ通りにしか動かない以上はイメージや文章だけでは話は進められませんので。
toto654

2019/05/19 03:05

抽象的な表現ですみません。改めて上記の質問に追記として書かせていただきました。
m.ts10806

2019/05/19 03:43

ざっと見た感じですが「フォーム複数で1つのコントローラーで別の処理をする」ということになるので、同じnameのinput要素をそれぞれのフォームに設置して別のvalueを設定しておき、 valueによって分岐かければ実現は可能かと思います。 それかルーティングの任意パラメーターでactionの末尾に別パラメータ与えて同じコントローラーでうけとってパラメータによって処理分けするか。 ただ、処理要件が別物であればやはりメソッドは分けたほうが良いです。
toto654

2019/05/19 03:56 編集

回答ありがとうございます。メソッドを分ける方法は思いつきませんでした。今から3パターン試してみたいと思います。 メソッドを分けた際に、どちらのメソッドを使用するかの判断はやはり、パラメーターで区別しないと出来ないのでしょうか? ルーティングの際に一つのGETに対して2つのPOSTがあるイメージをしてます
m.ts10806

2019/05/19 03:51

はい。もちろん「分けるためのパラメータを仕込む設定」は何かしらの形で必要です。 ファットコントローラー、ファットメソッドにならない工夫はしてください。
toto654

2019/05/19 03:58

はい! 助言ありがとうございます!
m.ts10806

2019/05/19 06:16

コメント欄だとマークダウン使えずコードも読みづらいので、進捗状況として質問に追記いただけますか?
toto654

2019/05/19 06:36

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

2019/05/20 03:41 編集

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

2019/05/20 03:46

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

0

自己解決方法

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

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

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

投稿2019/05/20 03:43

編集2019/05/20 03:45
toto654

総合スコア39

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問