Skip to content

Instantly share code, notes, and snippets.

@anjanesh
Created March 25, 2023 18:39
Show Gist options
  • Save anjanesh/01a08da165853a063ff05f8ef4874920 to your computer and use it in GitHub Desktop.
Save anjanesh/01a08da165853a063ff05f8ef4874920 to your computer and use it in GitHub Desktop.
<!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>
@anjanesh
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment