How to make menu and submenu dynamic Laravel - php

I want to make menu and submenu dynamic .I made menu with their link but unable to make submenu,please help me my database structure
table name:menu
id menu_name url timestamps
table:sub_menu
id submenu_name link menu_id timestamps
my query is like this
public function menu()
{
$sql=\DB::table('menu')->rightjoin('sub_menu','menu.id','=','sub_menu.menu_id')
->select('submenu_name','link','url','menu_id','menu_name','menu.id')->get();
return view('products.show.menu',compact('sql'));
}
view
<ul>
#foreach($sql as $key => $nav)
#if($key > 0)
<li>
{{$nav->menu_name}}
#if (count($nav->submenu_name) > 0 )
<ul>
#foreach($nav->submenu_name as $child)
<li>{{$child->submenu_name}}</li>
#endforeach
#endif
</ul>
</li>
#endif
#endforeach
</ul>

Have you set up models for these tables? Your query will return multiple rows for each menu/submenu combination, meaning you can't just iterate over it as you are. There's no need to use the query builder here.
Assuming your models are set up as follows (you will need to check the namespace used in the relationships):
class Menu extends Eloquent
{
protected $table = 'menu';
public function submenu()
{
return $this->hasMany('App\SubMenu');
}
}
class SubMenu extends Eloquent
{
protected $table = 'sub_menu';
public function menu()
{
return $this->belongsTo('App\Menu');
}
}
In your controller, you can do:
public function menu()
{
$menu = Menu::with('submenu')->get();
return view('products.show.menu', compact('menu'));
}
Then in your view:
<ul>
#foreach($menu as $menuItem)
<li>
{{ $menuItem->menu_name }}
#if( ! $menuItem->submenu->isEmpty())
<ul>
#foreach($menuItem->submenu as $subMenuItem)
<li>{{ $subMenuItem->submenu_name }}</li>
#endforeach
</ul>
#endif
</li>
#endforeach
</ul>

You can use it without controller
`#foreach(App\Menu::get() as $menuItem)
#if( ! $menuItem->submenu->isEmpty() )
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
{{ $menuItem->menu_name }}
</a>
#else
<li>
{{ $menuItem->menu_name }}
#endif
#if( ! $menuItem->submenu->isEmpty())
<ul class="dropdown-menu" role="menu">
#foreach($menuItem->submenu as $subMenuItem)
<li>{{ $subMenuItem->submenu_name }}</li>
#endforeach
</ul>
#endif
</li>
#endforeach`

Related

How do I customize the pagination items in this Laravel 8 application?

I am working on a blogging application in Laravel 8.
The ArticlesController controller I have this method to display the paginated articles:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\ArticleCategory;
use App\Models\Article;
use App\Models\Comment;
class ArticlesController extends FrontendController {
// Articles per page
protected $per_page = 12;
public function index(Request $request) {
// Search query
$qry = $request->input('search');
$articlesQuery = Article::where('title', 'like', '%' . $qry . '%')
->orWhere('short_description', 'like', '%' . $qry . '%')
->orWhere('content', 'like', '%' . $qry . '%');
// Search results count
if ($qry) {
$article_count = $articlesQuery->count();
}
$articles = $articlesQuery->orderBy('id', 'desc')->paginate($this->per_page);
$featured_articles = Article::where('featured', 1)->orderBy('id', 'desc')->get();
return view('themes/' . $this->theme_directory . '/templates/index',
array_merge($this->data, [
'search_query' => $qry,
'articles' => $articles,
'featured_articles' => $featured_articles,
'article_count' => $article_count ?? null
])
);
}
}
The pagination, in the plain HTML template, looks like this:
<nav class="pgn">
<ul>
<li>
<a class="pgn__prev" href="#0">Prev</a>
</li>
<li><a class="pgn__num" href="#0">1</a></li>
<li><span class="pgn__num current">2</span></li>
<li><a class="pgn__num" href="#0">3</a></li>
<li><span class="pgn__num dots">…</span></li>
<li><a class="pgn__num" href="#0">4</a></li>
<li>
<a class="pgn__next" href="#0">Next</a>
</li>
</ul>
</nav>
The goal
The goal is to keep the pagination structure above, in Laravel's Blade.
The problem
The code below works for the "Next" and "Prev" buttons, but not the links in between.
<nav class="pgn">
<ul>
<li>
<a class="pgn__prev" href="{{ $articles->withQueryString()->previousPageUrl() }}">Prev</a>
</li>
{!! $articles->withQueryString()->links() !!}
<li>
<a class="pgn__next" href="{{ $articles->withQueryString()->nextPageUrl() }}">Next</a>
</li>
</ul>
</nav>
Questions
What causes this bug?
What is the easiest fix?
To create a custom pagination, I'd recommend to make use of a custom "view".
Basically, what would you have to do (which you have already done), is define a limit, and then basically do the following:
you create your view file (which will be the custom paginator) - name it however you want to name it. I'll name it custom.blade.php
This view has to be created after running the command: php artisan vendor:publish --tag=laravel-pagination
here you can find a bit more in the documentation about it: https://laravel.com/docs/9.x/pagination#customizing-the-pagination-view
#if ($paginator->onFirstPage())
<li class="disabled"><span>← Previous</span></li>
#else
<li>
<a class="pgn__prev" href="{{ $articles->withQueryString()->previousPageUrl() }}">Prev</a>
</li>
#endif
#foreach ($elements as $element)
#if (is_string($element))
<li class="disabled"><span>{{ $element }}</span></li>
#endif
#if (is_array($element))
#foreach ($element as $page => $url)
#if ($page == $paginator->currentPage())
<li class="active my-active"><span>{{ $page }}</span></li>
#else
<li>{{ $page }}</li>
#endif
#endforeach
#endif
#endforeach
#if ($paginator->hasMorePages())
<li>
<a class="pgn__next" href="{{ $articles->withQueryString()->nextPageUrl() }}">Next</a>
</li>
#else
<li class="disabled"><span>Next</span></li>
#endif
And finally, on the view where you want to make use of the custom pagination:
{{ $articles->links(‘path.pagination.custom') }}
(just make sure to have the correct path)
edit: It's a bit hard for me to give a definitive answer without looking at the project itself, but I hope this at least helps somehow.

I got an error while creating sub menu in my database mysql

I am new to laravel. I want to create submenu for my website using the eloquent. However it gives me and error saying that
Base table or view not found: 1146 Table 'shopping.sub_menus' doesn't exist (SQL: select * from sub_menus where sub_menus.menu_id = 1 and sub_menus.menu_id is not null)
my model menu
Menu.php
class Menu extends Model
{
public function submenu()
{
return $this->hasMany(SubMenu::class);
}
}
// SubMenu Model
class SubMenu extends Model
{
public function menu()
{
return $this->belongsTo(Menu::class);
}
}
and below is blade
side-nav.blade.php
<ul>
#foreach ($menu as $_menu)
<li>
<a href="{{ route($_menu->route) }}" id={{ $_menu->id }} class="side-menu">
#if ($_menu->submene->count())
<ul>
#foreach ($_menu->submenu as $_submenu)
<li><a href="{{ route($_menu->route) }}" id={{ $_menu->id }}>{{$_submenu->$_menu}} </a></li>#endforeach
<div class="side-menu__icon"> <i data-feather={{ $_menu->icon_name }}></i> </div>
<div class="side-menu__title"> {{ $_menu->menu_name }} </div>
</a>
</li>
#endforeach

How to pass parameter to model function from view?

I have tree structure of categories. Now I have to display only that categories which is not applied in a particular business.
Code in Controller
public function edit($id)
{
try
{
$id=Crypt::decrypt($id);
$business=Business::findOrFail($id);
$business_contact_details=BusinessContactDetails::where('business_id',$id)->select('contact_no','id')->get();
$business_working_hours=BusinessWorkingHours::where('business_id',$id)->get();
$business_categories=BusinessCategories::leftJoin('categories','categories.id','=','category_id')->where('business_id',$id)->where('categories.parent_id','0')->select('categories.name as name','approved','category_id','business_categories.id as id')->get();
$categories = Categories::where('parent_id', '=', 0)->get();
return view('admin.businesses.edit',compact('business','business_contact_details','business_working_hours','categories','category_counter','business_categories'));
}
catch(DecryptException $e)
{
return view('errors.404');
}
}
Code in Model
public function subChilds(){
return $this->hasMany('App\Categories','parent_id','id')->whereNotExists(function($query){
$query->from('business_categories')->whereRaw('categories.id=business_categories.category_id')->where('business_id',2);
});
}
Code in edit View
<div class="col-md-6">
<ul id="tree1">
#foreach($categories as $category)
<li>
<input type="checkbox" value="{{$category->id}}" name="categories[]">
{{ $category->name }}
#if(count($category->subChilds($business->id)))
#include('admin.businesses.manageChildSub',['subChilds' => $category->subChilds($business->id)])
#endif
</li>
#endforeach
</ul>
</div>
Code in manageChildSub View
<ul>
#foreach($subChilds as $child)
<li>
<input type="checkbox" value="{{$child->id}}" name="categories[]">
{{ $child->name }}
#if(count($child->childs))
#include('manageChildSub',['subChilds' => $child->subChilds($business->id)])
#endif
</li>
#endforeach
</ul>
Here, You can see that I have passed business_id as 2, but I have to pass it as my current business ID. Basically I need to call the model function with ID.
After changing to this, I am not getting any subcategories.
You can try this:
public function subChilds($business_id){
return $this->hasMany('App\Categories','parent_id','id')
->whereNotExists(function($query) use ($business_id){
$query->from('business_categories')
->whereRaw('categories.id=business_categories.category_id')
->where('business_id', $business_id);
});
}

Get datas from one to many (inverse ) relation laravel

I have 2 models 'Trips.php'
public function region()
{
return $this->belongsTo('App\Region');
}
Region.php
public function trips()
{
return $this->hasMany('App\Trip');
}
I'm trying to show the trips that are in one one specific region. For example: I have a region named Lake Side and I want to show all trips that are in Lake Side region in list.
I tried the following:
In controller:
$trips = Trip::all();
In view:
#foreach($trips as $trip)
<li><a href="#">
{{$trip->region->name}}</a>
<ul class="dropdown">
<li><a href="#">
{{$trip->title}}</a>
</li>
</ul>
</li>
#endforeach
This gives me region name and trip name but repeats region name if more than one trip is made in same region.
And tried another way around (inverse):
<ul class="dropdown">
#foreach($regions as $region)
<li><a href="#">
{{$region->tour->title}}</a>
</li>
#endforeach
</ul>
And getting error Trying to get property of non-object
One way to do that is to use whereHas():
$trips = Trip::whereHas('region', function($q) use ($regionName) {
$q->where('name', $regionName);
})->get();
Pass $trips and $regionName to the view:
#foreach ($trips as $trip)
<li>{{ $regionName }}
<ul class="dropdown">
<li><a href="#">
{{ $trip->title }}</a>
</li>
</ul>
</li>
#endforeach
Alternatively, you can use eager loading:
$region = Region::where('name', $regionName)->with('trips')->first();
And in the view:
#foreach ($region->trips as $trip)
<li>{{ $region->name }}
<ul class="dropdown">
<li><a href="#">
{{ $trip->title }}</a>
</li>
</ul>
</li>
#endforeach
By getting trips with regions, what you're essentially getting is every trip with a region property.
Instead do the reverse Region::with('trips')->where('id', $regionId)->get() and you'll get regions with their trips. So now every region result has a trips property which contains many trips.
Alternatively don't use eager load. So Region::firstOrFail($regionId) then just use $region->trips.
And you can loop through them like
// Can print region here
#foreach($region->trips as $trip)
// Can print region's trips here
#endforeach

Dynamic menu laravel

I am starting with laravel, and made an integration with bootstrap. I want to make a menu bar to access to the information by year, the menu is made I this way to the view
<li class="dropdown-submenu">
<a tabindex="-1" href="#">2007</a>
<ul class="dropdown-menu">
<li><a tabindex="-1" href="<?php echo url('/convenios/2007/registrar', $parameters = array(), $secure = null); ?>">Registrar</a></li>
<li>Consultar</li>
</ul>
</li>
I made this on a view called base.blade.php, there is a better way to make the menus or I made this in the right way?
menus table
id - parent_id - title - url - order - created_at - updated_at
Make Menu model
class Menu extends Model
{
public $timestamps = false;
protected $table = 'menus';
protected $fillable = array('parent_id','title','url','order');
public function parent()
{
return $this->belongsTo('App\Menu', 'parent_id');
}
public function children()
{
return $this->hasMany('App\Menu', 'parent_id');
}
}
in View
#foreach(App\Menu::orderBy('order','asc')->get() as $menuItem)
#if( $menuItem->parent_id == 0 )
<li {{ $menuItem->url ? '' : "class=dropdown" }}>
<a href="{{ $menuItem->children->isEmpty() ? $menuItem->url : "#" }}"{{ $menuItem->children->isEmpty() ? '' : "class=dropdown-toggle data-toggle=dropdown role=button aria-expanded=false" }}>
{{ $menuItem->title }}
</a>
#endif
#if( ! $menuItem->children->isEmpty() )
<ul class="dropdown-menu" role="menu">
#foreach($menuItem->children as $subMenuItem)
<li>{{ $subMenuItem->title }}</li>
#endforeach
</ul>
#endif
</li>
#endforeach
you can make controller as you like
this way i spent all day trying to get this working code, when i finished i decide to search for anybody ask for that issue
Have fun :)

Categories