Why isn't all the data showing up in Laravel? - php

Want to ask why my data from the database (MySQL) doesn't all appear on the website from the grades table join with the grade_details table, my database is attached:
Screenshot my Database in MySQL
So this data is from the join grades table with join grade_details taken from the id_grade data like the table above.
Screenshot in web
As given by the blue contact in the Quiz table, only Student31 values appear, while the other Quiz values are at 0, but the student names Servira and Student4 already have values, namely 90 and 80, as in the grade_details table in the database. But to avoid confusion, the Servira and Student4 data don't show up with a value of only 0. Even though I have used a join with another table, the other quiz scores cannot be read, only 1 student readable value data.
Code:
Model Grade Detail:
class GradeDetail extends Model
{
use HasFactory;
protected $primaryKey = 'id_grade_detail';
protected $table = 'grade_details';
protected $fillable = [
'id_grade_detail',
'id_grade',
'id_student',
'quiz',
'assignment',
'd_t',
'min_text',
'final_text',
'total',
];
public function grades(){
return $this->belongsTo(Grade::class, 'id_grade','id_grade');
}
public function students(){
return $this->belongsTo(User::class, 'id_student','id');
}
}
Mode Grade:
class Grade extends Model
{
use HasFactory;
protected $primaryKey = 'id_grade';
protected $table = 'grades';
protected $fillable = [
'id_grade',
'id_subject',
'id_academic_year',
'id_semester',
'min_score',
'done',
];
public function details(){
return $this->belongsTo(GradeDetail::class, 'id_grade','id_grade');
}
}
Controller:
public function ViewGrade($id){
$subject = Grade::join('subjects', 'grades.id_subject', '=', 'subjects.id_sub')
->join('class_infos', 'subjects.id_class', '=', 'class_infos.id')
->join('class_details', 'class_infos.id', '=', 'class_details.id_class')
->join('users', 'class_details.id_user', '=', 'users.id')
->where('subjects.id_teacher', '=', Auth::user()->id)
->where('grades.id_grade', '=', $id)
->get();
return view('teacher.grade.view_grade', compact('subject'));
}
Blade:
<table class="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<thead class="text-xs text-white uppercase bg-[#464867] dark:bg-[#464867]">
<tr>
<th scope="col" class="py-3 px-6">
No
</th>
<th scope="col" class="py-3 px-6">
NISN
</th>
<th scope="col" class="py-3 px-6">
Name Student
</th>
<th scope="col" class="py-3 px-6">
Min Score
</th>
<th scope="col" class="py-3 px-6">
Quiz
</th>
<th scope="col" class="py-3 px-6">
Assignment
</th>
<th scope="col" class="py-3 px-6">
Daily Tests
</th>
<th scope="col" class="py-3 px-6">
Min Exam
</th>
<th scope="col" class="py-3 px-6">
Final Exam
</th>
<th scope="col" class="py-3 px-6">
Total
</th>
</tr>
</thead>
<tbody>
#php $no = 1; #endphp
#forelse($subject as $data)
<tr class="bg-white border-b dark:bg-gray-900 dark:border-gray-700">
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
{{$no++}}
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
{{$data->username}}
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
{{$data->name}}
</th>
<th scope="row" class="py-4 px-6 font-medium text-red-700 whitespace-nowrap dark:text-white">
{{$data->min_score}}
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
#if(!empty($data->details))
{{ (!empty( $data->id == $data->details->id_student )) ? $data->details->quiz: 0}}
#else
0
#endif
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
#if(!empty($data->details))
{{$data->details->assignment}}
#else
0
#endif
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
#if(!empty($data->details))
{{$data->details->d_t}}
#else
0
#endif
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
#if(!empty($data->details))
{{$data->details->min_text}}
#else
0
#endif
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
#if(!empty($data->details))
{{$data->details->final_text}}
#else
0
#endif
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
#if(!empty($data->details))
{{$data->details->total}}
#else
0
#endif
</th>
</tr>
#empty
<tr colspan = "10" class="bg-white border-b dark:bg-gray-900 dark:border-gray-700">
<td class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
No Data
</td>
</tr>
#endforelse
</tbody>
</table>
How do you make the Servira and Student4 column name fields filled with grades on quizzes on the web as well as in the grade_details database table?

in your model Grade you should specify the details relationship as a HasMany relation not a BelongsTo relation so your model would be :
public function details(){
$this->hasMany(GradeDetail::class, 'id_grade','id_grade');
}

#AlirezaSalehi is correct. It is indeed a hasMany relationship. The correct details relationship in your Grade is indeed:
public function details(){
$this->hasMany(GradeDetail::class, 'id_grade','id_grade');
}
In the GradeDetail model, your primary key is id_grade_detail (not id), which is fine, so your relationships should be as following:
public function grades(){
return $this->belongsTo(Grade::class, 'id_grade','id_grade_detail');
}
public function students(){
return $this->belongsTo(User::class, 'id_student','id_grade_detail');
}
Where id_student is the primary key of the User model, which I assume by the code you have given (out of the box, the primary key of the User model is id, did you change that?)
Check the documentation at https://laravel.com/docs/9.x/eloquent-relationships#one-to-many
In my experience, it's good practice to follow the Laravel conventions, explained on the same page. Unless you have no other choice, f.ex. if the DB is already in existence. If it's a fresh project, consider to follow the conventions. It will safe you debugging time later on. (speaking of personal experience)

Related

Edit Data using Array but the result is the same in Laravel

I want to edit data using an array, but when I submit the edits, the results are all the same from below.
When editing each student name, it has a different value, but when submitting, the results are all the same, like this in MySQL and the Web:
Code:
Controller
public function UpdateEditGradeStudent(Request $request){
$data = GradeDetail::find($request->id_grade_detail);
foreach($request->id_grade as $index => $value) {
DB::table('grade_details')
->update(array(
'id_grade' => $value,
'quiz' => $request->quiz[$index],
'assignment' => $request->assignment[$index],
'min_text' => $request->min_text[$index],
'd_t' => $request->d_t[$index],
'final_text' => $request->final_text[$index],
'total' => $request->total[$index],
));
}
return redirect('/');
}
Blade
<form method="POST" action="{{route('edit.teacher.grade')}}" enctype="multipart/form-data">
#csrf
{{-- <input type="hidden" name="id_grade[]" value="{{ $userGrades->id_grade }}">--}}
<div class="flex">
<input type="submit" class="focus:outline-none text-white bg-[#464867] hover:bg-[#464867] font-medium rounded-lg text-sm px-5 py-2.5 mb-2 mt-3 mr-4" type="button" value="Save">
<a href="{{url('teacher/data-grade')}}" class="focus:outline-none text-white bg-[#464867] hover:bg-[#464867] font-medium rounded-lg text-sm px-5 py-2.5 mb-2 mt-3" type="button" >Cancel</a>
</div>
<table class="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
#php $no = 1; #endphp
#forelse($subject as $data)
<input
type="hidden"
name="id_grade[]"
value="{{$data->id_grade}}"
>
<tr class="bg-white border-b dark:bg-gray-900 dark:border-gray-700">
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
{{$no++}}
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
{{$data->username}}
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
{{$data->name}}
</th>
<th scope="row" class="py-4 px-6 font-medium text-red-700 whitespace-nowrap dark:text-white">
{{$data->min_score}}
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
<input
type="number"
min="0"
max="100"
name="quiz[]"
id="quiz"
value="{{$data->quiz}}"
autocomplete="quiz"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white"
required
>
</th>
<th scope="row" class="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white">
<input
type="number"
min="0"
max="100"
name="assignment[]"
id="assignment"
value="{{$data->assignment}}"
autocomplete="min_score"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white"
required
>
</th>
I didn't screenshot all the blade coding.
How to edit data array according to the data we have edited data.
Looks like your key is id_grade_detail, you should filter by that field:
#forelse($subject as $data)
<input
type="hidden"
name="id_grade_detail[]"
value="{{$data->id_grade_detail}}"
>
<input
type="hidden"
name="id_grade[]"
value="{{$data->id_grade}}"
>
...
And on the server:
public function UpdateEditGradeStudent(Request $request)
{
foreach($request->id_grade_detail as $index => $value) {
$grade_detail = GradeDetail::find($value);
if ($grade_detail) {
$grade_detail->quiz = $request->quiz[$index];
$grade_detail->assignment = $request->assignment[$index];
$grade_detail->min_text = $request->min_text[$index];
$grade_detail->d_t = $request->quiz[$index];
$grade_detail->final_text = $request->final_text[$index];
$grade_detail->total = $request->total[$index];
$grade_detail->save();
}
}
return redirect('/');
}

How to create subrow in one column dynamically

In this image this table is based on my databse "Employee" table. there is 2 part. 1st part is from "#" column to "employee type" column. 2nd part is "Leave Type" Column. This column infromation will come from "LeaveType" Table. No I want to create different type leavetype for 1 employee. It mean I want to create subrow for each parent row in this column. But I can't
here is my incomplete table code in blade file.
<table class="table table-bordered mb-0" id="myTable">
<thead class="bg-orange">
<tr class="text-light">
<th >#</th>
<th >Employee Name</th>
<th >Employee Id</th>
<th >Employee Type</th>
<th >Leave Type</th>
<th >Entitled</th>
<th >Used Leave</th>
<th >Balance</th>
</tr>
</thead>
<tbody>
#foreach($users as $user)
<tr>
<th scope="row">{{$loop->iteration}}</th>
<td>
{{$user->name}} <br>
#foreach($designations as $designation)
#if($designation->id === $user->designationId)
{{$designation->designationName}}
<br>
#endif
#endforeach
#foreach($departments as $department)
#if($department->id === $user->departmentId)
{{$department->departmentName}}
#endif
#endforeach
</td>
<td>{{$user->employeeId}}</td>
#foreach($designations as $designation)
#if($designation->id === $user->designationId)
<td>{{$designation->attendanceType}}</td>
<br>
#endif
#endforeach
<td>
</td>
</tr>
#endforeach
</tbody>
</table>

Save lookup component query to another table

I have a livewire component that performs queries on a table in sql but I want to select the query that I want to save in another table in mysql
my component and my view
{
return view('livewire.search-users', [
'users' => viewfacturaa::where('FACTURA', $this->search)
->get(),
]);
}
<div>
<input wire:model="search" type="text" placeholder="Ingrese factura" />
<table class="min-w-full">
<thead class="bg-info dark:bg-white">
<tr>
<th scope="col"
class="py-3 px-6 text-xs font-medium tracking-wider text-left text-white uppercase dark:text-gray-400">
SELECCION
</th>
<th scope="col"
class="py-3 px-6 text-xs font-medium tracking-wider text-left text-white uppercase dark:text-gray-400">
FACTURA
</th>
<th scope="col"
class="py-3 px-6 text-xs font-medium tracking-wider text-left text-white uppercase dark:text-gray-400">
PRODUCTO
</th>
<th scope="col"
class="py-3 px-6 text-xs font-medium tracking-wider text-left text-white uppercase dark:text-gray-400">
DESCRIPCION
</th>
</tr </thead>
<tbody>
#foreach ($users as $user)
<tr>
<td class="border px-2 py-2 text-xs">{{$user->FACTURA}}</td>
<td class="border px-2 py-2 text-xs">{{$user->PRODUCTO}}</td>
<td class="border px-2 py-2 text-xs">{{$user->DESCRIPCION_FACTURA}}</td>
<td class="border px-2 py-2 text-xs text-center">
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
As can be seen in my view, it is a text type input in which I write the invoice number and the results are displayed in a table

Preventing a hyperlink from looping with the rest of the table?

I have a table that presents grouped data, and has 'buttons' in the form of hyperlinks for users to view more information about that grouped data as a whole. However the button also loops with every row, when ideally I would only like it to show once for every group. I have tried moving around my #foreach loops but keep getting errors that the requested ID does not exist in this collection instance.
For example, I am trying to get those links to only appear once in each group (once in 1 and 2 like in the image).
Code:
<tr>
#foreach ($grouped as $mealplan)
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Recipe Information
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Meal Plan Info
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Print
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Archive
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Recipe Name
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Day
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
#foreach ($mealplan as $recipe)
<tr>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
More
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
Meal Plan Info
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
Print Ingredient List
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
Archive
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
{{$recipe->recipe_name}}
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
{{$recipe->Day}}
</td>
</tr>
</br>
#endforeach
#endforeach
Any advice on where to move the loops, or how to only get the links to show once per group in the table would be really appreciated.
The concept of doing such iteration is as follows:
Notice the comments in the code
<table>
{{--/*Comment: iterate through the groups to show sub-groups*/--}}
#foreach ($group as $sub_group)
<thead>
{{--/*Comment: the group head row is here*/--}}
</thead>
<tbody>
{{--/*Comment: iterate through the sub-group to show its items*/--}}
#foreach ($sub_group as $item)
{{--/*Comment: put here a condition to filter items*/--}}
{{--/*Comment: in your case you want the "MORE" link to only
appear in the first row so we will check iteration index.
Luckily, we have $loop variable in Laravel so we don't have to count
the index manually. The condition will be like this:
1- if loop is in round "1", we should print the link inside the <td>.
2- if not we should print empty <td> */--}}
{{--/*Comment: Print the "more" link only on the first iteration */--}}
#if($loop->iteration == 1)
<td>{{--/*Comment: put the link here */--}}</td>
#else
<td>{{--/*Comment: empty cell*/--}}</td>
#endif
{{--/*Comment: then here comes the rest of the <td>s */--}}
#endforeach
</tbody>
#endforeach
</table>
And here is an Edit to your code
<table class="table" style="magin-left:200px">
#foreach ($grouped as $mealplan)
<thead>
<tr>
<th scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Recipe Information
</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Meal Plan Info
</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Print
</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Archive
</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Recipe Name
</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Day
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
#foreach ($mealplan as $recipe)
<tr>
{{-- Print the "more" link only on the first iteration --}}
#if ($loop->iteration == 1)
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
<a href="recipeinformation/{{ $recipe->Recipe_ID }}"
class="text-indigo-600 hover:text-indigo-900 mb-2 mr-2">More</a>
</td>
#else
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"></td>
#endif
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
<a href="/MealPlanDisplay/modal/{{ $recipe->MealPlan_ID }}"
class="text-indigo-600 hover:text-indigo-900 mb-2 mr-2">Meal Plan Info</a>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
<a href="printpreviewingredients/{{ $recipe->MealPlan_ID }}"
class="text-indigo-600 hover:text-indigo-900 mb-2 mr-2">Print Ingredient
List</a>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
<a href="/Archive/{{ $recipe->MealPlan_ID }}"
class="text-red-600 hover:text-indigo-900 mb-2 mr-2">Archive</a>
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
{{ $recipe->recipe_name }}
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
{{ $recipe->Day }}
</td>
</tr>
#endforeach
</tbody>
#endforeach
</table>
Outcome of the code

Can you split tables in a View during a foreach loop?

I am working on a meal plan project, and for visual presentation's sake, I was wondering if during a foreach loop each table with a unique MealPlan_ID could have a break (a separation) between each table with presented data?
Currently, each new meal plan that is generated just adds to the one table.
The View:
<thead>
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
ID
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Recipe Name
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Day
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
View More
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
#foreach ($data as $var)
<tr>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
{{$var->Recipe_ID}}
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
{{$var->recipe_name}}
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
{{$var->Day}}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
More
</td>
</tr>
#endforeach
</tbody>
I have two database tables that affect the populating of the table, the MealPlan Table and the Recipe Table.
Index method in MealPlanDisplayController:
public function index(){
$currentuserid = Auth::id();
$data = Recipe::join('mealplan_main', 'mealplan_main.Recipe_ID', '=', 'recipe.id')->where('mealplan_main.user_id', '=', $currentuserid)->get(['mealplan_main.Recipe_ID', 'recipe.recipe_name', 'mealplan_main.Day']);
return view('MealPlanDisplay.index', compact('data'));
Is it possible to split the table every time a new Meal Plan is generated with a new Meal Plan ID? If not, what is a better way to present the data other than a table, since I would like to visually present the meal plans separate from each other (as a user can have multiple meal plans)?
In that case $data is a collection, so you can use groupBy()
$grouped = $data->groupBy('Meal_Plan_ID');
/*
[
1 => [ /* data */ ], //Recepies for meal plan 1
2 => [ /* data */ ], //Recepies for meal plan 2
]
*/
Then in HTML
#foreach ($grouped as $mealPlan)
<!-- Init of new table or set pace -->
#foreach ($mealPlan as $recepie)
<!-- Recepie columns -->
#endforeach
#endforeach

Categories