Foreach loop with json data laravel - json

I want to make a table in html with json data using laravel excel, the data looks like this
4 => {
+"id": 5
+"date": "2020-1-3"
+"grade": "7"
+"nama": "["bryan","anderson"]"
+"status": "["active","active"]"
}
the excel file output i was hoping for is
this. Status fill the column based on dates and if there is no data in particular date the column will filled with "-". I tried a foreach loop I found here, but did not have any luck.
I call the data with $reports, for example $reports->status will return ["active","active"] and so on.
This is the code i am working on
<table>
<thead>
<tr>
<th>No.</th>
<th>Name</th>
#for ($i = 1; $i < 32; $i++)
<th>{{ $i }}</th>
#endfor
</tr>
</thead>
<tbody>
#foreach ($reports as $rp)
<tr>
<td>{{ $loop->iteration }}</td>
<!--INSERT DATA HERE-->
<td></td>
</tr>
#endforeach
</tbody>
</table>
dd($reports) return =
array:2 [▼
0 => {#455 ▼
+"id": 17
+"date": "2021-01-03"
+"grade": "7"
+"nama": "["bryan","anderson"]"
+"status": "["active","active"]"
+"created_at": "2021-01-23 05:33:27"
+"updated_at": "2021-01-23 05:33:27"
}
1 => {#1414 ▶}
]

Try this following code;
<table border=1>
<thead>
<tr>
<th>No.</th>
<th>Name</th>
<th>Status</th>
</tr>
</thead>
<tbody>
#php $index=1; #endphp
#foreach ($reports as $rp)
#foreach ($rp->nama as $key => $val)
<tr>
<td>{{ $index }}</td>
<td>{{ $val }}</td>
<td>{{ optional($rp->status)[$key] }}</td>
</tr>
#php $index++; #endphp
#endforeach
#endforeach
</tbody>
</table>

Related

How to combine two arrays into one array of objects?

Can I use an ngFor instead of repeating <table> two times?
NB: I thought to combine all the items into objects as items of a single array of mapping(each object contains a variable, label and value) but it does not work for me)
....
this.maxValueTable.push(selectedData.res.maxValue);
this.minValueTable.push(selectedData.res.minValue);
...
<div style="display: flex;">
<table style="width:100%;">
<thead>
<tr>
<th>Max</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let maxValue of maxValueTable">
<td> {{ maxValue | numberFormatter: (getUnit() | async)}}</td>
</tr>
</tbody>
</table>
<table style="width:100%;">
<thead>
<tr>
<th>Min</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let maxValue of minValueTable">
<td> {{ MinValue| numberFormatter: (getUnit() | async)}}</td>
</tr>
</tbody>
</table>
</div>
Another way:
<!--create an array directly in the .html: you can also use
a variable in your .ts-->
<table *ngFor="let table of [{head:'Max',data:maxValueTable},
{head:'Max',data:maxValueTable}]
style="width:100%;">
<thead>
<tr>
<!--use table.head-->
<th>{{table.head}}</th>
</tr>
</thead>
<tbody>
<!--see how iterate over table.data-->
<tr *ngFor="let maxValue of table.data">
<td> {{ maxValue | numberFormatter: (getUnit() | async)}}</td>
</tr>
</tbody>
</table>
If your arrays has the same length and only want a table, iterate over one array ans use the index to get the value of the another one
<table style="width:100%;">
<thead>
<tr>
<th>Max</th>
<th>Min</th>
</tr>
</thead>
<tbody>
<!--see the "let i=index"-->
<tr *ngFor="let maxValue of maxValueTable;let i=index">
<td> {{ maxValue | numberFormatter: (getUnit() | async)}}</td>
<!--use the "index" "i" to get the element of the another array-->
<td>
{{ minValueTable[i] | numberFormatter: (getUnit() | async)}}
</td>
</tr>
</tbody>
</table>
in this case you can also use map to create a new Array
minMax=this.minValueTable.map((x,index)=>({
min:x,
max:this.maxValueTable[index]
}))
And use {{value.min}} and {{value.max}}
You can create a function that will combine min and max values into an array like that:
mergeIntoArray(maxValue: Array<number>, minValue: Array<number>): IMergedObj[] {
let mergedArray = [];
maxValue.forEach((value, index) => {
let tempObj = {};
tempObj['maxValue'] = value;
tempObj['minValue'] = minValue[index];
mergedArray.push(tempObj);
});
return mergedArray;
}
and call this function like that:
let minAndMax = [];
this.minAndMax = this.mergeIntoArray(this.maxValueTable, this.minValueTable);
after that, use this variable (minAndMax) in your HTML template. This way you do not need to use ngFor twice.
<table style="width:100%;">
<thead>
<tr>
<th>Max</th>
<th>Min</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of minAndMax">
<td>{{ item.maxValue }}</td>
<td>{{ item.minValue }}</td>
</tr>
</tbody>
</table>
Here is the stackblitz link created for you. Hope that might help you.
You can use *ngTemplateOutlet for this case:
<div style="display: flex;">
<ng-container *ngTemplateOutlet="tableTemplate; context: {$implicit: maxValueTable, header: 'Max'}"></ng-container>
<ng-container *ngTemplateOutlet="tableTemplate; context: {$implicit: minValueTable, header: 'Min'}"></ng-container>
</div>
<ng-template #tableTemplate let-values, let-header="header">
<table style="width:100%;">
<thead>
<tr>
<th>{{ header }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let value of values">
<td> {{ value | numberFormatter: (getUnit() | async) }}</td>
</tr>
</tbody>
</table>
</ng-template>
And you will get the same table rendered twice - for Max and Min values.
As you can see, the arguments are passed as a second argument inside ngTemplateOutlet:
context: {$implicit: valuesArgument, header: headerArgument}
Later you could use this template to create infinite amount of tables:
<div *ngFor="let table of tables">
<ng-container *ngTemplateOutlet="tableTemplate; context: {$implicit: table.values, header: table.header}"></ng-container>
</div>
Assuming your tables property will look like
export class C {
tables: Table[] = [{header: 'Min', values: [1, 2, 3]}, {header: 'Max', values: [4, 5, 6]}, {header: 'Other', values: [0, -1, -2]}]
}

Laravel: How would you Query this Table and group two rows with the sameby their staff ID

I wish to achieve such a table:
I currently have this table:
EDIT!!
This is my attendance table in My sql.
This is the attendance table in mysql:
This is the Staff Table in mySql
Dashboard Controller
public function index()
{
$data = [
'attendances'=>Attendance::query()
->where('type','!=','255')
->with('staff')->get()
];
return view('dashboard.attendance_table',$data);
// $attendances = Attendance::all(); // or whatever Eloquent query you want that returns a collection
//
// $grouped = $attendances->groupBy('staff_id');
//
// dd($grouped);
}
attendance.blade
<div class="row">
<div class="col-lg-12">
<div class="card overflow-hidden">
<div class="card-body">
<div>
<h6 class="main-content-label mb-1">Attendance Table</h6>
</div>
<div class="table-responsive">
<table id="exportexampl" class="table table-bordered border-t0 key-buttons text-nowrap w-100 display " >
<thead>
<tr>
<th>#</th>
<th>Staff Name</th>
<th>User ID</th>
<th>Time In/ Time Out</th>
<th>Card No.</th>
<th>Date</th>
<th>Time</th>
</tr>
</thead>
<tbody>
#foreach($attendances as $attendance)
<tr>
<td>{{$loop->iteration}}</td>
<td>{{ $attendance->staff->name }}</td>
<td>{{ $attendance->staff->userid }}</td>
{{-- <td>{{gettype($attendance->type)}}</td>--}}
<td>{{ ($attendance->type==0) ? 'Time in': 'Time out'}}</td>
<td>{{ $attendance->staff->cardno }}</td>
<td>{{ \Carbon\Carbon::parse($attendance->timestamp)->toDateString() }}</td>
<td>{{ \Carbon\Carbon::parse($attendance->timestamp)->format("H:i:s") }}</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
How would you group the current attendance table so as to achieve my desired attendance table as shown above.
Note:
Time in is 'type'=0
time out is type =1
Try this:
$attendances = Staff::leftJoin('attendances', function($join) {
$join->on('attendances.staff_id', '=', 'staff.id')
->on('attendances.id', '=', DB::raw("(SELECT max(id) from attendances WHERE attendances.staff_id = staff.id)"));
})
->select(array('staff.*', 'attendances.time_in as time_in', 'attendances.time_out as time_out'))
->get();
or if time_in and time_out is placed in different row, try this:
Controller:
$staffs = Staff::all();
in your view .blade.php (inside $staffs foreach):
#php
$time_in = $staff->attendances()->where('type', 0)->orderBy('created_at', 'desc')->first() ? $staff->attendances ()->where('type', 0)->orderBy('created_at', 'desc')->first()->timestamp : '-';
$time_out = $staff->attendances()->where('type', 1)->orderBy('created_at', 'desc')->first() ? $staff->attendances()->where('type', 1)->orderBy('created_at', 'desc')->first()->timestamp : '-';
#endphp
so you can just call $time_in or $time_out in your <td>{{ $time_in }} - {{ $time_out }}</td>

I'm getting some errors while passing data to the frontend

I'm getting some errors while passing data to the frontend, but when I return this $order then it shows a JSON data like this
[
{
"id": 1,
"customer_id": 3446467182106354,
"products": {
"1": {
"'name'": "Soap",
"'quantity'": "1"
},
"2": {
"'name'": "Shampoo",
"'quantity'": "1"
}
},
"total_amount": 798,
"status": "pending",
"created_at": "2020-10-21T08:51:15.000000Z",
"updated_at": "2020-10-21T08:51:15.000000Z"
}
]
But when I pass It to the front end it says like this
Property [products] does not exist on this collection instance. (View: C:\xampp\htdocs\blog\resources\views\customer\orders.blade.php)
by the way I've a json data in my database
looking at the json data u have mentioned in the question, Products is array of products and its in side main array.
you can access products this way...
make another foreach loop for products
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Products</th>
<th scope="col">Total</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
#foreach ($orders as $order)
<tr>
#foreach{{$order->products as $product}}
<th>{{ $product->name }}</th>
#endforeach
<td>{{ $order->total }}</td>
<td>{{ $order->status }}</td>
</tr>
#endforeach
</tbody>
you need to loop over you cannot print collcetion so you need to update your controller and blade file like this
Controller
public function customerOrders($id)
{
$orders = Order::where('customer_id', $id)->get();
return view('customer.orders', compact('orders'));
}
blade
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Products</th>
<th scope="col">Total</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
#foreach ($orders as $order)
<tr>
<th>
#foreach ($order->products as $product)
{{ $product['name'] }}
#endforeach
</th>
<td>{{ $order->total }}</td>
<td>{{ $order->status }}</td>
</tr>
#endforeach
</tbody>
</table>
like this you will get all the data
Before using this data you should use json_decode() function

How to show json in laravel

So I want to show post in data table but there is 2 layer of data, the data it look like this
[
{
created_at":
"id_post":1,
"name":"trying post",
"comment_all":
[
{
"id_user":3,
}
],
So I want to get comment_all, I use this code in blade
#foreach($compalls as $compall )
<tr>
<td>{{ $compall->coment_all->id_user }}</td>
</tr>
#endforeach
but I got this error
Property [id_user] does not exist on this collection instance. (View: directory/file.blade.php)
hope you can help me
Your coment_all is an array. You have to loop through the array to retrieve each id_user:
#foreach ($compalls as $compall)
<tr>
#foreach ($compall->coment_all as $coment)
<td>{{ $coment->id_user }}</td>
#endforeach
</tr>
#endforeach
You need to loop coment_all because it is an array. like the following:
First foreach $compalls and another foreach inside that to get id_user.
#foreach ($compalls as $compall)
<tr>
#foreach ($compall->coment_all as $coment)
<td>{{ $coment->id_user }}</td>
#endforeach
</tr>
#endforeach

Fat-free framework: how to display a calendar using the Matrix class?

$matrix = \Matrix::instance();
$cal = $matrix->calendar('2014-06', 1);
I can not work out how to use data in $cal & get it to display in view
The calendar() method returns an array of weeks.
Here's a basic example:
index.php
$f3=require('lib/base.php');
$f3->route('GET /cal/#year/#month',function($f3,$params){
$f3->cal=Matrix::instance()->calendar($params['year'].'-'.$params['month'],1);
$f3->title=date('F Y',mktime(0,0,0,$params['month'],1,$params['year']));
echo Template::instance()->render('cal.html');
});
$f3->run();
cal.html
<h1>{{ #title }}</h1>
<table>
<thead>
<tr>
<th>Mo</th>
<th>Tu</th>
<th>We</th>
<th>Th</th>
<th>Fr</th>
<th>Sa</th>
<th>Su</th>
</tr>
</thead>
<tbody>
<repeat group="#cal" value="#week">
<tr>
<loop from="$d=0" to="$d<7" step="$d++">
<td>{{ ##week[ #d ] }}</td>
</loop>
</tr>
</repeat>
</tbody>
</table>
Now GET /cal/2014/06 should return something like: