Reputation: 123
I've got multiple forms with validation on one page, so once of it had been submitted it displays validation errors on every form. I want to prevent that, so if form 1 was submitted, I want to display validation messages only for form 1, without form 2.
So that's what I'm currently come up:
Controller
public function composeMail(Request $request)
{
$validator = Validator::make($request->all(),
[
'subject' => 'max:40|regex:/^[A-Za-z]+$/u',
'body' => 'required|min:1|max:1000|regex:/^[A-Za-z0-9]+$/u'
],
[
'subject.max' => 'Subject can be maximum 40 symbols length.',
'subject.regex' => 'In subject Only numbers and latin letters is allowed.',
'body.required' => 'Message cannot be empty.',
'body.min' => 'Message shall contain at least one character.',
'body.max' => 'Message can be only 10000 symbols length.',
'body.regex' => 'In message only numbers and latin letters is allowed.',
])->validateWithBag('email');
return redirect()->back()->withErrors($validator);
Views
@if ($errors->any())
<div class="alert">
<ul>
@foreach ($validator->email as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
Currently it just returns to the page and nothing happens, validation doesn't work and doesn't prints out anything... Can you tell me what's wrong with it?
Upvotes: 0
Views: 6830
Reputation: 10220
The behaviour you're seeing is expected. $errors->any()
inspects the default
message bag and does not take named error bags into consideration.
Illuminate\Support\ViewErrorBag.php
/**
* Determine if the default message bag has any messages.
*
* @return bool
*/
public function any()
{
return $this->count() > 0;
}
/**
* Get the number of messages in the default bag.
*
* @return int
*/
public function count()
{
return $this->getBag('default')->count();
}
So to show errors for your specific forms with named bags, you need to access them as such:
@if ($errors->namedBag->any())
<ul>
@foreach($errors->namedBag->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif
If you don't want to place all the validation error messages together but perhaps want to put error messages specific to a field underneath the field, you can provide the get()
method on the named error bag with the name of the field to get just the errors you want:
@if ($errors->namedBag->get('name'))
<ul>
@foreach($errors->namedBag->get('name') as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif
Upvotes: 0
Reputation: 3420
You are using ->validateWithBag('email');
to get automatic redirection see Automatic redirection,
but you are still passing return redirect()->back()->withErrors($validator, 'email');
.
Also you should redirect when it fails,
if ($validator->fails()) {
return redirect()
->back()
->withErrors($validator, 'email');
}
Also If you want automatic redirection you can directly use
$validatedData = $request->validateWithBag('email', [
'subject' => 'max:40|regex:/^[A-Za-z]+$/u',
'body' => 'required|min:1|max:1000|regex:/^[A-Za-z0-9]+$/u'
],
[
'subject.max' => 'Subject can be maximum 40 symbols length.',
'subject.regex' => 'In subject Only numbers and latin letters is allowed.',
'body.required' => 'Message cannot be empty.',
'body.min' => 'Message shall contain at least one character.',
'body.max' => 'Message can be only 10000 symbols length.',
'body.regex' => 'In message only numbers and latin letters is allowed.',
]);
Upvotes: 1
Reputation: 12845
Guess you need to send the name of the error bag too
public function composeMail(Request $request)
{
$validator = Validator::make($request->all(),
[
'subject' => 'max:40|regex:/^[A-Za-z]+$/u',
'body' => 'required|min:1|max:1000|regex:/^[A-Za-z0-9]+$/u'
],
[
'subject.max' => 'Subject can be maximum 40 symbols length.',
'subject.regex' => 'In subject Only numbers and latin letters is allowed.',
'body.required' => 'Message cannot be empty.',
'body.min' => 'Message shall contain at least one character.',
'body.max' => 'Message can be only 10000 symbols length.',
'body.regex' => 'In message only numbers and latin letters is allowed.',
])->validateWithBag('email');
return redirect()->back()->withErrors($validator, 'email');
}
And in blade view the errors from named bag need to be accessed as
@if ($errors->any())
<div class="alert">
<ul>
@foreach ($errors->email as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
Upvotes: 0