Instantly share code, notes, and snippets.
Created
March 25, 2023 18:39
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save anjanesh/01a08da165853a063ff05f8ef4874920 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<title>Flowbite Dynamic Nav Menu</title> | |
<link rel="stylesheet" href="styles.css" /> | |
</head> | |
<body> | |
<script> | |
let BASE_URL = window.location.origin + window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/")); | |
let menu_items = [ | |
{ id: "overview", name: "Overview", url: "#", show: true, count: "0", keywords: "" }, | |
{ id: "pages", name: "Pages", sub_menu_items: | |
[ | |
{ id: "pages", name: "Pages Default", url: "#", show: true, count: "0", keywords: "" }, | |
{ id: "pages-settings", name: "Settings", url: "", show: true, count: "0", keywords: "control panel" }, | |
{ id: "pages-kanban", name: "Kanban", url: "#", show: true, count: "0", keywords: "scrum" }, | |
{ id: "pages-calendar", name: "Calendar", url: "#", show: true, count: "0", keywords: "day,month,year" }, | |
], | |
keywords: "calendar", show: true, count: "0", expand: false | |
}, | |
{ id: "customers", name: "Customers", url: "", show: true, count: "0", keywords: "people" }, | |
{ id: "projects", name: "Projects", url: "#", show: true, count: "45", keywords: "workspace" }, | |
{ id: "work-experience", name: "Work Experience", url: "#", show: true, count: "10", keywords: "resume,bio data" }, | |
{ id: "reporting", name: "Reporting", url: "#", show: "6", count: "0", keywords: "logs,presentation" }, | |
{ id: "portfolios", name: "Portfolios", url: "#", show: true, count: "5", keywords: "presentation" }, | |
{ id: "contacts", name: "Contacts", url: "#", show: true, count: "0", keywords: "people" }, | |
{ id: "sales", name: "Sales", sub_menu_items: | |
[ | |
{ id: "sales-products", name: "Products", url: "", show: true, count: "0", keywords: "" }, | |
{ id: "sales-billing", name: "Billing", url: "", show: true, count: "0", keywords: "" }, | |
{ id: "sales-invoice", name: "Invoice", url: "#", show: true, count: "0", keywords: "" }, | |
], | |
keywords: "service,orders", show: true, count: "0", expand: false | |
}, | |
{ id: "messages", name: "Messages", url: "#", show: true, count: "0", keywords: "email" }, | |
{ id: "downloads", name: "Downloads", url: "#", show: true, count: "0", keywords: "zip" }, | |
]; | |
let global_filterMenuItems = (menus, value) => | |
{ | |
if (value == '') | |
{ | |
for (let i = 0; i < menus.length; i++) | |
{ | |
menus[i].show = true; | |
menus[i].expand = false; | |
if (menus[i].sub_menu_items) | |
{ | |
for (let j = 0; j < menus[i].sub_menu_items.length; j++) | |
{ | |
menus[i].sub_menu_items[j].show = true; | |
} | |
} | |
} | |
return; | |
} | |
let indexes = []; | |
for (let i = 0; i < menus.length; i++) | |
{ | |
// Single array of keywords for searching | |
let allKeywords = [menus[i].name.toLowerCase(), menus[i].keywords.toLowerCase().split(',')].flat(); | |
if (allKeywords.some(s => s.includes(value.toLowerCase()))) | |
{ | |
menus[i].show = true; | |
} | |
else if (menus[i].sub_menu_items) | |
{ | |
for (let j = 0; j < menus[i].sub_menu_items.length; j++) | |
{ | |
menus[i].show = false; | |
} | |
for (let j = 0; j < menus[i].sub_menu_items.length; j++) | |
{ | |
// Single array of keywords for searching | |
let subAllKeywords = [menus[i].sub_menu_items[j].name.toLowerCase(), menus[i].sub_menu_items[j].keywords.toLowerCase().split(',')].flat(); | |
if (subAllKeywords.some(s => s.includes(value.toLowerCase()))) | |
{ | |
menus[i].show = true; | |
menus[i].sub_menu_items[j].show = true; | |
menus[i].expand = true; | |
} | |
else | |
{ | |
menus[i].sub_menu_items[j].show = false; | |
} | |
} | |
} | |
else | |
{ | |
menus[i].show = false; | |
} | |
} | |
} | |
</script> | |
<div class="container"> | |
<aside class="flex top-0 left-0 w-64 h-full" aria-label="Sidebar"> | |
<div class="sm:hidden overflow-y-auto z-30 py-5 px-3 w-16 h-full bg-white border-r border-gray-200 dark:bg-gray-800 dark:border-gray-700"> | |
<ul class="space-y-2"> | |
<li> | |
<a href="#" class="flex items-center p-2 text-gray-400 rounded-lg transition duration-75 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<svg aria-hidden="true" class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"></path></svg> | |
</a> | |
</li> | |
<li> | |
<a href="" class="flex items-center p-2 text-gray-400 rounded-lg transition duration-75 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<svg fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clip-rule="evenodd"></path></svg> | |
</a> | |
</li> | |
<li> | |
<a href="#" class="flex items-center p-2 text-gray-400 rounded-lg transition duration-75 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M2 10a8 8 0 018-8v8h8a8 8 0 11-16 0z"></path><path d="M12 2.252A8.014 8.014 0 0117.748 8H12V2.252z"></path></svg> | |
</a> | |
</li> | |
<li> | |
<a href="#" class="flex items-center p-2 text-gray-400 rounded-lg transition duration-75 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M8.707 7.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l2-2a1 1 0 00-1.414-1.414L11 7.586V3a1 1 0 10-2 0v4.586l-.293-.293z"></path><path d="M3 5a2 2 0 012-2h1a1 1 0 010 2H5v7h2l1 2h4l1-2h2V5h-1a1 1 0 110-2h1a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V5z"></path></svg> | |
</a> | |
</li> | |
<li> | |
<a href="#" class="flex items-center p-2 text-gray-400 rounded-lg transition duration-75 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-700"> | |
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd"></path></svg> | |
</a> | |
</li> | |
</ul> | |
</div> | |
<div x-data="{ BASE_URL: BASE_URL, menus: menu_items, message: '', filterMenuItems(event, menus) { global_filterMenuItems(menus, event.target.value); } }" class="hidden sm:block overflow-y-auto py-4 px-3 h-full bg-white border-r border-gray-200 dark:bg-gray-800 dark:border-gray-700"> | |
<a href="#" class="flex items-center pl-2 mb-5"> | |
<img src="https://flowbite.com/docs/images/logo.svg" class="mr-3 h-6 sm:h-8" alt="Flowbite Logo" /> | |
<span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white">Flowbite</span> | |
</a> | |
<form class="flex items-center my-3"> | |
<label for="simple-search" class="sr-only">Search</label> | |
<div class="relative w-full"> | |
<div class="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none"> | |
<svg aria-hidden="true" class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd"></path></svg> | |
</div> | |
<input x-on:input.debounce="filterMenuItems($event, menus)" type="search" id="simple-search" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full pl-10 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="eg: type in people" required> | |
</div> | |
</form> | |
<ul id="ul-left-menu" class="space-y-2"> | |
<template x-for="menu in menus"> | |
<li> | |
<template x-if="menu.show && !menu.sub_menu_items"> | |
<a :href="menu.url" class="flex items-center p-2 w-full text-base font-normal text-gray-900 rounded-lg transition duration-75 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700"> | |
<img class="w-6 h-6" :src="await(await fetch(BASE_URL + '/icons/' + menu.id +'.svg')).url"/> | |
<span x-text="menu.name" class="flex-1 ml-3 whitespace-nowrap"></span> | |
<span x-text="menu.count" class="inline-flex justify-center items-center w-5 h-5 text-xs font-semibold text-primary-800 bg-primary-100 rounded-full dark:bg-primary-200 dark:text-primary-800"></span> | |
</a> | |
</template> | |
<template x-if="menu.show && menu.sub_menu_items"> | |
<div> | |
<button type="button" class="flex items-center p-2 w-full text-base font-normal text-gray-900 rounded-lg transition duration-75 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700" @click="menu.expand = !menu.expand"> | |
<img class="w-6 h-6" :src="await(await fetch(BASE_URL + '/icons/' + menu.id +'.svg')).url"/> | |
<span x-text="menu.name" class="flex-1 ml-3 text-left whitespace-nowrap"></span> | |
<svg aria-hidden="true" class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg> | |
</button> | |
<ul :id="'sub-' + menu.id" x-show="menu.expand" class="py-2 pt-0 space-y-2"> | |
<template x-for="sub_menu in menu.sub_menu_items"> | |
<template x-if="sub_menu.show"> | |
<li> | |
<a :href="sub_menu.url" x-text="sub_menu.name" class="flex items-center p-2 pl-9 w-full text-base font-normal text-gray-900 rounded-lg transition duration-75 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700"></a> | |
</li> | |
</template> | |
</template> | |
</ul> | |
</div> | |
</template> | |
</li> | |
</template> | |
</ul> | |
<ul class="pt-5 my-5 space-y-2 border-t border-gray-200 dark:border-gray-700"> | |
<li> | |
<a href="#" class="flex items-center p-2 text-base font-normal text-gray-900 rounded-lg transition duration-75 hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-white group"> | |
<svg aria-hidden="true" class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z"></path><path fill-rule="evenodd" d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm3 4a1 1 0 000 2h.01a1 1 0 100-2H7zm3 0a1 1 0 000 2h3a1 1 0 100-2h-3zm-3 4a1 1 0 100 2h.01a1 1 0 100-2H7zm3 0a1 1 0 100 2h3a1 1 0 100-2h-3z" clip-rule="evenodd"></path></svg> | |
<span class="ml-3">Docs</span> | |
</a> | |
</li> | |
<li> | |
<a href="#" class="flex items-center p-2 text-base font-normal text-gray-900 rounded-lg transition duration-75 hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-white group"> | |
<svg aria-hidden="true" class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-2 0c0 .993-.241 1.929-.668 2.754l-1.524-1.525a3.997 3.997 0 00.078-2.183l1.562-1.562C15.802 8.249 16 9.1 16 10zm-5.165 3.913l1.58 1.58A5.98 5.98 0 0110 16a5.976 5.976 0 01-2.516-.552l1.562-1.562a4.006 4.006 0 001.789.027zm-4.677-2.796a4.002 4.002 0 01-.041-2.08l-.08.08-1.53-1.533A5.98 5.98 0 004 10c0 .954.223 1.856.619 2.657l1.54-1.54zm1.088-6.45A5.974 5.974 0 0110 4c.954 0 1.856.223 2.657.619l-1.54 1.54a4.002 4.002 0 00-2.346.033L7.246 4.668zM12 10a2 2 0 11-4 0 2 2 0 014 0z" clip-rule="evenodd"></path></svg> | |
<span class="ml-3">Help</span> | |
</a> | |
</li> | |
</ul> | |
<div id="alert-update" class="p-4 mb-3 rounded-lg bg-primary-50 dark:bg-primary-900" role="alert"> | |
<div class="flex justify-between items-center mb-3"> | |
<span class="bg-purple-100 text-purple-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded">Beta</span> | |
<button type="button" class="inline-flex p-1 w-6 h-6 rounded-lg text-primary-700 bg-primary-50 focus:ring-2 focus:ring-primary-400 hover:bg-primary-100 dark:bg-primary-900 dark:text-primary-300 dark:hover:bg-primary-800 dark:hover:text-primary-200" data-dismiss-target="#alert-update" aria-label="Close"> | |
<span class="sr-only">Dismiss</span> | |
<svg aria-hidden="true" class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg> | |
</button> | |
</div> | |
<div class="mb-3 text-sm font-light text-primary-700 dark:text-primary-300"> | |
Preview the new Flowbite v2.0! You can turn the new features off for a limited time in your settings page. | |
</div> | |
<a href="#" class="text-sm font-medium underline text-primary-700 dark:text-primary-300 hover:no-underline"> | |
Turn new features off | |
</a> | |
</div> | |
</div> | |
</aside> | |
</div> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/1.6.4/flowbite.min.js"></script> | |
<script src="https://unpkg.com/alpinejs@3.12.0/dist/cdn.min.js"></script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Demo at https://anjanesh.s3.amazonaws.com/demo/alpine/flowbite-dynamic-nav-menu.html