in Laravel, is there any way to know which rule was invalid. For example:
'email': 'email|max:20'
And let's assume that I want to know is the email max rule failed
If you want to get error message considering specific field, then mention the name of the Validation object key on messages array. Ref
If validation has failed, you may retrieve the error messages from the validator.
if ($validator->fails())
{
$messages = $validator->messages();
}
echo $messages;
You may also access an array of the failed validation rules, without messages. To do so, use the failed method:
$failed = $validator->failed();
Retrieving All Error Messages For A Field
foreach ($messages->get('email') as $message)
{
//
}
By default all validation errors will be flashed to the session and available through $errors array in the template. Every failed rule will generate a separate error.
Example of displaying the errors using Bootstrap classes, taken from the documentation. Place this somewhere in your Blade template:
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
See more details in the official documentation
In my opinion it is better to use custom validation message for email max. I assume you are doing like this
$data = 'data_to_validate';
$rule = array('email': 'email|max:20') ;
$validator = Validator::make($data,$rule);
Add custom validation for email max like this
$message = array('email.max' => 'Exceeded max. email length');
new validator
$validator = Validator::make($data,$rule,$message);
Now if $validator->fails() for email max then $validator->messages() will show your custom validation. This way you can know your max rule failed.
Related
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
Consider the manual authentication. If the order ID has not been found in database, we redirect user to page with input fields and with error 'wrongOrderId':
public function login(Request $request) {
$inputted_orderId = $request->input('order_id');
$orderIdInDB = DB::table(self::SITE_IN_DEVELOPMENT_TABLE_NAME)
->where(self::ORDER_ID_FIELD_NAME, $inputted_orderId)->first();
if (is_null($orderIdInDB)) {
return Redirect::route('loginToSitesInDevelopmentZonePage')->withErrors('wrongOrderId');
}
}
In this example, we don't need to pass the error message: the message box is already exists in View; all we need is to display this message box when user has been redirected with error 'wrongOrderId':
#if (!empty($errors->first('wrongOrderId')))
<div class="signInForm-errorMessagebox" id="invalidID-errorMessage">
<!-- ... -->
</div>
#endif
All above code is working without laravel/php errors; I get into is_null($orderIdInDB) if-block when input wrong order number, however the error message box don't appears. I tried a lot of ways, and (!empty($errors->first('wrongOrderId'))) is just last one. What I doing wrong?
Did you try printing {{$errors->first()}}?
first(string), works as a key value pair, it invokes its first key VALUE
try this,
#if($errors->any())
<div class="signInForm-errorMessagebox" id="invalidID-errorMessage">
<!-- ... -->
</div>
#endif
If you want to get specific error from validator error, use the get() method.
$errors->get('wrongOrderId'); get all the wrongOrderId errors.
$errors->first('wrongOrderId'); get first error of wrongOrderId errors
I explored that $errors->first('wrongOrderId') has non-displayable but non-null value. So #if ( $errors->first('wrongOrderId') !== null ) will work.
Something more elegantly like #if ($errors->first('wrongOrderId'))? Unfortunately just one this check is not enough: even if we define
return Redirect::route('loginToSitesInDevelopmentZonePage')->withErrors(['wrongOrderId' => true]);
php will convert true to 1. So, #if ( $errors->first('wrongOrderId') == true ) will working, but #if ($errors->first('wrongOrderId')) will not.
However, we can to cast $errors->first('wrongOrderId') to bool, so the most elegant solution will be
#if ((bool) $errors->first('wrongOrderId'))
I have laravel application! I use original laravel authentication from
php artisan make:auth
My question is how to check if name already exist in database and if exist to return error message!
My user table structure is:-
user:
id - UNIQUE
name
email
password
remembertoken
timestamps
Laravel form validation
Following is quoted from there:
Use the "unique" rule for name.
$request->validate([
'name' => 'required|unique:users'
]);
And display error like this:
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div> #endif
You actually have two solutions:
Make sure you have an unique constraint on your database for name
See the code below
$user = User::where("name", $nameToTestAgainst)->first();
if($user!= null) {
$v->errors()->add('Duplicate', 'Duplicate user found!');
return redirect('to-your-view')
->withErrors($v)
->withInput();
}
You can use auth()->user()->name in blade file.
<?php $name=auth()->user()->name; ?>
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.
Is there any utility function in Laravel that allows you to give an alternative value for a specific input field if the old value is empty? Currently I have the following code:
<input type="text" class="form-control" id="title" name="title" value="{{ (!empty(Input::old('title'))) ? Input::old('title') : 'hey' }}">
But its not really that pretty. Any ideas?
use
Input::old('title', 'fallback value')
Yes! Don't use the input tag :)
If you use {{ Form you will get this, and much, much more!
{{ Form::text('email', null, array('class'=>'form-control', 'placeholder'=>'Email Address')) }}
Check out the docs here (http://laravel.com/docs/html & http://laravel.com/docs/requests) and you will notice that when the input is flashed to the session, this input box rendered by blade will automatically replace that "null" (the second parameter) with the flashed value from the session.
This removes the need to check for the old input or have any nasty if/else checks inside your template. Also, you no longer need to worry about any HTML code injections or XSS happening, because Form::text will ensure that the text is correctly converted to their HTML entities.
Where you are checking for errors, you should use a Laravel validator. Something similar to this:
protected function createUser(){
$rules = array(
'email'=>'required|email',
'password'=>'required|min:6|confirmed',
'password_confirmation'=>'required'
);
$validator = Validator::make(Input::all(), $rules);
if (! $validator->passes()) {
Input::flashExcept('password', 'password_confirmation');
return Redirect::to('my_form');
} else {
// do stuff with the form, it's all good
}
return Redirect::intended('/complete');
}
Additionally, in your template, you can show all of the errors from the form:
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
Or just select the first error and show it under the {{ Form::text
#if ($errors->has('first_name'))
<span class="error">{{$errors->first('first_name')}}</span>
#endif
Laravel has all of this built in, and you get it for free! Using Requests, Validators, Blade/HTML