--- tags: Laravel, Navigation Bar, Sidebar --- # 將 Laravel 預設的 Navigation Bar 改為 Sidebar :::warning 先將 Laravel Project 裡的 `/resources/views/layouts/app.blade.php` 複製一份並貼到 `/resources/views/layouts` 資料夾作為備份之用。完成後,`/resources/views/layouts` 資料夾應該會有以下兩個檔案: ```! /resources/views/layouts app.blade copy.php app.blade.php ``` ::: :::success 因為以下步驟會把你原本寫好的程式碼覆蓋掉,所以如果你已經改動過自己 Laravel Project 裡的 `app.blade.php` 內容,請不要依以下步驟進行改動。 不過,還是可以參考以下程式碼,把它融入到你的程式碼裡。 ::: ## 1. 修改 `app.blade.php` 首先,我們先把 sidebar 所需要的 HTML 元素加到網頁頁面。打開 `/resources/views/layouts/app.blade.php`,把 `<div id="app">` 和 `</div>` 中間的程式碼裡刪掉, ```=html <div id="app"> 這裡面的程式碼都刪掉 </div> ``` 然後把以下程式碼貼到`<div id="app">` 和 `</div>` 裡 ```=html <nav class="navbar navbar-expand-md navbar-light bg-light shadow-sm"> <div class="container-fluid"> <a class="navbar-brand" href="{{ url('/') }}">&#5176;</a> <button class="navbar-toggler text-light" aria-label="{{ __('Toggle navigation') }}"> <span class="navbar-toggler-icon"></span> </button> </div> </nav> <main class="py-4 flex-grow-1 d-flex align-items-center order-2"> @yield('content') </main> {{-- Sidebar: display on either one of the following two conditions - (1) when screen width is equal to or greater than 992px; (2) a user presses/clicks on the navbar toggler when screen width is below 992px --}} <aside class="sidebar bg-secondary px-3 py-5"> <h2 class="px-3 mb-4 text-light">{{ __('Navigation Menu') }} <span class="close-nav pl-5">&#9587</span> </h2> <ul class="sidebar-nav p-0"> <a class="nav-link text-light" href="{{ url('/') }}">{{ __('Frontpage') }}</a> <!-- Authentication Links --> @guest <li class="nav-item"> <a class="nav-link text-light" href="{{ route('login') }}">{{ __('Login') }}</a> </li> @if (Route::has('register')) <li class="nav-item"> <a class="nav-link text-light" href="{{ route('register') }}">{{ __('Register') }}</a> </li> @endif @else {{-- @canany (['view', 'update', 'delete'], \App\Product::class) --}} <li class="nav-item"> <a class="nav-link text-light" href="#">{{ __('Product Information') }}</a> </li> {{-- @endcanany --}} {{-- @canany ('create', \App\Product::class) --}} <li class="nav-item"> <a class="nav-link text-light" href="#">{{ __('Create New Product') }}</a> </li> {{-- @endcanany --}} {{-- @canany (['create', 'view', 'update', 'delete'], \App\ProductPurchaseOrder::class) --}} <li class="nav-item"> <a class="nav-link text-light" href="#">{{ __('Purchase Orders') }}</a> </li> {{-- @endcanany --}} {{-- @canany (['create', 'view', 'update', 'delete'], \App\ProductSalesOrder::class) --}} <li class="nav-item"> <a class="nav-link text-light" href="#">{{ __('Sales Orders') }}</a> </li> {{-- @endcanany --}} {{-- @canany (['create', 'view', 'update', 'delete'], \App\ProductStock::class) --}} <li class="nav-item"> <a class="nav-link text-light" href="#">{{ __('Product Stocks') }}</a> </li> {{-- @endcanany --}} {{-- @canany (['create', 'view', 'update', 'delete'], \App\CanceledOrder::class) --}} <li class="nav-item"> <a class="nav-link text-light" href="#">{{ __('Canceled Orders') }}</a> </li> {{-- @endcanany --}} {{-- @canany (['create', 'view', 'update', 'delete'], \App\ProductSalesOrder::class) --}} <li class="nav-item"> <a class="nav-link text-light" href="#">{{ __('Add Cancel Order') }}</a> </li> {{-- @endcanany --}} {{-- @canany (['create', 'view', 'update', 'delete'], \App\ProductStock::class) --}} <li class="nav-item"> <a class="nav-link text-light" href="#">{{ __('Product Stock Locations') }}</a> </li> {{-- @endcanany --}} {{-- @canany (['create', 'view', 'update', 'delete'], \App\Vendor::class) --}} <li class="nav-item"> <a class="nav-link text-light" href="#">{{ __('Vendor Information') }}</a> </li> {{-- @endcanany --}} {{-- @canany (['create', 'view', 'update', 'delete'], \App\VendorBonus::class) --}} <li class="nav-item"> <a class="nav-link text-light" href="#">{{ __('Vendor Bonus System') }}</a> </li> {{-- @endcanany --}} {{-- @canany (['create', 'view', 'update', 'delete'], \App\User::class) --}} <li class="nav-item"> <a class="nav-link text-light" href="#">{{ __('User Management') }}</a> </li> {{-- @endcanany --}} <li class="nav-item"> <a class="nav-link text-light" href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();"> {{ __('Logout') }} </a> <form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none"> @csrf </form> </li> @endguest </ul> </aside> ``` ## 2. 修改 `app.scss` 接著,我們幫 sidebar 添加 css 讓它好看點。其實有部份 Sidebar 的風格已經用 Bootstrap class 加在上面 HTML 程式碼。打開 `/resources/sass/app.scss`,把以下程式碼貼到 `app.scss` 裡面最底部 ```=scss // transform Laravel's default nevigation bar into a sidebar #app { height: 100vh; position: relative; display: flex; @media screen and (max-width: 991px) { display: block; overflow: hidden; } // Sidebar styling .sidebar { width: auto; height: 100vh; .close-nav { cursor: pointer; display: none; } .sidebar-nav { list-style: none; // remove default html list style } // Hide sidebar when screen width is below 992px @media screen and (max-width: 991px) { position: absolute; top: 0; right: calc(-100% - 0px); // hide the sidebar by moving it completely out of the its parent wrapper to the right transition: .5s; .close-nav { display: inline-block; } } } // Display top navigation bar when screen width is below 992px, or otherwise, hide it .navbar { display: none; @media screen and (max-width: 991px) { display: flex; .navbar-toggler { display: inline-block; } } } } ``` ## 3. 修改 `app.js` 當頁面寬度少於 992px 時,Sidebar 會隱藏起來。用戶需要按 Navigation Bar 上的漢堡標,Sidebar 才會顯示。這個動作需要 JavaScript 的協作。打開 `/resources/js/app.js`,把以下程式碼貼到 `app.js` 裡面最底部 ```=javascript /** * Toggling sidebar when screen width is below 992px */ const navBarToggler = document.querySelector('.navbar-toggler'); const sideBar = document.querySelector('.sidebar'); const closeNavMenu = document.querySelector('.close-nav'); // listen to click event of the navbar toggler navBarToggler.addEventListener('click', function(){ // display sidebar by moving it back to the inside of its parent wrapper from the right sideBar.style.right = 0; // listen to click event of the close navigation menu button closeNavMenu.addEventListener('click', function(){ // hide the sidebar by moving it completely out of the its parent wrapper to the right sideBar.style.right = (sideBar.offsetWidth * -1) + 'px'; }); }); ``` ## 4. 執行 `npm run dev` 修改完上面第 2 和第 3 步的 `app.scss` 和 `app.js`,記得要先存檔。然後在 VSCode 的 Terminal 裡執行 ``` npm run dev ``` 把修改好的程式碼分別推送到 `/public/css/app.css` 和 `/public/js/app.js`。我們的 `app.blade.php` 預設是直著連著這兩個檔案的。 ## 5. 完成後效果 完成以上步驟後,打開頁面應該要看到以下效果。 ![Sidebar效果](https://i.imgur.com/iMJTebs.gif)