Hello Dev.
Nowaday, i will provide an explanation for how can create dynamic multi level menu in laravel we will create instance of multi step dynamic menu in laravel you can simply to make many level dynamic menu in laravel. i will display parents and child menu with nested tree view structure in Laravel software.
on this article i simple create "menus" table and manage end level of parents and child menu with nested tree view structure in Laravel utility. i take advantage of jquery for make tree view layout and child relationship with menu model for hierarchical data. I also add form for create new menu in tree view. I additionally create dynamic drop down menu the use of bootstrap nav.
here following example step of multi level dynamic menu in laravel treeview.
we are going from scratch, So we require to get fresh Laravel application using bellow command, So open your terminal OR command prompt and run bellow command:
composer create-project --prefer-dist laravel/laravel blog
Database Configuration
In this step, we require to make database configuration, you have to add following details on your .env file.
- Database Username
- Database Password
- Database Name
In .env file also available host and port details, you can configure all details as in your system, So you can put like as bellow:
.env
DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
In this step we have to create migration and model for menus table using Laravel php artisan command, so first fire bellow command:
After this command you have to put bellow code in your migration file for create menus table.
/database/migrations/2021_09_01_112426_create_menus_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMenusTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('menus', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->integer('parent_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('menus');
}
}
Now we require to run migration be bellow command:
php artisan migrate
After you have to put bellow code in your model file for create Menu table.
/app/Menu.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Menu extends Model
{
protected $fillable = ['title','parent_id'];
public function childs() {
return $this->hasMany('App\Menu','parent_id','id') ;
}
}
In this is step we need to create route for tree menu show layout file, create menu for post method.
route and show dynamic menus.
/routes/web.php
Route::get('menus','MenuController@index');
Route::get('menus-show','MenuController@show');
Route::post('menus','MenuController@store')->name('menus.store');
here this step now we should create new controller as MenuController,So run bellow command for generate new controller
php artisan make:controller MenuController
now this step, this controller will manage menu layout and create menu with validation with post request,bellow content in controller file. i added three method in this controller as listed bellow:
1. index()
2. store()
3. show()
/app/Http/Controllers/MenuController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Menu;
class MenuController extends Controller
{
public function index(){
$menus = Menu::where('parent_id', '=', 0)->get();
$allMenus = Menu::pluck('title','id')->all();
return view('menu.menuTreeview',compact('menus','allMenus'));
}
public function store(Request $request)
{
$request->validate([
'title' => 'required',
]);
$input = $request->all();
$input['parent_id'] = empty($input['parent_id']) ? 0 : $input['parent_id'];
Menu::create($input);
return back()->with('success', 'Menu added successfully.');
}
public function show()
{
$menus = Menu::where('parent_id', '=', 0)->get();
return view('menu.dynamicMenu',compact('menus'));
}
}
In this step, we have to create menu folder in total four blade file as listed bellow:
1. menuTreeview.blade.php
2. manageChild.blade.php
3. dynamicMenu.blade.php
4. menusub.blade.php
This both blade file will help to render menu tree structure, so let's create both file view file and put bellow code.
/resources/views/menu/menuTreeview.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Multi Level Dynamic Menu In Laravel Treeview - meaningarticles.com</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<link href="/css/treeview.css" rel="stylesheet">
</head>
<body class="bg-dark">
<div class="container">
<div class="row">
<div class="col-md-10 offset-md-1 mt-4">
<div class="card">
<div class="card-header">
<h5>Multi Level Dynamic Menu In Laravel Treeview - meaningarticles.com</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h5 class="mb-4 text-center bg-success text-white ">Add New Menu</h5>
<form accept="{{ route('menus.store')}}" method="post">
@csrf
@if(count($errors) > 0)
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert">×</button>
@foreach($errors->all() as $error)
{{ $error }}<br>
@endforeach
</div>
@endif
@if ($message = Session::get('success'))
<div class="alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>{{ $message }}</strong>
</div>
@endif
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Title</label>
<input type="text" name="title" class="form-control">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Parent</label>
<select class="form-control" name="parent_id">
<option selected disabled>Select Parent Menu</option>
@foreach($allMenus as $key => $value)
<option value="{{ $key }}">{{ $value}}</option>
@endforeach
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-success">Save</button>
</div>
</div>
</form>
</div>
<div class="col-md-6">
<h5 class="text-center mb-4 bg-info text-white">Menu List</h5>
<ul id="tree1">
@foreach($menus as $menu)
<li>
{{ $menu->title }}
@if(count($menu->childs))
@include('menu.manageChild',['childs' => $menu->childs])
@endif
</li>
@endforeach
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="/js/treeview.js"></script>
</body>
</html>
here following include blade fille
/resources/views/menu/manageChild.blade.php
<ul>
@foreach($childs as $child)
<li>
{{ $child->title }}
@if(count($child->childs))
@include('manageChild',['childs' => $child->childs])
@endif
</li>
@endforeach
</ul>
After This both blade file will help to render dynamic drop down menu view file, so let's create both file view file and put bellow code.
/resources/views/menu/dynamicMenu.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://bootstrapthemes.co/demo/resource/bootstrap-4-multi-dropdown-hover-navbar/css/bootstrap-4-hover-navbar.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</head>
<body class="bg-dark">
<nav class="navbar navbar-expand-md navbar-light bg-light btco-hover-menu">
<a class="navbar-brand" href="#">meaningarticles.com</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav">
@foreach($menus as $menu)
<li class="nav-item dropdown">
<a class="nav-link {{ count($menu->childs) ? 'dropdown-toggle' :'' }}" href="https://bootstrapthemes.co" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ $menu->title }}
</a>
<ul class="dropdown-menu " aria-labelledby="navbarDropdownMenuLink">
@if(count($menu->childs))
@include('menu.menusub',['childs' => $menu->childs])
@endif
</ul>
</li>
@endforeach
</ul>
</div>
</nav>
<div style="position: absolute; left:2%; top:55%;">
<h2 class="bg-white p-2 shadow-lg rounded">Multi Level Dynamic Menu In Laravel Treeview - meaningarticles.com</h2>
</div>
</body>
</html>
here following include blade fille
/resources/views/menu/menusub.blade.php
@foreach($childs as $child)
<li><a class="dropdown-item {{ count($child->childs) ? 'dropdown-toggle' :'' }}" href="#" style="border:1px solid #ccc;">{{ $child->title }}</a>
@if(count($child->childs))
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="#" style="position: absolute;">
@include('menu.menusub',['childs' => $child->childs])
</a>
</li>
</ul>
@endif
</li>
@endforeach
In last step, we have to add one css file and one js file for treeview design. I simply use bootsnipp css and js code, so let's create css and js file as following path:
public/css/treeview.css
.tree, .tree ul {
margin:0;
padding:0;
list-style:none
}
.tree ul {
margin-left:1em;
position:relative
}
.tree ul ul {
margin-left:.5em
}
.tree ul:before {
content:"";
display:block;
width:0;
position:absolute;
top:0;
bottom:0;
left:0;
border-left:1px solid
}
.tree li {
margin:0;
padding:0 1em;
line-height:2em;
color:#369;
font-weight:700;
position:relative
}
.tree ul li:before {
content:"";
display:block;
width:10px;
height:0;
border-top:1px solid;
margin-top:-1px;
position:absolute;
top:1em;
left:0
}
.tree ul li:last-child:before {
background:#fff;
height:auto;
top:1em;
bottom:0
}
.indicator {
margin-right:5px;
}
.tree li a {
text-decoration: none;
color:#369;
}
.tree li button, .tree li button:active, .tree li button:focus {
text-decoration: none;
color:#369;
border:none;
background:transparent;
margin:0px 0px 0px 0px;
padding:0px 0px 0px 0px;
outline: 0;
}
This is require js file
public/js/treeview.js
$.fn.extend({
treed: function (o) {
var openedClass = 'glyphicon-minus-sign';
var closedClass = 'glyphicon-plus-sign';
if (typeof o != 'undefined'){
if (typeof o.openedClass != 'undefined'){
openedClass = o.openedClass;
}
if (typeof o.closedClass != 'undefined'){
closedClass = o.closedClass;
}
};
/* initialize each of the top levels */
var tree = $(this);
tree.addClass("tree");
tree.find('li').has("ul").each(function () {
var branch = $(this);
branch.prepend("");
branch.addClass('branch');
branch.on('click', function (e) {
if (this == e.target) {
var icon = $(this).children('i:first');
icon.toggleClass(openedClass + " " + closedClass);
$(this).children().children().toggle();
}
})
branch.children().children().toggle();
});
/* fire event from the dynamically added icon */
tree.find('.branch .indicator').each(function(){
$(this).on('click', function () {
$(this).closest('li').click();
});
});
/* fire event to open branch if the li contains an anchor instead of text */
tree.find('.branch>a').each(function () {
$(this).on('click', function (e) {
$(this).closest('li').click();
e.preventDefault();
});
});
/* fire event to open branch if the li contains a button instead of text */
tree.find('.branch>button').each(function () {
$(this).on('click', function (e) {
$(this).closest('li').click();
e.preventDefault();
});
});
}
});
/* Initialization of treeviews */
$('#tree1').treed();
Now we are ready to run our example so run bellow command so quick run:
php artisan serve
open bellow URL to create menu on your browser:
http://localhost:8000/menus
Now you can open bellow URL to dropdown nav menu on your browser:
http://localhost:8000/menus-show
i'm hoping it assist you to, thanks for visit my article if you like my article then proportion together with your friend and social platform.