Firstly I can say that after search I dont find any solution about this. I do validation array like this post: laravel validation array
I need validate each size array position. I write this validation code:
// Fields validation
$request->validate([
'name' => 'required|max:150',
'theySay' => 'nullable|array',
'theySay.*' => 'string|max:1000',
'theyDontSay' => 'nullable|array',
'theyDontSay.*' => 'string|max:1000',
]
Where theySay and theyDontSay are both array of strings. In migration I have both fields (text) like strings of 1000 characters.
$table->string('text', 1000);
And validation works correctly. I mean, if put a text greater than 1000 chars I cannot save but..dont show any error message.
I want the error message to be shown in the input just like the rest of the fields.
What am I doing wrong?
Best regards
'YOUR_FIELD' => '...|...|max:1000| ...'
Look at the Laravel validation docs for more information
Please put below code in your blade file for show any error message.
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Quoting laravel documentation:
Likewise, you may use the * character when specifying your validation messages in your language files, making it a breeze to use a single validation message for array based fields:
'custom' => ['person.*.email' => ['unique' => 'Each person must have a unique e-mail address']]
It seems it does not work. I have a validation message:
'infos.*.*.*' => ['required' => 'My text']
Then I have some inputs in my view:
<input type="text" name="infos[1234][0][name]">
<input type="text" name="infos[1234][1][name]">
<input type="text" name="infos[5678][0][name]">
And in my controller I validate the input:
$this->validate($request, [
'infos.*.*.*' => 'required'
]);
And in view I have a error displayer:
#if (count($errors) > 0)
<strong>Oops. Errors:</strong>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
#endif
And if I leave all input empty I got:
My text
My text
My text
My text
My text
etc.
What's wrong with my code? Reading Laravel documentation I though it should have worked (I mean: it should have been displayed only once). Did I misunderstood something?
This is working as intended. Since you're passing multiple inputs in an array, the validation throws an error for each item. Therefore 3 inputs with 2 causing errors and 1 passing would obviously pass error for 2 inputs. So in your case the multiple errors are due to multiple inputs failing validation.
Taken from lrvl 5.1 documentation, I read:
using these lines in the controller:
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'author.name' => 'required',
'author.description' => 'required',
]);
If validation doesn't pass controller stops execution and redirect back to previous location.
This is happening correctly.
Then doc says:
"$errors variable will always be available in all of your views on every request"
And then suggests the following blade code:
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
But actually I'll get a ErrorException undefined variable errors....
What am I missing?
Thanks
I'll answer myself to this question,
just in case It was not clear the commented solution.
(Thanks to train_fox for the hint).
Just add 'web' middleware usage.
in your routing that is target in form action (get/post)
Example:
Route::group(['middleware' => 'web'],
function(){
Route::post('/edit' , 'My_Controller#edit');
});
Variable $errors the becomes available on view to be parsed.
I'm building a roster system as a side project and on one of the pages you can change the regular hours someone works.
On the page I have a checkbox for each day of the week, you can then go through and select the appropriate days that the person works.
They need to work at least one day and so at least one of the checkboxes needs to be checked when submitted.
To test this I am using the required_without_all rule of Laravel's validator.
It works perfectly, however if no boxes are checked it will redirect you back and spit out the same error message 7 times (as there are 7 checkboxes for each day of the week).
I am using custom error messages so this is why the error message is the same, but even if I didn't I wouldn't want a similar error message being repeated over and over.
This is what my validator looks like:
$validator = Validator::make($request->all(), [
'mondayCheckbox' => 'required_without_all:tuesdayCheckbox,wednesdayCheckbox,thursdayCheckbox,fridayCheckbox,saturdayCheckbox,sundayCheckbox',
'tuesdayCheckbox' => 'required_without_all:mondayCheckbox,wednesdayCheckbox,thursdayCheckbox,fridayCheckbox,saturdayCheckbox,sundayCheckbox',
'wednesdayCheckbox' => 'required_without_all:mondayCheckbox,tuesdayCheckbox,thursdayCheckbox,fridayCheckbox,saturdayCheckbox,sundayCheckbox',
'thursdayCheckbox' => 'required_without_all:mondayCheckbox,tuesdayCheckbox,wednesdayCheckbox,fridayCheckbox,saturdayCheckbox,sundayCheckbox',
'fridayCheckbox' => 'required_without_all:mondayCheckbox,tuesdayCheckbox,wednesdayCheckbox,thursdayCheckbox,saturdayCheckbox,sundayCheckbox',
'saturdayCheckbox' => 'required_without_all:mondayCheckbox,tuesdayCheckbox,wednesdayCheckbox,thursdayCheckbox,fridayCheckbox,sundayCheckbox',
'sundayCheckbox' => 'required_without_all:mondayCheckbox,tuesdayCheckbox,wednesdayCheckbox,thursdayCheckbox,fridayCheckbox,saturdayCheckbox',
'effective_from' => 'date',
], [
'mondayCheckbox.required_without_all' => 'Surely they are working at least one day!',
'tuesdayCheckbox.required_without_all' => 'Surely they are working at least one day!',
'wednesdayCheckbox.required_without_all' => 'Surely they are working at least one day!',
'thursdayCheckbox.required_without_all' => 'Surely they are working at least one day!',
'fridayCheckbox.required_without_all' => 'Surely they are working at least one day!',
'saturdayCheckbox.required_without_all' => 'Surely they are working at least one day!',
'sundayCheckbox.required_without_all' => 'Surely they are working at least one day!',
'effective_from.date' => 'You have provided an invalid date for when their hours are effective from!',
]);
if ($validator->fails())
{
return Redirect::back()
->withErrors($validator)
->withInput();
}
So if no boxes are checked on submission, the error Surely they are working at least one day! is shown 7 times.
I am displaying the errors on the page like this:
#if (count($errors) > 0)
<div class="alert alert-danger">
<p><b>There were some problems:</b></p>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Is there anyway to only get it to show once?
There are many ways to go around this. Since JS hacks are on the table too, we can also come in from the Blade end and do this (feel free to use your own favourite array manipulation functions):
<ul>
<li>
{{-- Show error message only once --}}
#if( $errors->has('mondayCheckbox') || $errors->has('tuesdayCheckbox') || $errors->has('wednesdayCheckbox') || $errors->has('thursdayCheckbox') || $errors->has('fridayCheckbox') || $errors->has('saturdayCheckbox') || $errors->has('sundayCheckbox') )
Surely they are working at least one day!
#endif
</li>
#foreach ($errors->all() as $error)
{{-- Show other errors not related to the checkboxes --}}
#unless($error == 'Surely they are working at least one day!')
<li>
{{ $error }}
</li>
#endunless
#endforeach
</ul>
The other way is to deal with the Illuminate\Contracts\Support\MessageBag in your validator with the After Validation Hook and clean things up there.
It is late but might help someone with similar problem.
Just apply the rule for a hypothetical field, say, weekdays like below.
$validator = Validator::make($request->all(), [
'weekdays' => 'required_without_all:mondayCheckbox,tuesdayCheckbox,wednesdayCheckbox,thursdayCheckbox,fridayCheckbox,saturdayCheckbox,sundayCheckbox',
'effective_from' => 'date',
], [
'required_without_all' => 'Surely they are working at least one day!',
'effective_from.date' => 'You have provided an invalid date for when their hours are effective from!',
]);
And put all the fields (mondayCheckbox.... sundayCheckbox) that you want this rule to be applied after required_without_all. And write the validation message for the rule only once.
You can use array_unique($array) function to remove duplicates from error messages.
Here is the code snippet
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach (array_unique($errors->all()) as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
I am submitting an array of inputs to my controller like so:
<input id="box-1-nickname" name="box-nickname[]" class="form-control" type="text" placeholder="Required">
<input id="box-2-nickname" name="box-nickname[]" class="form-control" type="text" placeholder="Required">
I am doing some validation like this:
$validator = Validator::make(Input::all(), array(
'supplies-count' => 'required|in:0,1,2,3,4',
));
$arrayValidator = Validator::make(Input::all(), []);
$arrayValidator->each('box-nickname', ['required|min:1|max:60']);
if( $validator->fails() || $arrayValidator->fails() ) {
return Redirect::route('route-2')
->withErrors($arrayValidator)
->withInput();
}
The problem is when I try to check the errors like this it doesn't work:
if( $errors->has('box-1-nickname') ) { echo ' has-error'; }
Displaying input array errors in the view (L5.8 onwards)
To get the first validation error for an input array:
{{ $errors->first('input_array.*') }}
To check if there is an error within an input array:
#if($errors->has('input_array.*'))
<h1>There is an error in your input array</h1>
<ul>
#foreach($errors->get('input_array.*') as $errors)
#foreach($errors as $error)
<li>{{ $error }}</li>
#endforeach
#endforeach
</ul>
#endif
Other examples:
#error('input_array.*')
<div class="alert alert-danger">{{ $message }}</div>
#enderror
From 5.8^ documentation
Working with error messages
If you are validating an array form field, you may retrieve all of the messages for each of the array elements using the * character:
foreach ($errors->get('attachments.*') as $message) {
//
}
Hope it helps!
You've probably long found a solution, but for anyone else who stumbles across this:
The validator uses array dot notation of the field array keys. For example box-nickname[0] becomes box-nickname.0
Therefore if( $messages->has('box-nickname.0') ) { echo ' has-error'; } should give you your desired result. However, you will need to dynamically generate the array key since as you've said, you won't know how many box-nicknames are being applied. I use this in my form view:
#if(!is_null(Input::old('box-nickname')))
#foreach(Input::old('box-nickname') as $n => $box-nickname)
#include('box-nickname-create-form-partial')
#endforeach
#endif
Then create a partial view called "box-nickname-create-form-partial.blade.php" or whatever you want to call it with the form field, which might look something like this:
<div class="form-group {!! $errors->has('box-nickname.'.$n) ? ' has-error' : '' !!}">
<input name="box-nickname[{{$n}}]" class="form-control" type="text" placeholder="Required">
</div>
I hope that's helpful.
The errors are collected by name property, not id, and Laravel's default MessageBag variable is $messages, not $errors:
if( $messages->has('box-nickname') ) { echo ' has-error'; }
http://laravel.com/docs/4.2/validation#working-with-error-messages
$errors is correct, but you should be checking for box-nickname. As you can see you will run into the issue of not being able to identify what box is what because of the generic name. I think the easiest way to to give each input a unique name (eg. box-1, box-2)and do a for loop on the server side to retrieve inputs that start with box-.