Laravel validation rules: checking against input array index - laravel

In my form the user can add (or remove) licence items which
are generated as input nested arrays:
<div>
<select name="licences[0][type]">
<option value="">- Select -</option>
<option value="car">Car</option>
<option value="motorbike">Motorbike</option>
</select>
<input type="text" name="licences[0][car_spec]" value="">
<input type="text" name="licences[0][motorbike_spec]" value="">
</div>
<div>
<select name="licences[1][type]">
<option value="">- Select -</option>
<option value="car">Car</option>
<option value="motorbike">Motorbike</option>
</select>
<input type="text" name="licences[1][car_spec]" value="">
<input type="text" name="licences[1][motorbike_spec]" value="">
</div>
...
and here are my rules:
$rules = [
'licences.*.type' => 'required',
'licences.*.car_spec' => 'required_if:licences.*.type|car',
'licences.*.motorbike_spec' => 'required_if:licences.*.type|motorbike',
];
Now how can I ensure that the validations match the same index (*) of the licences array ?
For instance, the licences[1][car_spec] input is checked against the licences[1][type] input and not against the licences[0][type].

try like this one:
public function validation(){
$rules = [
'licences.*.type' => 'required',
'licences.*.car_spec' => 'required_if:licences.*.type|car',
'licences.*.motorbike_spec' => 'required_if:licences.*.type|motorbike',
];
foreach($this->request->get('licences') as $key => $value){
$rules['licences.'.$key.'.type'] = 'required';
$rules['licences.'.$key.'.car_spec'] = 'required_if:licences.*.type|car';
$rules['licences.'.$key.'.motorbike_spec'] = 'required_if:licences.*.type|motorbike';
}
return $rules;
}
I hope this works for you.

Related

How to get the old value in a select without unchecked with option formed with an foreach

I need a little help..
In case of validation errors, when the page is reloaded I lose the information entered previously.
This is my code:
Controller:
public function create()
{
$nationalities = array('Italian','Brazilian','Spanish','Romanian');
return view('guest.create', ['nationalities'=>$nationalities);
}
public function store(Request $request)
{
$request->validate([
'nationality' => 'required'
]);
Guest::create([
'nationality' => $request->nationality
]);
return redirect(route('guest.index'));
}
View:
<div class="mb-3">
<label for="nationality" class="form-label fw-bold">Select<span class="required">*</span></label>
<select class="form-select" id="nationality" name="nationality" aria-label="Floating label select example">
#foreach($nationalities as $nationality)
<option value="{{$nationality}}">{{$nationality}}</option>
#endforeach
</select>
</div>
How can I modify the code so that this doesn't happen?
How can you select back what failed if you did not even ask for the old value?
This may or not work depending on how you are validating, but you did not want to show that...
<div class="mb-3">
<label for="nationality" class="form-label fw-bold">Select<span class="required">*</span></label>
<select class="form-select" id="nationality" name="nationality" aria-label="Floating label select example">
#foreach($nationalities as $nationality)
<option value="{{$nationality}}" {{ old('nationality') === $nationality) ? 'selected="selected"' : '' }}>{{$nationality}}</option>
#endforeach
</select>
</div>
<option value="{{$nationality}}" #selected(old('nationality')==$nationality)>
{{$nationality}}
</option>
add the #selected directive in blade.

How can I pre-fill form data entered by a user in Laravel 7

I'm making a registration form where users will be redirected to a preview page to confirm their details first before submitting the form. I'm using Laravel 7 and I'm quite new to Laravel. Once the user enters their details in registration form, the same details will be pre-filled in the preview form before submission. I have tried some code in my controller but it's giving me an error Trying to get property 'myForm' of non-object In my Controller, $data is an array, I'm not sure how I can achieve this. Please help.
In my Conroller:
public function confirmation(Request $request)
{
$categories = Category::all();
$request->validate([
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'telephone_number' => 'required|digits:10',
'email' => 'required|string|email|max:255|unique:users','regex:/^[\w\-\.\+]+\#[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,6}$/',
'password' => 'required|string|min:6|confirmed',
'password_confirmation' => 'required',
'region' => 'required|string',
'description' => 'required|string|max:2500',
'start_date' => 'required|date',
'client_region' => 'string|max:500',
'client_category' => 'integer|max:255',
]);
$data['myForm'] = $request->all();
return view('auth.client.preview', compact('categories', 'data'));
}
In my blade view:
<div class="form-group">
<label for="first_name">First Name</label><span class="text-danger">*</span>
<input type="text" class="form-control{{ $errors->has('first_name')?'is-invalid':'' }}"
name="first_name" value="{{$data->myForm['first_name']}}"
placeholder="Enter First Name" autofocus tabindex="1" required>
<div class="invalid-feedback">
{{ $errors->first('first_name') }}
</div>
</div>
My Route:
Route::post('/preview-details', 'Auth\Client\PreviewRegisterDetailsController#confirmation')->name('preview-details');
Dropdown List:
<label for="fundi_type">Fundi Type</label><span class="text-danger">*</span>
<select class="custom-select" id="category_id" name="category_id">
#foreach($categories as $category )
<option value="{{ $category->id }}">{{ $category->name }}</option>
#endforeach
</select>
Simplify like this below .So no need to create extra array key .
$myForm = $request->all();
return view('auth.client.preview', compact('categories', 'myForm'));
and in view
<input type="text" class="form-control{{ $errors->has('first_name')?'is-invalid':'' }}"
name="first_name" value="{{$myForm['first_name']}}"
placeholder="Enter First Name" autofocus tabindex="1" required>
Updated
<option value="{{ $category->id }}" {{($myForm['category_id']==$category->id)?'selected':null}}>{{ $category->name }}</option>
Edit your blade file code.
Actually your controller is sending array and you are accessing that array as a collection.
From :
<input type="text" class="form-control{{ $errors->has('first_name')?'is-invalid':'' }}"
name="first_name" value="{{$data->myForm['first_name']}}"
placeholder="Enter First Name" autofocus tabindex="1" required>
To
<input type="text" class="form-control{{ $errors->has('first_name')?'is-invalid':'' }}"
name="first_name" value="{{$data['myForm']['first_name']}}"
placeholder="Enter First Name" autofocus tabindex="1" required>
Hope this will be useful.

How to insert multiple data with one form submission [ LARAVEL - Eloquent ]

I have form where I am planning to insert data into units table .. it has fields course_id | unit_number | unit_title
relationship defined : course has many units .. units belongs to course.
the form is working fine, in case I'm inserting only one unit. but when I insert multiple rows it only stores the last row.
#include('admin.messages')
<form action="{{ route('adminSendCreateUnits')}}" method="post" enctype="multipart/form-data">
{{csrf_field()}}
<div class="row col-12">
<div class="col-sm">
<div class="form-group">
<label style="width:100%; background-color:grey; color:white; padding:15px;" for="course_id">Course</label>
<select name="course_id" class="form-control">
<option>Select Course</option><!--selected by default-->
#foreach ($courses as $course)
<option value="{{$course->id}}">
{{ $course->id}}-{{ $course->crs_title}}
</option>
#endforeach
</select>
</div>
</div>
</div><br>
<label for="unit_number">Unit Number</label>
<select name="unit_number[]" class="form-control">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="10">10</option>
</select>
<label for="unit_title">Unit Title</label>
<input type="text" class="form-control" name="unit_title[]" id="unit_title" placeholder="Unit Title" required>
my unitscontroller.php [ I'm sure this is wrong .. since I was trying stuff and i lack the knowledge]
public function adminSendCreateUnit(Request $request){
$course_id = $request->input('course_id');
$unit_number = $request->input('unit_number', []);
$unit_title = $request->input('unit_title', []);
$newCategoryArray = array(
"course_id"=>$course_id,
"unit_number"=>$unit_number,
'created_at' => \Carbon::now(),
"unit_title"=> $unit_title);
$created = DB::table("units")->insert($newCategoryArray);
if($created){
return redirect()->route("adminAllUnits")->withSuccess('Unit Created successfully!');
}else{
return "Unit was not Created";
}
}
I would like to have the course ID same in all rows .. only Unit number and titles change. would appreciate any input :)
Solved by trying this out.
public function adminSendCreateUnit(Request $request){
$course_id = $request->input('course_id');
$unit_number = $request->input('unit_number', []);
$unit_title = $request->input('unit_title', []);
$units = [];
foreach ($unit_number as $index => $unit) {$units[] = [
"course_id" => $course_id, // change this
"unit_number" => $unit_number[$index],
'created_at' => \Carbon::now(),
"unit_title" => $unit_title[$index]
];
}
$created = Unit::insert($units);
if($created){
return redirect()->route("adminAllUnits")->withSuccess('Unit Created successfully!');
}else{
return "Unit was not Created";
}
}

Laravel validation with create form: retrieve old input data for dropdown box

I have a Laravel application which uses a form to create items. The form uses validation as defined in the Laravel documentation under this section.
I have a StoreItem Request file:
public function rules() {
return [
'item_name'=>'required',
'category_id'=> 'required',
'collection_id'=> 'required',
'brewery_id'=> 'required',
];
}
and in the controller I have the following:
public function store(storeItem $request)
{
$validated = $request->validated();
$item = new Item([
'user_id' => Auth::id(),
'item_name' => $request->item_name,
'category_id' => $request->category_id,
'collection_id' => $request->collection_id,
'brewery_id' => $request->brewery_id,
]);
$item->save();
When validation is catching an error, the create form is presented again but I don't see the old input data.
For the input text fields, I have done the following:
<input type="text" class="form-control" name="item_name" value="{{ old('item_name') }}" />
and this shows the old input data, but what to do for the dropdown boxes like category_id, collection_id and brewery_id. I want them to have the old value as the 'selected' value.
Currently in the form I have (for the dropdown boxes):
<div class="form-group">
<label class="form-label" for="brewery">Brewery: (*)</label>
<select class="form-control" name="brewery_id" >
#foreach($breweries as $brewery)
<option value="{{ $brewery->id }}">{{ $brewery->brewery_name }}</option>
#endforeach
</select>
</div>
This source seems to indicate that using the old() method might even not be needed, but if I don't use the
You need to manually add the selected attribute to the previously selected value. For example:
<div class="form-group">
<label class="form-label" for="brewery">Brewery: (*)</label>
<select class="form-control" name="brewery_id" >
#foreach($breweries as $brewery)
<option value="{{ $brewery->id }}" {{ old("brewery_id") == $brewery->id ? "selected" : "" }}>{{ $brewery->brewery_name }}</option>
#endforeach
</select>
</div>
try this as well. I've added bracket open and close to (old('brewery_id')==$brewery->id)
<div class="form-group">
<label class="form-label" for="brewery">Brewery: (*)</label>
<select class="form-control" name="brewery_id" >
#foreach($breweries as $brewery)
<option value="{{ $brewery->id }}" {{ (old('brewery_id') == $brewery->id)? "selected" : "" }}>{{ $brewery->brewery_name }}</option>
#endforeach
</select>
</div>

CakePHP 3 - How to validate multiple select field (belongsToMany Association)

How to validate in CakePHP 3 multiple select field (belongsToMany Association)? All I need is validation rule.
Multiple select field:
<!--select multiple-->
<div class="form-group ">
<label class="control-label">Group:<em>*</em></label>
<select name="newsletter_groups[_ids][]" class="form-control" multiple>
<option></option>
<option value="1" selected>Group 1</option>
<option value="2" >Group 2</option>
<option value="3" selected>Group 3</option>
<option value="4" selected>Group 4</option>
</select>
<label class="error"></label>
</div>
Add in NewsletterTable.ctp
$validator
->add('groups', 'custom', [
'rule' => function($value, $context) {
return (!empty($value['_ids']) && is_array($value['_ids']));
},
'message' => 'Please choose at least one Group'
]);

Resources