Laravel 5.4 Nested Loop with Grouped dataset - php

"Filters" table looks like following:
id | group | label | value
----+----------+-------------------+----------------
12 | deadline | 1 to 3 days | 1 AND 3
14 | price | Any | 0
15 | price | Less than 1000 | 0 AND 1000
16 | price | 1000 to 10000 | 1000 AND 10000
22 | location | Any | 0
23 | location | New York | newyork
24 | location | California | california
25 | location | Alabama | alabama
I need to show chunk of "label" under the "group".
My controller:
public function index(){
$filters = Filters::all();
return view('frontend.request', compact('filters'));
}
My view has:
<?php foreach ($filters as $filter) { ?>
<div class="panel panel-default">
<b>{{ $filter->group }}</b>
<div id="collapseOne1" class="panel-collapse collapse in">
<div class="panel-body">
<div class="checkbox">
<label><input type="checkbox" name="{{ $filter->group }}" value="{{ $filter->any }}">{{ $filter->label }}</label>
</div>
</div>
</div>
</div>
<?php } ?>
I want to show all labels under the group within one box and so on. The above codes create different boxes for each label which is not right.
I believe, its got to be nested loop but I'm having difficult writing it on Laravel. Any idea how it should be?
Note: This thread gives partial answer but we don't know chunk size in my case: Laravel 5.1 - Nested Loop - Blade Templating

You could use Laravel's groupBy() collection method;
https://laravel.com/docs/5.4/collections#method-groupby
Controller:
public function index(){
$filters = Filters::all();
$groups = $filters->groupBy('group');
return view('frontend.request', compact('groups'));
}
View:
#foreach ($groups as $group => $filters)
<div class="panel panel-default">
<b>{{ $group }}</b>
#foreach($filters as $filter)
<div id="collapseOne1" class="panel-collapse collapse in">
<div class="panel-body">
<div class="checkbox">
<label><input type="checkbox" name="{{ $filter->group }}" value="{{ $filter->any }}">{{ $filter->label }}</label>
</div>
</div>
</div>
#endforeach
</div>
#endforech

Related

How to return images sequentially inside a "for loop"?

My view displays collections from four different tables. $redtable is my longest collection.
#for ($i = 0; $counter < $redtable->count(); $i++)
<div>
{{ $red->slice($i, 1)->first()?->content }}
{{ $green->slice($i, 1)->first()?->content }}
{{ $blue->slice($i, 1)->first()?->content }}
{{ $gray->slice($i, 1)->first()?->content }}
<div>
#endfor
My image table:
+----+------------------------------------+-------------------------+--------------+
| id | image | imageable_type | imageable_id |
+----+------------------------------------+-------------------------+--------------+
| 1 | /path/redtable/image.png | App\Models\Red | 1 |
| 2 | /path/greentable/image.png | App\Models\Green | 1 |
| 3 | /path/blue/image1.png | App\Models\Blue | 1 |
| 4 | /path/blue/image2.png | App\Models\Blue | 1 |
| 5 | /path/blue/image3.png | App\Models\Blue | 1 |
| 6 | /path/blue/image4.png | App\Models\Blue | 1 |
| 7 | /path/blue/image5.png | App\Models\Blue | 1 |
| 8 | /path/gray/image.png | App\Models\Gray | 2 |
+----+------------------------------------+-------------------------+--------------+
My Controller:
class ColorsController extends Controller
{
public function index()
{
$red = \App\Models\Red::with('polymorphicRelationship')->limit(3)->orderby('id', 'desc')->get();
$green = \App\Models\Green::with('polymorphicRelationship')->limit(3)->orderby('id', 'desc')->get();
$blue = \App\Models\Blue::with('polymorphicRelationship')->limit(3)->orderby('id', 'desc')->get();
$gray = \App\Models\Gray::with('polymorphicRelationship')->limit(3)->orderby('id', 'desc')->get();
return view('home.colors', [
'red' => $red,
'green' => $green,
'blue' => $blue,
'gray' => $gray
]);
}
How to display the images of the "Model Blue" table in the view.
I did a test using $picture->first()?->polymorphicRelationship()->first()->image, but it only displays the image of the first line of the table.
#for ($i = 0; $counter < $red->count(); $i++)
<div class="general">
{{ $red->slice($i, 1)->first()?->content }}
{{ $green->slice($i, 1)->first()?->content }}
{{ $blue->slice($i, 1)->first()?->content }}
<div class="slide">
<!-- First slide image -->
{{ $blue->polymorphicRelationship->image1 }}
<!-- Second slide image -->
{{ $blue->polymorphicRelationship->image1 }}
<!-- Third slide image -->
{{ $blue->polymorphicRelationship->image1 }}
<!-- Fourth slide image -->
{{ $blue->polymorphicRelationship->image1 }}
<!-- Fifth slide image -->
{{ $blue->polymorphicRelationship->image1 }}
</div>
{{ $graytable->slice($i, 1)->first()?->content }}
</div>
#endfor
Assumming the relationship is defined as a polymorphic one to many, you can just add another loop.
Also you can replace slice($i, 1)->first() with get($i).
#for ($i = 0; $counter < $red->count(); $i++)
<div class="general">
{{ $red->get($i)?->content }}
{{ $green->get($i)?->content }}
{{ $blue->get($i)?->content }}
<div class="slide">
#foreach ($blue->polymorphicRelationship as $image)
{{ $image->image }}
#endforeach
</div>
{{ $graytable->get($i)?->content }}
</div>
#endfor

multi level subcategory in laravel

i want to show categories list on selectbox with tree structure (multi level subcategory)
similar this:
-electronic
--camera
---sumsung
---- other subcategory
---- ...
---lg
-art
table structure:
+----+------------+-----------+
| id | name | parent_id |
+----+------------+-----------+
| 1 | electronic | 0 |
+----+------------+-----------+
| 2 | arts | 0 |
+----+------------+-----------+
| 3 | camera | 1 |
+----+------------+-----------+
| 4 | sumsung | 3 |
+----+------------+-----------+
| 4 | lg | 3 |
+----+------------+-----------+
Category model:
public function children()
{
return $this->hasMany(self::class, 'parent_id', 'id');
}
public function parent()
{
return $this->belongsTo(self::class, 'parent_id');
}
and this return only category and 1 level subcategories
<select>
#foreach($data as $categories)
<optgroup label="{{ $categories->name }}">
#foreach($categories->children as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
#endforeach
</optgroup>
#endforeach
</select>
how to show multi level subcategory?
Well, here I didn't followed your approach by putting the categories in a select box, but instead I have chosen to depict it via nested unordered lists, but you can find a way to make it work for you in select box too.
To tackle multilevel category rendering, you can use a recursive approach. Here, I have created a blade template file namely categories.blade.php the code is as below:
categories.blade.php
<!-- Displaying the current category -->
<li value="{{ $category->id }}">{{ $category->name}}
<!-- If category has children -->
#if (count($category->children) > 0)
<!-- Create a nested unordered list -->
<ul>
<!-- Loop through this category's children -->
#foreach ($category->children as $sub)
<!-- Call this blade file again (recursive) and pass the current subcategory to it -->
#include('subcategories', ['category' => $sub])
#endforeach
</ul>
#endif
</li>
Now, in your parent blade template file, you can include the categories.blade.php file in a way to loop through your categories and display them.
...
<!-- Start an unoredered list -->
<ul>
<!-- Loop through each category -->
#foreach ($categories as $category)
<!-- Include subcategories.blade.php file and pass the current category to it -->
#include('subcategories', ['category' => $category])
#endforeach
<ul>
...
Here is an example that worked for me using the above technique:
Note 1: based on my example, the categories.blade.php file and the parent blade file are assumed to be in the same folder, if you decide to put them in different folder, make sure to put the correct path in the #include statement in the parent blade file.
Note 2: As per this: https://www.w3.org/TR/html401/interact/forms.html#h-17.6, you cannot put nested optgroup tags inside one another, so I suggest you find another way to display your select box.

Laravel Model Count By Relationship

I have an eCommerce site with a Product model and a ProductCategory model. I currently show products on the page from the Product model but would like to be able to get a list of all the categories with products in the current model and how many products are in each category. I can get the overall count but can't figure out how to get the list of categories being shown and how many results per category have been returned.
Product Model
Product_ID
Product_Name
Product_Description
Category_ID (Many-To-1: ProductCategory.Category_ID
ProductCategory Model
Category_ID
Category_Name
Currently, I access the results in the blade using...
#foreach($products->chunk(3) as $row)
<div class="item-row">
#foreach($row as $product)
<div class="item item-thumbnail" style="height: 250px;">
<a href="product_detail.html" class="item-image">
#if(empty($product->Images{0}->original_image))
<img style="width: 100px; height: 100px;"
src="https://example.com/100x100/d3d3d3/fff.gif&text=No+Image"
alt="" />
#else
<img style="width: 100px; height: 100px;"
src="https://cdn.example.com.au/products/{{$product->id}}/{{$product->Images{0}->original_image}}"
alt="" />
#endif
</a>
<div class="item-info">
<h4 class="item-title">
<a href="/store/{{$category->alias}}/{{$product->alias}}">
{{$product->product_name}}
</a>
</h4>
<p class="item-desc"> </p>
#if(empty($product->special_price))
<div class="item-price">
${{$product->normal_price}}
</div>
#else
<div class="item-price">
${{$product->special_price}}
</div>
<div class="item-discount-price">
${{$product->normal_price}}
</div>
#endif
</div>
</div>
#endforeach
</div>
#endforeach
And would like to be able to generate a list of all the categories with products displayed as...
#foreach($products->categories as $category)
<li>
{{$category->category_name}} ({{$category->count}})
</li>
#endforeach
All from within the same model.
Additional
If it helps clarify I don't want the model to change drastically in that I still want to be able to access the products in the model from the blade template as is currently done but would like to also be able to pull a list of categories such as the below example...
| Product_ID | Product_Name | Category_ID |
| ---------- | ------------ | ----------- |
| 1 | Product 1 | 1 |
| 2 | Product 2 | 1 |
| 3 | Product 3 | 2 |
| Category ID | Category Name |
| ----------- | ------------- |
| 1 | Category 1 |
| 2 | Category 2 |
And wind up with the following table on my page to show the product categories being shown in the results...
| Category Name | # Products |
| ------------- | ---------- |
| Category 1 | 2 |
| Category 2 | 1 |
It would be super helpful if you provided the code where you query the products and categories.
But here's essentially what you need to do. You need to make use of ->withCount(..):
$products = Product::with([
'categories' => function ($query) {
// Adds count of category-related products
$query->withCount('products as count');
},
])->get();
And then this would work in your view:
#foreach($products as $product)
#foreach($product->categories as $category)
<li>{{$category->category_name}} ({{$category->count}})</li>
#endforeach
#endforeach

Making a category menu with its subcategories getting data from DB and PHP?

I am willing to do a dropdown (or a list, it doesn't matter) with categories and subcategories getting directly the data from the database.
The order should be:
CATEGORY 1
-- Subcategory 1
-- Subcategory 2
-- Subcategory 3
-- ...
CATEGORY 2
-- Subcategory 1
-- ...
...
And so on even adding future categories and subcategories.
I am using MVC and this is my code this far:
View:
<?php foreach ( $datoCategorias as $categorias ) { ?>
<div class="col">
<div class="dropdown">
<button class="col btn btn-secondary" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<?php echo $categorias['NAME'] ?></button>
<div class=" col dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="index.php?controller=products&action=category&id="></a>
</div>
</div>
</div>
<?php } ?>
Index.php:
if ($_GET['action'] == "category") {
$controller = new productos_controller();
$controller->category();
}
Controller:
function category() {
$categorias = new productos_models();
$datoCategorias=$categorias->get_categorias();
require_once("views/products.php");
}
Model:
public function get_categorias(){
$categorias=$this->db->query("select * from CATEGORY;");
while($listaCategorias=$categorias->fetch_assoc()){
$this->cats[]=$listaCategorias;
}
return $this->cats;
}
Database table CATEGORY:
| ID | NAME | PARENTCATEGORY |
| 1 | CAT1 | null |
| 2 | CAT2 | null |
| 3 | CAT3 | null |
| 4 | SUB1 | 1 |
| 5 | SUB1 | 2 |
The problem is: How I should do the foreach or foreach'es to make the result look like the order I said before because I only managed to show the category's name.

How to show menu dynamically in Laravel

I'm trying to show menu in laravel dynamically.
I have two table, One holds Main Category and other one Holds Sub category
Here is the structure of Category table
----------------------------------
| id | title | slug | type |
| 1 | title1 | slug1 | Android |
| 2 | title2 | slug2 | Android |
| 3 | title3 | slug3 | Android |
| 4 | title4 | slug4 | Ubuntu |
| 5 | title5 | slug5 | Ubuntu |
----------------------------------
Sub Category Structure
-----------------------------------------------
| id | title | slug | category_of|
| 1 | title1 | slug1 | 1 |
| 2 | title2 | slug2 | 1 |
| 3 | title3 | slug3 | 1 |
| 4 | title4 | slug4 | 2 |
| 5 | title5 | slug5 | 1 |
-----------------------------------------------
Here is What I've tried
<?php
$category = App\Models\Menu::where('categories.type', 'Android')
->select('categories.*', 'sub_category.slug as sub_slug', 'sub_category.title')
->join('sub_category', 'sub_category.category_of', '=', 'categories.id')
->get();
?>
#foreach ($category as $value)
<li class="inner-dropdown-item">
<p>
{{ucwords(str_replace('-', ' ', $value->slug))}}
</p>
</li>
<li class="inner-dropdown-item">
{{ucwords(str_replace('-', ' ', $value->sub_slug))}}
</li>
#endforeach
The Problem I'm facing is, it is duplicating main category every time due to foreach loop, for e.g
<li class="inner-dropdown-item">
<p>
Android
</p>
</li>
<li class="inner-dropdown-item">
Calendars
</li>
<!-- /INNER DROPDOWN ITEM -->
<!-- /This Below Android category should not be shown again -->
<li class="inner-dropdown-item">
<p>
Android
</p>
</li>
<li class="inner-dropdown-item">
Database Abstractions
</li>
As you see it is duplicating main category every time sub category is shown. How can i show Main category Once and then all sub category following under it
I have another Template which has different menu HTML Structure
<!-- MENU ITEM -->
<li class="menu-item sub">
<a href="#">
Designer
<!-- SVG ARROW -->
<svg class="svg-arrow">
<use xlink:href="#svg-arrow"></use>
</svg>
<!-- /SVG ARROW -->
</a>
<div class="content-dropdown">
<!-- FEATURE LIST BLOCK -->
<?php $m_des = ''; ?>
#foreach ($design_category as $des_value)
#if($m_des != $des_value->slug)
<div class="feature-list-block">
<a href="{{ Config::get('constants.url.BASE_URL') }}category/{{$des_value->slug}}/">
<h6 class="feature-list-title">{{ucwords(str_replace('-', ' ', $des_value->slug))}}</h6></a>
<hr class="line-separator">
<?php $m_des = $des_value->slug; ?>
#endif
<!-- FEATURE LIST -->
<ul class="feature-list">
<li class="feature-list-item">
{{ucwords(str_replace('-', ' ', $des_value->sub_slug))}}
</li>
</ul>
<!-- /FEATURE LIST -->
</div>
#endforeach
</div>
</li>
<!-- /MENU ITEM -->
It is generating ul and div again and again which causes html errors
There may be a better solution for it. But you can try this. Do order by categories.id then in loop check main category is printed last time or not
<?php
$category = App\Models\Menu::where('categories.type', 'Android')
->select('categories.*', 'sub_category.slug as sub_slug', 'sub_category.title')
->join('sub_category', 'sub_category.category_of', '=', 'categories.id')
->orderBy('categories.id');
->get();
$latest_category = "";
?>
#foreach ($category as $value)
<?php if($latest_category != $value->slug){ ?>
<li class="inner-dropdown-item">
<p>
{{ucwords(str_replace('-', ' ', $value->slug))}}
</p>
</li>
<?php
$latest_category = $value->slug;
} ?>
<li class="inner-dropdown-item">
{{ucwords(str_replace('-', ' ', $value->sub_slug))}}
</li>
#endforeach
EDIT
<div class="content-dropdown">
<!-- FEATURE LIST BLOCK -->
<?php $m_des = '';
$end_div = '';
?>
#foreach ($design_category as $des_value)
#if($m_des != $des_value->slug)
{{$end_div}}
<div class="feature-list-block">
<a href="{{ Config::get('constants.url.BASE_URL') }}category/{{$des_value->slug}}/">
<h6 class="feature-list-title">{{ucwords(str_replace('-', ' ', $des_value->slug))}}</h6></a>
<hr class="line-separator">
<?php $m_des = $des_value->slug;
$end_div = "</div>";
?>
#endif
<!-- FEATURE LIST -->
<ul class="feature-list">
<li class="feature-list-item">
{{ucwords(str_replace('-', ' ', $des_value->sub_slug))}}
</li>
</ul>
<!-- /FEATURE LIST -->
#endforeach
{{$end_div}}
</div>

Categories