前回の例はメールアドレス1つの入力でしたが、今度はちょっと複雑にして複数のメールアドレスを入力する配列入力の話です。
入力画面
画面はこんな感じです。
そして、その画面のブレードはこんなです。前回で定義したx-inputのコンポーネントを使用しています。
< x-layout > < div class = "container" > < div class = "row justify-content-center" > < div class = "col-md-8" > < div class = "card" > < div class = "card-header" >登録</ div > < div class = "card-body" > < x-form action = "{{ route('register') }}" > @for($i=1;$i <=3;$i++) < div class = "row mb-3" > < x-label name = "email{{ $i }}" >メールアドレス {{ $i }}</ x-label > < div class = "col-md-6" > < x-input id = "email{{ $i }}" type = "email" name = "emails[{{ $i }}]" /> </ div > </ div > @endfor < div class = "row mb-0" > < div class = "col-md-6 offset-md-4" > < x-button type = "submit" class = "m-2" level = "primary" >登録</ x-button > </ div > </ div > </ x-form > </ div > </ div > </ div > </ div > </ div > </ x-layout > |
前回と違って、name="emails[1]"
のように配列の文字列となっていることに注意を。
なにかがおかしい!
上の画面で以下のようにEメールでない値を入れて「登録」ボタンを押すと、
もちろん、画面ではエラーが表示されることを期待しますが、何もでてきません。しかも、入力した値は空になってしまいます。まさに、最初の空の入力画面と同じ状態です。
ちなみに、バリデーションのルールは以下です。
'emails' => [ 'required' , 'array' ], 'emails.*' => [ 'string' , 'email' , 'max:255' ], |
何がおかしいのでしょう?
ここで、前回のx-inputのコンポーネントをここで再度掲載します。
@props([ 'type' => 'text' , 'name' , 'value' => null, ]) <input type= "{{ $type }}" name= "{{ $name }}" value= "{{ old($name, $value) }}" @error( $name ) {{ $attributes -> class ( 'form-control is-invalid' ) }} @ else {{ $attributes -> class ( 'form-control' ) }} @enderror /> @error( $name ) <span class = "invalid-feedback" role= "alert" > <strong>{{ $message }}</strong> </span> @enderror |
調査すると、問題はコンポーネントにおける、old($name, $value)
と@error($name)
に渡している$nameの値です。
配列なので、この$nameには、emails[1]、emails[2]、emails[3]の文字列が入ってきます。
しかし、old()はこれらの文字列を理解しません。@errorに関しては、debugbarでセッションを見ると、以下のように、emails[1]ではなく、emails.1という文字列になっています。
対応
ということは、old()や@error()に渡す指標が配列の文字列なら、ドットの文字列に変換すればよいですね。
以下は、改良したコンポーネントです。
@props([ 'type' => 'text' , 'name' , 'value' => null, ]) @php $index = str_replace ([ '.' , '[]' , '[' , ']' ], [ '_' , '' , '.' , '' ], $name ); // 'emails[1]'が'emails.1'となる @endphp <input type= "{{ $type }}" name= "{{ $name }}" value= "{{ old($index, $value) }}" @error( $index ) {{ $attributes -> class ( 'form-control is-invalid' ) }} @ else {{ $attributes -> class ( 'form-control' ) }} @enderror /> @error( $index ) <span class = "invalid-feedback" role= "alert" > <strong>{{ $message }}</strong> </span> @enderror |
これで再度「登録」ボタンを押すと、期待通りにエラーが表示されます。
メルマガ購読の申し込みはこちらから。