前回の例はメールアドレス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
これで再度「登録」ボタンを押すと、期待通りにエラーが表示されます。
メルマガ購読の申し込みはこちらから。



