PHP Laravel - Nested blade loop requiring SQL query - php

I am trying to return a loop to my blade template file with below result:
Main Name
Sub name #1
Sub name #2
Main Name
Sub name #1
Sub name #2
etc..
I have created a controller for this:
MergerController.php
public function index()
{
$MainOrganisations = DB::table('test')
->select('address', 'code', DB::raw('count(*) as amount'))
->where('code', 'LIKE', '64%')
->groupBy('address')
->orderBy('amount', 'desc')
->get();
foreach($MainOrganisations as $value){
$SubOrganisations = DB::table('test')
->select('name', 'code')
->where('address', $value->address)
->where('code', 'NOT LIKE', '64%')
->get();
}
$data = [
'MainOrganisations' => $MainOrganisations,
'SubOrganisations' => $SubOrganisations,
];
#Return data to our view
return view('merger.list')->with($data);
}
Then, inside my view file, I try to show this data:
list.blade.php
<table>
#foreach ($MainOrganisations as $Main)
<thead>
<th colspan="2">{{ $Main->address }}</th>
</thead>
<thead>
<th>Name</th>
<th>Code</th>
</thead>
<tbody>
#foreach($SubOrganisations as $Sub)
<tr>
<td>{{ $Sub->name }}</td>
</tr>
#endforeach
</tbody>
#endforeach
</table>
However, above only return the first result from $SubOrganisations, and then loops ONLY that result in my nested foreach:
#foreach($SubOrganisations as $Sub)
<tr>
<td>{{ $Sub->name }}</td>
</tr>
#endforeach
Returns:
Sub name #1
Sub name #1
Sub name #1

The way you are looping through each data for sub organization is wrong. Its better yo use eloquent relationship with eager loading for better performance.
Change your controller code:
public function index()
{
$MainOrganisations = DB::table('test')
->select('address', 'code', DB::raw('count(*) as amount'))
->where('code', 'LIKE', '64%')
->groupBy('address')
->orderBy('amount', 'desc')
->get();
foreach($MainOrganisations as $key => $MainOrganisation){
$SubOrganisations = DB::table('test')
->select('name', 'code')
->where('address', $MainOrganisation->address)
->where('code', 'NOT LIKE', '64%')
->get();
$MainOrganisation->subOrganisations = $SubOrganisations;
}
$data = [
'MainOrganisations' => $MainOrganisations
];
#Return data to our view
return view('merger.list')->with($data);
}
In you view:
<table>
#foreach ($MainOrganisations as $Main)
<thead>
<th colspan="2">{{ $Main->address }}</th>
</thead>
<thead>
<th>Name</th>
<th>Code</th>
</thead>
<tbody>
#foreach($Main->subOrganisations as $Sub)
<tr>
<td>{{ $Sub->name }}</td>
</tr>
#endforeach
</tbody>
#endforeach
</table>

Related

Laravel 9 | Laravel Excel 3.1 - Group multiple records in one cell

This is how my app generate a report (excel file) from my app:
Export/ActividadesporTodosServiciosExport.php
public function collection()
{
return Actividad::whereMonth('fecha_inicio', '12')
->whereYear('fecha_inicio', '2022')
->orderBy('servicio_id', 'ASC')
->with('servicio')
->get();
}
public function headings(): array
{
return [
'SERVICIO',
'DESCRIPCION',
];
}
public function map($actividad) : array
{
$nombre = [];
$descripcion = [];
foreach($actividad as $activity){
// dump($actividad);
$nombre[]=$actividad->descripcion;
foreach($actividad->servicio as $key => $servicio){
$descripcion = $actividad->servicio->nombre;
}
}
return [
[
$nombre[0],
$descripcion,
'',
'',
],
];
}
The screenshot shows 4 records in 4 rows, and I wanna try to convert that 4 records in one only cell of a row, like this example:
You could do that easily in a view.
https://docs.laravel-excel.com/3.1/exports/from-view.html
namespace App\Exports;
use App\Models\Actividad;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;
class ActividadesporTodosServiciosExport implements FromView
{
public function view(): View
{
$actividades = Actividad::query()
->whereMonth('fecha_inicio', '12')
->whereYear('fecha_inicio', '2022')
->orderBy('servicio_id', 'ASC')
->with('servicio')
->get();
return view('exports.your_view', [
'actividades' => $actividades,
]);
}
}
resources/views/exports/your_view.blade.php
<table>
<thead>
<tr>
<th>SERVICIO</th>
<th>DESCRIPCION</th>
</tr>
</thead>
<tbody>
#foreach($actividades as $actividad)
<tr>
<td>{{ $actividad->descripcion }}</td>
<td>{{ $actividad->servicio->implode('nombre', "\n") }}</td>
</tr>
#endforeach
</tbody>
</table>
Alternatively using the rowspan attribute to get grouped cells in the spreadsheet
<table>
<thead>
<tr>
<th>SERVICIO</th>
<th>DESCRIPCION</th>
</tr>
</thead>
<tbody>
#foreach($actividades as $actividad)
<tr>
<td rowspan="{{ $actividad->servicio->count() + 1">{{ $actividad->descripcion }}</td>
</tr>
#foreach($actividad->servicio as $servicio)
<tr>
<td>{{ $servicio->nombre }}</td>
</tr>
#endforeach
#endforeach
</tbody>
</table>

Laravel - Counting a collection of models

I'm trying to get the count of different models and list them by company.
I have a collection of different models.
public function listAllRequets()
{
$requests = collect();
$terms = Termination::with('user.company')->where('default_status', 2)->get();
$deacs = LoaDeactivation::with('user.company')->where('manager_status', 2)->get();
$reacs = LoaReactivation::with('user.company')->where('manager_status', 2)->get();
// Use push() to collect them all in one collection
foreach ($terms as $term)
$requests->push($term);
foreach ($deacs as $deac)
$requests->push($deac);
foreach ($reacs as $reac)
$requests->push($reac);
return $requests;
}
In my index function I'm adding them to $requests.
To get the list of companies I'm grouping them using the groupBy() method.
public function index()
{
$requests = $this->listAllRequets();
$requestCompanies = $requests->groupBy(function($requests) {
return $requests->user->company->company_acronym;
});
In my view I have this:
<table class="table table-sm">
<thead class="thead-light">
<tr>
<th>Company</th>
<th class="text-center">Terms</th>
<th class="text-center">Deacs</th>
<th class="text-center">Reacs</th>
</tr>
</thead>
<tbody>
#foreach ($requestCompanies as $company => $requests)
<tr>
<td class="pt-3"><strong>{{ $company }}</strong></td>
#foreach ($requests as $request)
<td class="text-center">{{ $request-> }}</td>
#endforeach
</tr>
#endforeach
</tbody>
</table>
I need a way to get the count of each model by company.
My companies list out as expected but I'm not sure how to get the correct model count.
If you have relationships among your company and each request model (Termination, LoaDeactivation, LoaReactivation), wouldn't be easier to do that with a query at database level?
That seems a nice use case for with count method that eloquent provides:
Assuming the relations in the company model are called terminations, deactivations and reactivations, you could do:
public function index()
{
$companies = Company::withCount('terminations','deactivations','reactivations')->get();
// here pass $companies array to your view
}
Then in your view you can access the count for each type on each company:
<table class="table table-sm">
<thead class="thead-light">
<tr>
<th>Company</th>
<th class="text-center">Terms</th>
<th class="text-center">Deacs</th>
<th class="text-center">Reacs</th>
</tr>
</thead>
<tbody>
#foreach ($companies as $company)
<tr>
<td class="pt-3"><strong>{{ $company->name }}</strong></td>
<td class="text-center">{{ $company->terminations_count }}</td>
<td class="text-center">{{ $company->deactivations_count }}</td>
<td class="text-center">{{ $company->reactivations_count }}</td>
</tr>
#endforeach
</tbody>
</table>

Laravel 5 Search Multi attribute Error

I`m new to the Laravel 5.4 .i needed to develop multiple attributed Search function.Here is the error um getting .
Here is my registered.index.blade.php View
<div class="panel panel-default">
<div class="panel-body">
<table class="table table-striped">
<thead>
<th>Full Name</th>
<th>Name with initials</th>
<th>National ID Number</th>
<th>Date Of Birth</th>
</thead>
<tbody>
#foreach($items as $item)
<tr>
<td>{{ $item->full_name }}</td>
<td>{{ $item->name_with_initials }}</td>
<td>{{ $item->nic_no }}</td>
<td>{{ $item->date_of_birth }}</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
Here is the my Controller .
public function search_code(Request $request){
$query = $request->search;
$queryType = $request->institute; // 'id' or 'name'
$items = DB::table('registerdetails');
if($queryType == 'id'){
$items = $items->where('id', 'LIKE',"%$query%");
}
if($queryType == 'name'){
$items = $items->where('name', 'LIKE',"%$query%");
}
$items->get();
return view('registeredusers.index')->with('items',$items);
}
Can Anyone suggest me the solution for this error?
Change this:
$items->get();
To this:
$items = $items->get();
When you're doing just $items->get();, the $items variable has an instance of Query Builder and not query result.

Select List From Database With Parameter

Hi there i have some problem getting list from database using laravel 4.1
I have session that stored some value about companyid. Then i want to print the list to table based on the companyid itself. Let say i can access the session using {{ Session::get('name')}}
This is my controller index()
public function index($cid) {
$pengguna = User::where('id_company', '=', $cid)->get();
$pengguna->toarray();
$data = array(
'pengguna' => $pengguna,
'page' => 'master',
'index' => 0
);
return View::make('console.pengguna')->with($data);
}
then i want to print the data to table in view
#if($pengguna->count())
<table class="table table-striped table-bordered" id="table_pengguna_list">
<thead>
<tr>
<th>No</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Username</th>
<th>Email</th>
<th>Status</th>
<th>Last Login</th>
<th class="td-actions">Action</th>
</tr>
</thead>
<tbody>
#foreach ($pengguna as $pgn)
<tr>
<td>{{ $index++ }}</td>
<td>{{ $pgn->firstname }}</td>
<td>{{ $pgn->lastname }}</td>
<td>{{ $pgn->username }}</td>
<td>{{ $pgn->email }}</td>
<td>{{ $pgn->level }}</td>
<td>{{ $pgn->updated_at }}</td>
</tr>
#endforeach
</tbody>
</table>
....
how to pass the parameter from session to the controller then? so basically pass the {{ Session::get('name')}} to $cid in index controller.
thank you.
hi there i have found the solution, just place refactor the index controller to;
public function index() {
$cid = Session::get('name');
$pengguna = User::where('id_company', '=', $cid)->get();
$pengguna->toarray();
$data = array(
'pengguna' => $pengguna,
'page' => 'master',
'index' => 0
);
return View::make('console.pengguna')->with($data);
}

How do I prevent repetition in my Laravel app?

I am currently working on a new large app and I am trying to ensure I implement best practices from the start. I am new to Laravel so one question I have is how can I limit repetition throughout my app.
As an example I currently have a resource controller for an admin section that makes a view like so:
public function index()
{
// $data will be passed to the view
$data = array(
'pageTitle' => 'Manage Products',
'btn' => array(
'title' => 'Add product',
'url' => 'admin.catalog.product.create',
)
);
return View::make('catalog::product.index', $data)->with('products', Product::all());
}
My view file looks likes so:
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>SKU</th>
<th>Price</th>
<th>Qty</th>
<th>Created</th>
<th><i class="icon-cog"></i></th>
</tr>
</thead>
<tbody>
#foreach ($products as $product)
<tr>
<td>{{ $product->pid }}</td>
<td>{{ $product->name }}</td>
<td>{{ $product->sku }}</td>
<td>{{ Currency::display($product->price) }}</td>
<td>{{ $product->quantity }}</td>
<td>{{ Dates::showTimeAgo($product->created_at) }}</td>
<td>
Edit
{{ Form::open(array('route' => array('admin.catalog.product.destroy', $product->pid), 'method' => 'delete', 'data-confirm' => 'Are you sure?')) }}
<button type="submit" href="{{ URL::route('admin.catalog.product.destroy', $product->pid) }}" class="btn btn-danger btn-mini">Delete</button>
{{ Form::close() }}
</td>
</tr>
#endforeach
</tbody>
Is there a way that I can just use the one view file for all admin tables and pass what columns I want for the header and body through the controller instead of hard coding this in the view like above?
I know I can pass the $data array but not sure how to go about passing the columns I want through this. Any ideas or suggestions would be much appreciated.
I don't think this really is a question regarding Laravel, but hey, here we go.
You could add functions to your models to map column names to your values.
public function getColumns()
{
return array(
'ID' => 'pid',
'Name' => 'name',
....
);
}
public function getColumnData()
{
$columns = $this->getColumns();
$records = [];
foreach ($columns as $column) {
if ('name' == $column) {
$data = '' . $product->name . '';
} if else (..) {
...
} else {
$data = $this->{$column};
}
}
return $records;
}
And your view would become something like this:
<thead>
<tr>
#foreach ($records->first()->getColumns() as $column)
<th>{{ $column->name }}</th>
#endforeach
</tr>
</thead>
<tbody>
#foreach ($records->all() as $record)
<tr>
#foreach ($record->getColumnData() as $data)
<td>{{ $data }}</td>
#endforeach
</tr>
#endforeach
</tbody>
I would like this
View:
<table>
<thead>
<tr>
#foreach ($records[0] as $k => $v)
<th>{{ ucwords(str_replace('_', ' ', $k)) }}</th>
#endforeach
</tr>
</thead>
<tbody>
#foreach ($records as $record)
<tr>
#foreach ($record as $col)
<td>{{ $col }}</td>
#endforeach
</tr>
#endforeach
</tbody>
</table>
Controller: (Using getColumns helper function)
$users = User::all();
// In the first array, just pass the fields
// you want to get, second one is data array
$data['records'] = getColumns(array('id', 'username', 'email'), $users->toArray());
return View::make('user.users', $data);
Or, you may use it like this
$users = User::all()->toArray();
// In this example, I want to show only
// username, first_name and last_name
$records = getColumns(array('username', 'first_name', 'last_name'), $users);
return View::make('user.users')->with('records', $records);
This is a helper function, it's possible to use this from any model/controller
function getColumns($keys, $result)
{
$records = array();
foreach ($result as $row) {
$record = array();
foreach ($row as $k => $v) {
if(in_array($k, $keys)) $record[$k] = $v;
}
$records[] = $record;
}
return $records;
}
I'm using helper function because, I can use it with any model and it's in my filters.php file, you can put it anywhere. Actually, I have a file custom_helpers.php file in app folder where filters.php and at the end of my filters.php file, I've this
include "custom_helpers.php";
In this custom_helpers.php I've this helper function with other functions. Here is an example with screenshot
$users = User::take(5)->get()->toArray();
$records = getColumns(array('username', 'first_name', 'last_name'), $users);
return View::make('user.users')->with('records', $records);
Screen Shot:
Thanks for all the responses. I actually ended up using a package created by Rob Gordijn. Works great for me and prevents a lot of repetition. You can get this package at the URl below:
https://github.com/RobGordijn/Bamboo

Categories