Save multiple Items many-to-many Laravel 6 - laravel

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">
//...

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

How To submit form by one submit button in foreach loop in laravel?

This is my create page. Here there is form in foreach loop having on submit button. (This is my create page. Here there is form in foreach loop having on submit button.)
<form method="post" action="{{route('types.store')}}">
#csrf
<table>
#foreach ($students as $student)
<tr>
<td>Name : </td>
<td><input type="text" class="form-control" name="name" value="{{ $student->name }}" readonly></td>
</tr>
<tr>
<td>Type : </td>
<td>
<select name="type" id="type">
<option value="present">present</option>
<option value="absent">absent</option>
<option value="half_day">half day</option>
</select>
</td>
</tr>
<tr>
<td>Date : </td>
<td><input type="date" class="form-control" name="date"></td>
</tr>
#endforeach
<button class="btn btn-primary" name="submit" id="submit">Submit</button>
</table>
</form>
This is my TypeController. This is my TypeController. I want to store data in foreach loop. (This is my TypeController. This is my TypeController. I want to store data in foreach loop)
public function create()
{
$students = Student::all();
return view('types.create', compact('students'));
}
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'type' => 'required',
'date' => 'required',
]);
$type = Type::create([
'name' => $request->input('name'),
'type' => $request->input('type'),
'date' => $request->input('date'),
]);
return redirect()->route('types.index')->withSuccess('Done');
}
This is my Type model which has relation with Student table (This is my Type model which has relation with Student table)
use HasFactory;
protected $table = 'types';
protected $fillable = [
'name',
'date',
];
public function student()
{
return $this->belongsTo(Student::class);
}
Make array for each input like given below:
<form method="post" action="{{route('types.store')}}">
#csrf
<table>
#foreach ($students as $student)
<tr>
<td>Name : </td>
<td><input type="text" class="form-control" name="name[]" value="{{ $student->name }}" readonly></td>
</tr>
<tr>
<td>Type : </td>
<td>
<select name="type[]" id="type">
<option value="present">present</option>
<option value="absent">absent</option>
<option value="half_day">half day</option>
</select>
</td>
</tr>
<tr>
<td>Date : </td>
<td><input type="date" class="form-control" name="date[]"></td>
</tr>
#endforeach
<button class="btn btn-primary" name="submit" id="submit">Submit</button>
</table>
</form>

How to get Selected checkbox into database

I have a page for purchase order in that page i show data from table obat and i want to get selected checkbox using that data into table purchase order
This is my table obat
<table class="table table-bordered" style="margin-top:20px">
<tbody>
<tr class="text-center">
<th>No</th>
<td>Kode Obat</td>
<td>Nama Obat</td>
<td>Harga</td>
</tr>
#foreach ($obat as $key =>$o)
<tr>
<th class="text-center">
#foreach ($po as $po)
<input type="checkbox" name="select" id="select">
#endforeach
</th>
<td>
<input type="text" class="form-control" value="{{ $o->kode_obat }}">
</td>
<td>
<input type="text" class="form-control" value="{{ $o->nama_obat }}">
</td>
<td>
<input type="text" class="form-control" value="{{ $o->harga_obat }}">
</td>
</tr>
#endforeach
</tbody>
</table>
The checkbox(select) is from table purchase order but it can't show. if i did't use foreach its show
you can pass array also to check if it is in the array or not then you can this like below.
in your controller
public function edit($id)
{
$odat=Odat::all();
foreach($odat as $od)
{
$listod[]=$odat->select;
}
return view('yourbladefile',compact('roles','listod'));
}
then in your view
<input type="checkbox" name="select" #if (in_array(yourpurchaseordernamefromdb, $listod))
{{'checked'}} #endif>Selected</td>
personally i managed liked this. hope it helps

laravel 5 : how to validate multi dimensional checkbox

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'
])

Resources