laravel 5 : how to validate multi dimensional checkbox - laravel

Hello i have the following in my view
<table class="table">
<tbody>
#foreach($products as $indexKey => $product)
<tr>
<td>
<input type="checkbox name="order_products[{{$indexKey}}][id]" value="{{$product->id}}"/>
</td>
<td>
<input type="text" name="order_products[{{$indexKey}}][quantity]" value=""/>
</td>
</tr>
#endforeach
</tbody>
</table>
and in my controller
$this->validate($request,[
'order_products'=>'required'
])
how can I validate that if one checkbox is checked, make sure the 'quantity' is not empty?
i checked so many websites and nothing comes close to my answer, they are all using just one dimensional array.
thank you!

Try this if it works
$this->validate($request,[
'order_products'=>'required|array',
'order_products.id' => 'required',
'order_products.quantity' => 'required'
])

Related

How can I validate textboxes that are dependent on each other and display error messages under dynamically (using JS) added input textboxes?

In my form, I have a "Seminars attended" set of text inputs- User inputs the seminar title, date, and seminar conductor/organizer.
<table class="table" id="addRemoveSeminar">
<thead>
<tr>
<th scope="col">Title</th>
<th scope="col">Date Taken</th>
<th scope="col">Conducted By</th>
<th><button type="button" name="add" onclick="addSeminar()" id="dynamic-ar-seminar" class="btn btn-outline-primary">Add Seminar</button></th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row"><input type="text" id="" name="Seminars[0][title]"></th>
<td><input type="date" id="" name="Seminars[0][date]"></td>
<td><input type="text" id="" name="Seminars[0][conducted_by]"></td>
</tr>
</tbody>
</table>
The
form originally loads with just one set of these text inputs, but if user wants to add more seminars, they can click the
"Add Seminar" button, and a new set of these three input boxes will appear. Here is the js code:
JS file:
function addSeminar() {
var i = 0;
++i;
$("#addRemoveSeminar").append('<tr><th scope="row"><input type="text" id="" name="Seminars[' + i +
'][title]"></th><td><input type="date" id="" name="Seminars[' + i +
'][date]"></td><td><input type="text" id="" name="Seminars[' + i +
'][conducted_by]"></td><td><button type="button" class="btn btn-outline-danger remove-input-field">Delete</button></td></tr>'
);
$(document).on('click', '.remove-input-field', function () {
$(this).parents('tr').remove();
});
}
As you can see, the name attributes of title,date, and conducted_by will be added as keys to the Seminars array.
Question 1:
If validation fails, I don't just want to call a foreach() on all the errors and display them on the top of the page, I want each error to display on the bottom of the textbox it corresponds to.
Even the ones that have been dynamically added through Javascript. How do I do that?
Question 2:
For now, all these inputs are nullable in the validation rule. However, if the user should enter a value on one of the input boxes, I want the other two input boxes to be required.
For example, if a user types in a Seminar title, he can't leave the date and conducted_by input box empty.
I tried reading the Laravel documentation: https://laravel.com/docs/8.x/validation#complex-conditional-validation part, but I'm
struggling to figure out how I can implement the given example
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'games' => 'required|numeric',
]);
with my current scenario, since the current validating syntax I use for all of the input is request()->validate(). How can I do this?
My current validation in controller:
$validated = request()->validate([
'Seminars.*.title' => ['nullable','max:100',new LetterSpaceOnly],
'Seminars.*.date' => ['nullable','before_or_equal: today','date'],
'Seminars.*.conducted_by' => ['nullable','max:100',new LetterSpaceOnly]
]);
Thank you so much in advance
For your second question first, you may use the required_with validation rule.
You may check it here in the documentaion
Now, for the second question, since the fields are added after the DOM has been loaded, it's not going to be present when Laravel validates the inputs.
However, there's a work around here.
In this example we may use the old helper, also you may check it here in the docs
A little context here about old, when you submit your form, all your inputs will going to be flashed into session, and we can retrieve them using the helper above.
So the workaround here, is whenever tha validation fails, it will return back with the 'old' inputs, using that helper, we can re-create the first table, the user submitted, and we can show errors under each one of the input fields.
For the code now:
This is the code of the view, where we check if we have old values in the session or not:
<table class="table" id="addRemoveSeminar">
<thead>
<tr>
<th scope="col">Title</th>
<th scope="col">Date Taken</th>
<th scope="col">Conducted By</th>
<th><button type="button" name="add" onclick="addSeminar()" id="dynamic-ar-seminar" class="btn btn-outline-primary">Add Seminar</button></th>
</tr>
</thead>
<tbody>
#if (old('Seminars'))
#foreach (old('Seminars') as $key => $seminar)
<tr>
<th scope="row">
<input type="text" id="" name="Seminars[{{ $key }}][title]" value="{{ $seminar['title'] }}">
#if ($errors->has('Seminars.' . $key . '.title'))
{{ $errors->first('Seminars.' . $key . '.title') }}
#endif
</th>
<td>
<input type="date" id="" name="Seminars[{{ $key }}][date]" value="{{ $seminar['date'] }}">
#if ($errors->has('Seminars.' . $key . '.date'))
{{ $errors->first('Seminars.' . $key . '.date') }}
#endif
</td>
<td>
<input type="text" id="" name="Seminars[{{ $key }}][conducted_by]" value="{{ $seminar['conducted_by'] }}">
#if ($errors->has('Seminars.' . $key . '.conducted_by'))
{{ $errors->first('Seminars.' . $key . '.conducted_by') }}
#endif
</td>
<td><button type="button" class="btn btn-outline-danger remove-input-field">Delete</button></td>
</tr>
#endforeach
#else
<tr>
<th scope="row">
<input type="text" id="" name="Seminars[0][title]">
</th>
<td>
<input type="date" id="" name="Seminars[0][date]">
</td>
<td>
<input type="text" id="" name="Seminars[0][conducted_by]">
</td>
</tr>
#endif
</tbody>
</table>
and here's the controller validation rules
$this->validate($request, [
'Seminars.*.title' => 'sometimes|required_with:Seminars.*.date, Seminars.*.conducted_by',
'Seminars.*.date' => 'sometimes|required_with:Seminars.*.title, Seminars.*.conducted_by',
'Seminars.*.conducted_by' => 'sometimes|required_with:Seminars.*.title, Seminars.*.date',
]);
...
Also, one more thing, in your JS code, the onclick event, should be outside of the function.
function addSeminar() {
#if (old('Seminars'))
var i = {{ count(old('Seminars')) }} - 1;
#else
i= 0;
#endif
++i;
$("#addRemoveSeminar").append('<tr><th scope="row"><input type="text" id="" name="Seminars[' + i +
'][title]"></th><td><input type="date" id="" name="Seminars[' + i +
'][date]"></td><td><input type="text" id="" name="Seminars[' + i +
'][conducted_by]"></td><td><button type="button" class="btn btn-outline-danger remove-input-field">Delete</button></td></tr>'
);
}
$(document).on('click', '.remove-input-field', function () {
$(this).parents('tr').remove();
});
For changing the validation messages, you may use it as follows:
$this->validate($request, [
'Seminars.*.title' => 'sometimes|required_with:Seminars.*.date, Seminars.*.conducted_by',
'Seminars.*.date' => 'sometimes|required_with:Seminars.*.title, Seminars.*.conducted_by',
'Seminars.*.conducted_by' => 'sometimes|required_with:Seminars.*.title, Seminars.*.date',
],
[
'Seminars.*.title.required_with' => 'Custom message here',
'Seminars.*.date.required_with' => 'Custom message here',
'Seminars.*.conducted_by' => 'Custom message here',
]);
And change the messages as your needs.
I hope everything is clear.

How to assign task to multiple users at same time?

I make task management system and i don't know well how to assign task to multiple users at same time?
This is my AssignmentController Store function.
public function store(Request $request)
{
$request->validate(array(
'assignment' => 'array|required',
'assignment.*.assigned_to' => 'required',
'task_title' => 'required',
'task_description' => 'required',
'done_at' => 'sometimes',
));
foreach($request->get('assignment') as $assignment)
$assignment = Assignment::create(array(
'task_title' => $request->input('task_title'),
'task_description' => $request->input('task_description'),
'assigned_to' => $assignment['assigned_to'],
'done_at' => $request->input('done_at'),
));
}
This is my assignment.create page where is 3 field assigned_to, task_title and task_description done_at is optional
<form method="post" action="{{route('assignments.store')}}">
#csrf
<table>
<tr>
<td>Staff Name : </td>
<td>
<select name="assignment[{{$key}}][assigned_to]" id="assigned_to" multiple>
<option value="">Select One</option>
#foreach ($staffs as $staff)
<option value="{{ $staff->id }}">{{ $staff->name }}</option>
#endforeach
</select>
</td>
</tr>
<tr>
<td>Task Title : </td>
<td><input type="text" name="task_title" class="form-control"></td>
</tr>
<tr>
<td>Task Description : </td>
<td><input type="text" name="task_description" class="form-control"></td>
</tr>
<tr>
<td>Done At :</td>
<td><input type="time" name="done_at" class="form-control"></td>
</tr>
<td><button class="btn btn-primary" name="submit" type="submit" value="submit" id="submit">Submit</button></td>
</table>
</form>
You have users table
id
name
and assignments table
id
title
description
And you must have user_assignment table
user_id
assignment_id
This table define many to many relationship between users and assignments
Which means that each user has many tasks and each task belongs to many users
read the documentation :
https://laravel.com/docs/7.x/eloquent-relationships#many-to-many

Save multiple Items many-to-many Laravel 6

I'm trying to save multiple Product into Purchase by using Vuejs for frontend and Laravel for Backend and that is a many-to-many relationship between them.
In My Vuejs
<tr class="tablePurchase--td" v-for="(item, index) in items">
<td>{{item.name}}</td>
<td>{{item.code}}</td>
<td>
<input type="number" class="table-quantity" v-model="items[index].quantity">
</td>
<td>
<input type="number" class="table-quantity" v-model="items[index].unit_price" placeholder="0.00">
</td>
<td>
<input type="number" class="table-quantity" v-model="items[index].discount" placeholder="0.00">
</td>
<td>
<v-btn small color="red" outlined #click="removeItem(index)">
<v-icon>mdi-delete</v-icon>
</v-btn>
</td>
</tr>
In my Controller
public funtion store(Request $request) {
....
foreach($purchase->products as $item) {
$purchase->products()->attach($product_id, [
'unit_price' => $item['unit_price'],
'quantity' => $item['quantity'],
'discount' => $item['discount'],
]);
}
}
But, its got empty array... i even tried dd($request->items) and its return null
I'll appreciate all ur Help? Thanks
You should name all of your inputs as items[]
//...
<input type="number" class="table-quantity" name="items[]" v-model="items[index].unit_price" placeholder="0.00">
//...

data is not submitting into db:laravel-5.8

I'm new to laravel and trying to save data into db but nothing happens. I just want to save it into db.
controller:
public function store(Request $request)
{
$request->validate([
'date' => 'required',
'start_time' => 'required',
'end_time' => 'required',
'time_slot' => 'required',
]);
Form::create(request(['date', 'start_time', 'end_time', 'time_slot']));
$data->save();
return view('form.index');
}
blade file:
<table class="table table-hover mt-5">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Start Time</th>
<th scope="col">End Time</th>
<th scope="col">Time Slice</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<input type="date" name="date">
</th>
<td>
<input type="text" id="datetimepicker" name="start_time" />
</td>
<td>
<input type="text" id="datetimepicker" name="end_time" />
</td>
<td>
<select name="time_slot">
<option value="1">15 min</option>
<option value="2">30 min</option>
<option value="3">45 min</option>
<option value="4">1 hr</option>
</select>
</td>
</tr>
</tbody>
</table>
<button type="submit" type="button" class="btn btn-primary">Add Data</button>
I'm using resource route for it.
you have 2 options to save it in database:
1---------------------------
public function store(Request $request)
{
$request->validate([
'date' => 'required',
'start_time' => 'required',
'end_time' => 'required',
'time_slot' => 'required',
]);
$form = new Form(); //make new object from your model
$form->date = $request['date']; //each of the DB field fill with $request fields
$form->start_time = $request['start_time'];
$form->end_time = $request['end_time'];
$form->time_slot = $request'time_slot'];
$form->save(); //Save this to your DB
return view('form.index');
}
2-------------------------------Recomended
in this way you need to do something in your model
Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Form extends Model
{
protected $table = "forms"; //table name in your DB
protected $fillable = ['date','start_date','end_date','time_slot']; //your fields in DB table that you want to fill them
}
Controller
public function store(Request $request)
{
$request->validate([
'date' => 'required',
'start_time' => 'required',
'end_time' => 'required',
'time_slot' => 'required',
]);
$form = new Form(); //make new object from your model
$form->create($request->all()); //NOTE:your fields in view should be the same name with your fields in DB, i mean for example you should get the start_date from an input that it's name is start_date, <input name="start_date">
return view('form.index');
}
i hope this helps you !
public function store(Request $request)
{
$request->validate([
'date' => 'required',
'start_time' => 'required',
'end_time' => 'required',
'time_slot' => 'required',
]);
Form::create($request->all());
return view('form.index');
}
blade file:
<form method="post" action="{{ route('form.store' }}">
{{ csrf_field() }}
<table class="table table-hover mt-5">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Start Time</th>
<th scope="col">End Time</th>
<th scope="col">Time Slice</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<input type="date" name="date">
</th>
<td>
<input type="text" id="datetimepicker" name="start_time" />
</td>
<td>
<input type="text" id="datetimepicker" name="end_time" />
</td>
<td>
<select name="time_slot">
<option value="1">15 min</option>
<option value="2">30 min</option>
<option value="3">45 min</option>
<option value="4">1 hr</option>
</select>
</td>
</tr>
</tbody>
</table>
<button type="submit" class="btn btn-primary">Add Data</button>
</form>

Laravel: Edit Data on Same Page it's Displayed on

I'd like to make changes to user data on the same page it's been displayed.
Basically, I want to either select verified or rejected, click submit button and the page refreshes with the change.
So i have this code:
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Receipt</th>
<th scope="col">Status</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
#foreach($users as $user)
<tr>
<form method='POST' action="{{ action('PaymentController#update' , $user->id )}}"
enctype="multipart/form-data">
#csrf
#method('PUT')
<th scope="row">{{$user->id}}</th>
<td>{{$user->name}}</td>
<td>
{{$user->receipt}}
</td>
#if( $user->payment_status != NULL )
<td>
PAYMENT VERIFIED
</td>
#else
<td>
<div class="form-group">
<select multiple class="form-control-sm" id="exampleFormControlSelect2" name="nsap_reg"
required="">
<option value="verified">Verified</option>
<option value="NULL">Rejected</option>
</select>
</div>
</td>
#endif
<td>
<input type="submit" value="SUBMIT">
</td>
</form>
</tr>
#endforeach
</tbody>
</table>
Controller:
public function update(Request $request, $id)
{
$request->validate([
'nsap_reg' => 'required',
]);
$payment_status = \App\User::find($id);
['nsap_reg' => $request->nsap_reg];
$payment_status->save();
return redirect('user-status');
}
My problem is nothing happens when I click submit, the page just refreshes.
Any help will be appreciated.
You just need to set the value of nsap_reg to user object and save it.
$payment_status = \App\User::find($id);
$payment_status->nsap_reg = $request->nsap_reg;
$payment_status->save();
As I can see you created select list with multiple select and when you are saving data to database then you sending array data to saving.
But you have to firstly convert that to json and then set to save.
Below is the example to save multi-select nsap_reg.
<?php
public function update(Request $request, $id)
{
$request->validate([
'nsap_reg.*' => 'required',
]);
$payment_status = \App\User::find($id);
$payment_status->nsap_reg = json_encode($request->input('nsap_reg'));
$payment_status->save();
return redirect('user-status');
}
But if you are using single select then remove multiple attribute from the select list and then use this code
<?php
public function update(Request $request, $id)
{
$request->validate([
'nsap_reg' => 'required',
]);
$payment_status = \App\User::find($id);
$payment_status->nsap_reg = $request->input('nsap_reg');
$payment_status->save();
return redirect('user-status');
}

Resources