Insert Multiple record in database laravel 8 - laravel

I need to insert all the number in my database. I used foreach loop to view students and marks to insert.
When click save all data of class test partA partB will store in database.
I am facing difficulties in controller
`<form action="{{ route('teacher.add_all_student_results',[$session_id,$semester_id,$course_id,$course_credit]) }}" method="POST">
<table class="table table-bordered table-hover table-sm">
<thead>
<tr>
<th>IMG</th>
{{-- <th>Department Name</th> --}}
<th>Reg.No</th>
<th>ID.No</th>
<th>Student Name</th>
<th>Attendance</th>
<th>Class Test</th>
<th>PartA</th>
<th>PartB</th>
{{-- --}}
</tr>
</thead>
<tbody>
#csrf
#php $i=1;
#endphp
#foreach($semester_students as $semester_student)
<tr data-widget="expandable-table" aria-expanded="false">
<td>
<input type="hidden" name="student_id" value={{ $semester_student->id }} placeholder="add marks" class="form-control">
</td>
<td><img class="img-circle img-bordered-sm" src="" alt="U" width="50"></td>
<td>{{$semester_student->registration_number}}</td>
<td>{{$semester_student->roll_number}}</td>
<td>{{$semester_student->firstname}} {{$semester_student->lastname}}</td>
<td>
<input type="text" name="attendance" placeholder="add marks" class="form-control">
</td>
<td>
<input type="text" name="class_test" placeholder="add marks" class="form-control">
</td>
<td>
<input type="text" name="parta" placeholder="add marks" class="form-control">
</td>
<td>
<input type="text" name="partb" placeholder="add marks" class="form-control">
</td>
</tr>
#endforeach
</tbody>
</table>
<button type="submit" class="btn btn-success mt-1"><i class="fa fa-check-circle"
aria-hidden="true"></i>
Save</button>
</form>`

To use multiple inputs by looping them you need to define input names as arrays.
For example;
<input name="student_id[]">
<input name="student_id[]">
<input name="student_id[]">
<input name="student_id[]">
<input name="student_id[]">
If I place this inputs in a form and submit it, I can receive request()->input('student_id') as an array which contains all 5 values in it.
So, in your foreach loop you need to define every multiple input as an array.
Also you can give custom indexes to them to fetch them easily. For example;
<input name="student_data[][student_id]">
<input name="student_data[][student_id]">
<input name="student_data[][student_id]">
<input name="student_data[][student_id]">
<input name="student_data[][student_id]">
Now you can access all looped rows with request()->input('student_data') or directly request()->student_data
It will be an array and you can use it in a foreach. dd(request()->student_data) for example;
array:5 [▼
0 => array:1 [▼
"student_id" => "123"
]
1 => array:1 [▼
"student_id" => "234"
]
2 => array:1 [▼
"student_id" => "345"
]
3 => array:1 [▼
"student_id" => "456"
]
4 => array:1 [▼
"student_id" => "567"
]
]
Now if you give them manual indexes for each row, yo can group everything together;
<input name="student_data[0][student_id]">
<input name="student_data[0][student_name]">
<input name="student_data[1][student_id]">
<input name="student_data[1][student_name]">
<input name="student_data[2][student_id]">
<input name="student_data[2][student_name]">
<input name="student_data[3][student_id]">
<input name="student_data[3][student_name]">
<input name="student_data[4][student_id]">
<input name="student_data[4][student_name]">
Now request()->student_data will be like this;
array:5 [▼
0 => array:2 [▼
"student_id" => "1"
"student_name" => "1st name"
]
1 => array:2 [▼
"student_id" => "2"
"student_name" => "2nd name"
]
2 => array:2 [▼
"student_id" => "3"
"student_name" => "3rd name"
]
3 => array:2 [▼
"student_id" => "4"
"student_name" => "4th name"
]
4 => array:2 [▼
"student_id" => "5"
"student_name" => "5th name"
]
]
So; you need to update your inputs' names.
<form action="{{ route('teacher.add_all_student_results',[$session_id,$semester_id,$course_id,$course_credit]) }}"
method="POST">
<table class="table table-bordered table-hover table-sm">
<thead>
<tr>
<th>IMG</th>
{{-- <th>Department Name</th> --}}
<th>Reg.No</th>
<th>ID.No</th>
<th>Student Name</th>
<th>Attendance</th>
<th>Class Test</th>
<th>PartA</th>
<th>PartB</th>
{{-- --}}
</tr>
</thead>
<tbody>
#csrf
#php $i=1;
#endphp
#foreach($semester_students as $semester_student)
<tr data-widget="expandable-table" aria-expanded="false">
<td>
<input type="hidden" name="student_data[{{ $semester_student->id }}][student_id]" value={{ $semester_student->id }} placeholder="add marks"
class="form-control">
</td>
<td><img class="img-circle img-bordered-sm" src="" alt="U" width="50"></td>
<td>{{$semester_student->registration_number}}</td>
<td>{{$semester_student->roll_number}}</td>
<td>{{$semester_student->firstname}} {{$semester_student->lastname}}</td>
<td>
<input type="text" name="student_data[{{ $semester_student->id }}][attendance]" placeholder="add marks" class="form-control">
</td>
<td>
<input type="text" name="student_data[{{ $semester_student->id }}][class_test]" placeholder="add marks" class="form-control">
</td>
<td>
<input type="text" name="student_data[{{ $semester_student->id }}][parta]" placeholder="add marks" class="form-control">
</td>
<td>
<input type="text" name="student_data[{{ $semester_student->id }}][partb]" placeholder="add marks" class="form-control">
</td>
</tr>
#endforeach
</tbody>
</table>
<button type="submit" class="btn btn-success mt-1"><i class="fa fa-check-circle" aria-hidden="true"></i>
Save</button>
</form>
Now use it in your controller as request()->student_data
Let's loop it;
foreach(request()->student_data as $student_id => $student_row) {
// you can do whatever you want with each row
$student_row['attendance']; // you can access all inputs in this way and run your insert queries for each of rows
}
If you want to use validation on array inputs you can still achieve it;
$request->validate([
'student_data.*.student_id' => 'required|numeric',
'student_data.*.attendance' => 'required',
// and others...
]);

Related

Laravel : Insert multiple data into database

I have been creating Quesionnaire where there are 3 tables : standarts,questions,and responses.
Inside each standart have their own questions.
here is how my form question look like
#foreach($standarts as $s)
<form action="/standart/{{ $s->id }}/answer/post" method="post">
#endforeach
#csrf
<div class="row pt-3 mb-3">
<div class="col-auto">Dokumen Pendukung :</div>
<div class="col-7">
<input class="form-control form-control-sm" name="files_link" type="text" placeholder="Link google drive" aria-label="files_link">
</div>
</div>
<h3 class="text-center">Penilaian</h3>
<table class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th scope="col" class="text-center">No</th>
<th scope="col">Pertanyaan</th>
#foreach($standarts as $s)
#if($s->type == 'Likert')
<th scope="col" class="text-center">1</th>
<th scope="col" class="text-center">2</th>
<th scope="col" class="text-center">3</th>
<th scope="col" class="text-center">4</th>
#else
<th scope="col" class="text-center">Ya</th>
<th scope="col" class="text-center">Tidak</th>
#endif
#endforeach
</tr>
</thead>
<tbody>
#foreach($standarts as $s)
#foreach($s->questions as $q)
<tr>
<td style="width: 7%;" class="text-center">{{ $loop->iteration }}</td>
<td>
<input type="hidden" id="question" name="question[]{{ $q->id }}" value="{{$q->question}}">
<input type="hidden" id="question" name="question_id[]{{ $q->id }}" value="{{$q->id}}">
{{$q->question}}
</td>
#if($s->type == 'Likert')
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="answers[]{{ $q->id }}" id="inlineRadio1" value="1">
</td>
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="answers[]{{ $q->id }}" id="inlineRadio2" value="2">
</td>
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="answers[]{{ $q->id }}" id="inlineRadio3" value="3">
</td>
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="answers[]{{ $q->id }}" id="inlineRadio4" value="4">
</td>
#else
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="answers[]{{ $q->id }}" id="inlineRadio5" value="Ya">
</td>
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="answers[]{{ $q->id }}" id="inlineRadio6" value="Tidak">
</td>
#endif
</tr>
#endforeach
#endforeach
</tbody>
</table>
<div class="row pt-3 mb-4">
<div class="col-auto">Keterangan :</div>
<div class="col-10">
<textarea name="description" class="form-control" id="description" rows="3"></textarea>
</div>
</div>
<hr>
<div class="row pt-3 mb-4">
<div class="col-auto pe-0">
<button type="submit" class="btn btn-success">Simpan</button>
</div>
<div class="col-auto">
<a type="button" href="{{route('auditee.dashboard')}}" class="btn btn-secondary">Batal</a>
</div>
</div>
</form>
this is my controller :
$request->all();
foreach ( $request->get('answers') as $answer) {
$answers[] = [
'user_id' => \Auth::user()->id,
'files_link' => $request->files_link,
'question' => $request->question,
'question_id' => $request->question_id,
'answer' => $request->answers,
'description' => $request->description,
];
}
dd($answers);
and here is how it look like at diedump :
array:3 [▼
0 => array:6 [▼
"user_id" => 3
"files_link" => "http://127.0.0.1:8000/auditee/1/respons/"
"question" => array:3 [▼
0 => "Lorem Ipsum is "
1 => "Lorem Ipsum is "
2 => "Lorem Ipsum is "
]
"question_id" => array:3 [▼
0 => "6"
1 => "7"
2 => "8"
]
"answer" => array:3 [▼
0 => "Ya"
1 => "Tidak"
2 => "Ya"
]
"description" => "asdasd"
]
1 => array:6 [▶]
2 => array:6 [▶]
]
While what i want is like this :
array:3 [▼
0 => array:6 [▼
"user_id" => 3
"files_link" => "http://127.0.0.1:8000/auditee/1/respons/"
"question" => "Lorem Ipsum is "
"question_id" => "6"
"answer" => "Ya"
"description" => "asdasd"
]
1 => array:6 [▼
"user_id" => 3
"files_link" => "http://127.0.0.1:8000/auditee/1/respons/"
"question" => "Lorem Ipsum is"
"question_id" => "7"
"answer" => "Tidak"
"description" => "asdasd"
]
2 => array:6 [▶]
]
and then insert it to the database.
im new at laravel and i have been searching the whole day on internet some example to make it work.
Thanks before
You can do somethink like this
#foreach($standarts as $s)
#foreach($s->questions as $key=>$q)
<tr>
<td style="width: 7%;" class="text-center">{{ $loop->iteration }}</td>
<td>
<input type="hidden" id="question" name="standart[{{$key}}][question]" value="{{$q->question}}">
<input type="hidden" id="question" name="standart[{{$key}}][question_id]" value="{{$q->id}}">
{{$q->question}}
</td>
#if($s->type == 'Likert')
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="standart[{{$key}}][answers]" id="inlineRadio1" value="1">
</td>
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="standart[{{$key}}][answers]" id="inlineRadio2" value="2">
</td>
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="standart[{{$key}}][answers]" id="inlineRadio3" value="3">
</td>
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="standart[{{$key}}][answers]" id="inlineRadio4" value="4">
</td>
#else
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="standart[{{$key}}][answers]" id="inlineRadio5" value="Ya">
</td>
<td style="width: 10%;" class="text-center">
<input class="form-check-input" type="radio" name="standart[{{$key}}][answers]" id="inlineRadio6" value="Tidak">
</td>
#endif
</tr>
#endforeach
#endforeach
So in your controller method you can
dd($request->all()); or dd($request->standart)

Displaying Validation Error Messages Beside The Input Box in Laravel

<form action="/regvalid", method="POST">
{{ csrf_field()}}
<h2>Personal Information</h2>
<hr>
<table>
<tr>
<td>First Name:</td>
<td><input type="text" name="fname" value="{{ old('fname') }}"></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input type="text" name="lname"></td>
</tr>
<tr>
<td>Gender:</td>
<td>
<div class="radio">
<label><input type="radio" value="male" name="gender">Male</label>
<label><input type="radio" value="female" name="gender">Female<label>
</div>
</td>
</tr>
<tr>
<td>Mobile Phone:</td>
<td><input type="text" name="mp"></td>
</tr>
<tr>
<td>Tel No.:</td>
<td><input type="text" name="telno"></td>
</tr>
<tr>
<td>Birth Date:</td>
<td><input type="date" name="bd" ></td>
</tr>
<tr>
<td>Address:</td>
<td><input type="text" name="add"></td>
</tr>
<tr>
<td>Email:</td>
<td><input type="email" name="email"></td>
</tr>
<tr>
<td>Website:</td>
<td><input type="text" name="website"></td>
</tr>
I have already their error rules in the controller;
$rules = [
'fname' => 'required|max:50',
'lname' => 'required|max:50',
'gender' => 'required',
'mp' => 'required|regex:/^([0-9\s-+()]*)$/|min:11',
'telno' => 'required|min:11|numeric',
'bd' => 'required|date',
'add' => 'required|max:100',
'email' => 'required|email',
'website' => 'required|url',
'username' => 'required|min:6|max:20',
'pass' => 'required|min:6|max:12',
'repass' => 'required|min:6|max:12',
];
and also the code that will show all;
#if(count($errors)>0)
#foreach ($errors->all() as $errors)
{{ $errors}}
#endforeach
#endif
I want to display the error messages on each one of the input boxes besides them. I don't know how.
For Displaying error message
Method 1:
<input type="text" name="firstname">
#if($errors->has('firstname'))
<div class="error">{{ $errors->first('firstname') }}</div>
#endif
Method 2:
#error('firstname')
<div class="error">{{ $message }}</div>
#enderror
These two ways of doing it

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>

Model::updateOrCreate actually updates but does not create when record does not exist

I am building an app where if a user wants to update any records the user can edit and update but also add more fields on the front-end so that does data entered in the fields can be added to the records and if user edited anything, that too can updated change successfully.
So there are tests(question) that a user is supposed to do and each test has options just like an examination.
When I try to change anything and click on the update button the record gets updated successfully but if I add a new input as part of the form, it only updates the record and does not add the new one.
This is my HTML:
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>Contraceptive pill</th>
<th>UID</th>
<th>Implant</th>
<th>Injectable</th>
<th>Male condom</th>
<th>Female condom</th>
<th>Fertility awareness</th>
<th>Withdrawal</th>
<th>Sterilization</th>
<th>Emergency contraceptive</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="test-inputs">
#foreach($Test0ptions as $option)
<tr>
<td></td>
<td>
<input class="form-control" type="number" name="contraceptive_pills[]" required value="{{ $option->contraceptive_pill }}">
</td>
<td>
<input class="form-control" type="number" name="uids[]" required value="{{ $option->uid}}">
</td>
<td>
<input class="form-control" type="number" name="implants[]" required value="{{ $option->implant}}">
</td>
<td>
<input class="form-control" type="number" name="injectables[]" required value="{{ $option->injectable}}">
</td >
<td>
<input class="form-control" type="number" name="male_condoms[]" required value="{{ $option->male_condom}}">
</td>
<td>
<input class="form-control" type="number" name="female_condoms[]" required value="{{ $option->female_condom}}">
</td>
<td>
<input class="form-control" type="number" name="fertility_awareness[]" required value="{{ $option->fertility_awareness}}">
</td>
<td>
<input class="form-control" type="number" name="withdrawals[]" required value="{{ $option->withdrawal}}">
</td>
<td>
<input class="form-control" type="number" name="sterilizations[]" required value="{{ $option->sterilization}}">
</td>
<td>
<input class="form-control" type="number" name="emergency_contraceptives[]" required value="{{ $option->emergency_contraceptive}}">
</td>
</tr>
</tbody>
</table>
<div class="form-group" style="padding-bottom: 10px;">
<button type="submit" class="btn primary"><i class="fa fa-save"></i> Update</button>
</div>
This is my script that will add new set of form:
populateNewTestForms() {
$('#test-inputs').append(`
<tr>
<td>${this.incrementTableCounter+=1}</td>
<td><input class="form-control" type="number" name="contraceptive_pills[]" required> </td>
<td> <input class="form-control" type="number" name="uids[]" required> </td>
<td> <input class="form-control" type="number" name="implants[]" required> </td>
<td> <input class="form-control" type="number" name="injectables[]" required> </td>
<td> <input class="form-control" type="number" name="male_condoms[]" required> </td>
<td> <input class="form-control" type="number" name="female_condoms[]" required> </td>
<td> <input class="form-control" type="number" name="fertility_awareness[]" required> </td>
<td> <input class="form-control" type="number" name="withdrawals[]" required> </td>
<td> <input class="form-control" type="number" name="sterilizations[]" required> </td>
<td> <input class="form-control" type="number" name="emergency_contraceptives[]" required>
</td>
<td>
<button type="button" onclick=" $(this).closest('tr').remove(); " class="btn btn-danger" title="delete"><i class="fa fa-trash"></i></button>
</td>
</tr>
`);
This is my controller :
foreach ($request->option_ids as $option_id) {
TestOption::updateOrCreate(['id' => $option_id], [
'test_id' => $test->id,
'name' => $request->names[$i],
'contraceptive_pill' => $request->contraceptive_pills[$i],
'uid' => $request->uids[$i],
'implant' => $request->implants[$i],
'injectable' => $request->injectables[$i],
'male_condom' => $request->male_condoms[$i],
'female_condom' => $request->female_condoms[$i],
'fertility_awareness' => $request->fertility_awareness[$i],
'withdrawal' => $request->withdrawals[$i],
'sterilization' => $request->sterilizations[$i],
'emergency_contraceptive' => $request->emergency_contraceptives[$i]
]);
Your function searches for option only, try swapping them around like this.
TestOption::updateOrCreate([
'test_id' => $test->id
'name' => $request->names[$i],
'contraceptive_pill' => $request->contraceptive_pills[$i],
'uid' => $request->uids[$i],
'implant' => $request->implants[$i],
'injectable' => $request->injectables[$i],
'male_condom' => $request->male_condoms[$i],
'female_condom' => $request->female_condoms[$i],
'fertility_awareness' => $request->fertility_awareness[$i],
'withdrawal' => $request->withdrawals[$i],
'sterilization' => $request->sterilizations[$i],
'emergency_contraceptive' => $request->emergency_contraceptives[$i]
],['id' => $option_id]);

Resources