Laravel 5: Check for Specific Error - laravel-5

I have Password and Confirm Password inputs. I have coded these inputs so that in the event of an error the inputs highlight, like so:
<div class="form-group {{ $errors->has('password') ? 'has-error' : '' }}>
<label>Password</label>
<input type="password" name="password" class="form-control">
</div>
<div class="form-group {{ $errors->has('password_confirmation') ? 'has-error' : '' }}>
<label>Password</label>
<input type="password" name="password_confirmation" class="form-control">
</div>
In my Controller, I validate these inputs as follows:
$this->validate($request, [
....
'password' => 'required|min:8|confirmed',
'password_confirmation' => 'required',
....
]);
When either input is null and/or less than 8 characters, the inputs highlight as expected. However, when the inputs don't match, I would logically expect the Confirm Password input to highlight. However, it is the Password field that highlights, because that is the input that the "confirmed" rule is set to.
The "$errors->has()" method simply checks if an error exists for an input. Is there a way to check if an input has a specific kind of error?

Yes, you can get the array of errors for a given input name by using:
{{ $errors->get('password') }}
So you can check if the password errors array has the confirmation error and then add the additional class to your confirmation input field:
#if (in_array(trans('validation.confirmed', ['attribute' => 'password']), $errors->get('password'))) has-error #endif
And the helper methods may vary between Laravel versions:
Laravel < 5.4: trans('validation.confirmed', ['attribute' => 'password'])
Laravel 5.4: __('validation.confirmed', ['attribute' => 'password'])

Related

Save array [ ] of form data in same columns individual row - Laravel

when the user click add more and submit their form data, I'm having a problem saving form array like this (service[], Amount[], Description[]) in database rows. I have two related tables of invoices and invoice_details, i want the form array to submit the list of form data into the invoice_details table. I have successfully created the models and relations between the invoice and invoice_details.
<!--Blade -->
<div class="service-box">
<div class="row">
<div class="col-md-12 service-group">
<div class="row">
<div class="form-group mb-3 col-md-6">
<label class="form-label">Service</label>
<div >
<select type="text" class="form-select" placeholder="Services" value="" name="service[]" id="service">
<option value="" disabled selected>Select your option</option>
#foreach ($services as $service)
<option value="{{$service->service_name}}" data-id="{{$service->amount}}">{{$service->service_name}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group mb-3 col-md-6">
<label class="form-label">Amount</label>
<div >
<input type="text" class="form-control" name="amount[]" id="amount" placeholder="Amount" readonly>
</div>
</div>
<div class="form-group mb-3 col-md-12">
<label class="form-label">Description</label>
<textarea class="form-control" id="description" name="description[]" rows="6" placeholder="Description.." ></textarea>
</div>
</div>
</div>
</div>
</div>
//Controller
$invoicedetailModel = new Invoice_detail;
//Here is where the problem lies, I have to save for arrays.
$invoicedetailModel->service = request('service');
$invoicedetailModel->amount = request('amount');
$invoicedetailModel->description = request('description');
$invoiceModel->Invoice_details()->save($invoicedetailModel);
It seems to me (correct me if I'm misinterpreting) that you're trying to save a batch of different InvoiceDetails and attach them to an original Invoice model.
The problem here is that you're trying to do so by passing arrays to a single invoiceDetails model so let's suppose you have the you have two detail instances passed by form you would have the request parameters structured like this:
$request->service: ['serviceX','serviceY']
$request->amount: [1,2]
$request->description: ['Lorem', 'Ipsum']
So if you tried to create the model you're trying to save in your code you would be doing something like this:
Invoice_Details::create([
'service' => ['serviceX', 'serviceY'],
'amount' => [1,2]
'description' => ['Lorem', 'Ipsum']
]);
Which can not work because those values are not set as Json to the database, and also explains why the createMany is not working, because there's a single object that uses an array of values for each value. What you might want is a situation like this:
Invoice_Details::createMany([
[
'service' => 'serviceX',
'amount' => 1
'description' => 'Lorem'
],
[
'service' => 'serviceY',
'amount' => 2
'description' => 'Ipsum'
]
]);
So you should iterate the request parameters and save a whole array of single models rather than try to stuff everything into a single one.
Also, it's pretty legitimate to ask yourself "Sure, but they all have two parameters, why doesn't it just split them when I use the createMany method?" Well, let's suppose the same situation with different parameters:
$request->service: ['serviceX','serviceY']
$request->amount: [1,2]
$request->description: ['Ipsum']
To which model does that description belong to? We could just go by appearence order, but this kind of assumption might lead to huge problems in case of bad implementations. This sadly means that everytime we need to create multiple models we need to define every single one, even though it means adding an iteration beforehand.
TL;DR: Instead of an array of parameters you need an array of models. Iterate through your parameters and build your models before saving them.
//Supposing you already fetched the arrays and they are all of the same length
$details = [];
foreach($services as $key => $service) {
$invoicedetailModel = new Invoice_detail();
$invoicedetailModel->service = $services[$key];
$invoicedetailModel->amount = $amounts[$key];
$invoicedetailModel->description = $descriptions[$key]);
$details[] = $invoicedetailModel;
}
// code to create and attach the many models

How can I receive a specific index of an validator array of array validation in Laravel?

I validate an array in laravel controller and receive message by using $errors->first('field_name') or $errors or $errors->has('field_name). Now the problem is, I validate an array named vaccine_certificate and I can not receive the error message. Actually I receive the message when show all erros at once. but I want to show it with it's input area. How can I solve it?
$this->validate($request, [
'name' => 'required',
'employee_no' => 'required',
'vaccine_certificate.*' => 'image|mimes:png,jpg|max:2048|dimensions:max_height=200,max_width=200',
//'expertise' => 'required',
]);
Input field looks like
<div class="col-6 form-group">
<label class="control-label " for="vaccine_certificate"><h5 class="h6">Vaccine Certificate <small>(<2mb,png,jpg) </small> </h5></label>
<input class="form-control" type="file" name="vaccine_certificate[]" id="vaccine_certificate" multiple/>
#if ($errors->has('vaccine_certificate'))
<p id="employee_no_checker_message" class="text-danger p-2" onload="changeInputBorderColor('vaccine_certificate')"> {{ $errors->first('vaccine_certificate') }}</p>
#endif
</div>
You can use and see all errors in the error bag of form.
$errors->all()
However, as far as I can see there is no "required" in vaccine_certificate, and your rule is vaccine_certificate.*, that means it should be an array. If you make it vaccine_certificate and required like you did in the name field you can see the error message.
If you need to use array, you can use:
$errors->first('vaccine_certificate.*')
Since it is not "required" it will not throw an error and you can not see it in the $errors variable.

Validation on checkbox where one one checkbox must be checked in laravel

I have the following Checkboxes now a want put validation in checkbox that one checkbox must be checked . But i dont't know how to do that.
CheckBox
<div class="form-group clearfix">
<label for="" class="col-sm-2 col-form-label">Arch (es) </label>
<div class="col-sm-10">
<label class="control-label" for="inputError" style="color: red"><i
id="arch_upper_error"></i></label>
<div class="demo-checkbox">
<input id="md_checkbox_1" name="arch_upper" value="41" class="chk-col-black"
type="checkbox">
<label for="md_checkbox_1">Upper</label>
<input id="md_checkbox_2" name="arch_lower" value="41" class="chk-col-black"
type="checkbox">
<label for="md_checkbox_2">Lower</label>
</div>
</div>
</div>
I tried this in laravel validation but i know its wrong because it required for both but i want at least one checkbox is checked.
public function rules()
{
return [
'arch_lower' => 'required',
'agarch_upper' => 'required',
,
];
}
I think you could use Laravel's required-without method:
The field under validation must be present and not empty only when any
of the other specified fields are not present.
Implementation would look something like this:
'arch_upper' => 'required_without: arch_lower',
If, by any chance, you have more checkboxes, you could use required-without-all:
The field under validation must be present and not empty only when all
of the other specified fields are not present.
Implementation:
'arch_upper' => 'required_without_all: arch_lower,another_checkbox',
Note: Code is not tested, if you encounter any errors, let me know.
You can read more on Laravel's official documentantion.

Laravel multiple select array validation always give error

I am using multiple select in my form, facing problem with its form validation, i am using multiple select field name as array if i give same name for validation rule its work great, but keep giving validation error on selected options also. here is my html code and validation rule.
<select multiple="multiple" name="skills[]" class="form-control">
validation rule
'skills[]' => 'required'
if i use field name without [] or skills.* validation not working for this field, guide me where i am doing something wrong. I am using laravel 5.7 for my project.
If your select looks like this for example:
<div class="form-group row">
<label for="skills" class="col-md-4 col-form-label text-md-right">Skills</label>
<div class="col-md-6">
<select multiple name="skills[]" id="skills" class="form-control{{ $errors->has('skills') ? ' is-invalid' : '' }}" required>
<option value="ios">iOS</option>
<option value="php">PHP</option>
<option value="laravel">Laravel</option>
</select>
#if($errors->has('skills'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('skills') }}</strong>
</span>
#endif
</div>
</div>
Create a custom request:
$ php artisan make:request ExampleRequest
ExampleRequest validation would look like this:
public function authorize()
{
return true;
}
public function rules()
{
return [
'skills' => 'required|array',
];
}
Then just grab the validated data from your $request directly
public function submitForm(ExampleRequest $request)
{
// at this point, validation already passed
// if validation failed, you would be back at form with errors
$skills = request('skills');
// or
$skills = $request->skills;
dd($skills);
}
Custom requests are being validated first before even hitting your controller method.

Laravel form binding

Hi I am using laravel form binding along with
jqBootstrapValidation . In order to successfuly have the validate the input fields, I must pass something like "required" (without quotes) in the tag . Can you please let me know how can I achieve this ?
FYI .. the minlength works fine but the required does not work.
For example one of input elements currently looks as such
{{Form::text('username', null, array('class'=> 'form-control tip', 'data-toggle'=> 'tooltip', 'data-placement'=> 'bottom', 'title'=>'Enter your username that you have been using till now. This is a compulsory field.','placeholder'=>'Username ( must be filled )','minlength'=>'2'))}}
Thanks
You can't, take a look at the source code that builds the attributes:
protected function attributeElement($key, $value)
{
if (is_numeric($key)) $key = $value;
if ( ! is_null($value)) return $key.'="'.e($value).'"';
}
You'll always get a <attribute>=<name>, what you can test is to use it this way:
{{ Form::text('username',
null,
array( 'class'=> 'form-control tip',
'data-toggle'=> 'tooltip',
'data-placement'=> 'bottom',
'title'=>'Enter your username that you have been using till now. This is a compulsory field.',
'placeholder'=>'Username ( must be filled )',
'minlength'=>'2',
0 => 'required'
)
)
}}
It will build a tag
<... required="required" ...>
And it might work for jqBootstrapValidation.
Otherwise you'll have to create those inputs manually.
I've used this with the HTML attributes required="required" and also required="" works too. Changing the example they provide and adding in the Laravel Blade tags gives
<form class="form-horizontal" novalidate>
<div class="control-group">
<label class="control-label">Type something</label>
<div class="controls">
{{ Form::text('name', null , array('required' => '')) }}
<p class="help-block"></p>
</div>
</div>
{{ Form::submit('submit')}}
</form>
This worked fine and produced the error "This is required". I swapped in your form field and added in the
'required' => ''
to the end of your attribute array and that too worked just fine. Alternatively you could instead add in
'required' => 'required'
as jqBootstrapValidation picks up either. Good luck.

Resources