Instantly share code, notes, and snippets.
Last active
December 4, 2020 11:53
-
Save MilovanovM/84ffbbec02391c1ba1771a3a6aee5797 to your computer and use it in GitHub Desktop.
A prototype for quick filtering sidebar items in django admin
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
.sticky { | |
position: sticky; | |
top: 0; | |
max-height: 100vh; | |
} | |
.toggle-nav-sidebar { | |
z-index: 20; | |
left: 0; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
flex: 0 0 23px; | |
width: 23px; | |
border-right: 1px solid #eaeaea; | |
background-color: #ffffff; | |
cursor: pointer; | |
font-size: 20px; | |
color: #447e9b; | |
padding: 0; | |
} | |
[dir="rtl"] .toggle-nav-sidebar { | |
border-left: 1px solid #eaeaea; | |
border-right: 0; | |
} | |
.toggle-nav-sidebar:hover, | |
.toggle-nav-sidebar:focus { | |
background-color: #f6f6f6; | |
} | |
#nav-sidebar { | |
z-index: 15; | |
flex: 0 0 275px; | |
left: -276px; | |
margin-left: -276px; | |
border-top: 1px solid transparent; | |
border-right: 1px solid #eaeaea; | |
background-color: #ffffff; | |
overflow: auto; | |
} | |
[dir="rtl"] #nav-sidebar { | |
border-left: 1px solid #eaeaea; | |
border-right: 0; | |
left: 0; | |
margin-left: 0; | |
right: -276px; | |
margin-right: -276px; | |
} | |
.toggle-nav-sidebar::before { | |
content: '\00BB'; | |
} | |
.main.shifted .toggle-nav-sidebar::before { | |
content: '\00AB'; | |
} | |
.main.shifted > #nav-sidebar { | |
left: 24px; | |
margin-left: 0; | |
} | |
[dir="rtl"] .main.shifted > #nav-sidebar { | |
left: 0; | |
right: 24px; | |
margin-right: 0; | |
} | |
#nav-sidebar .module th { | |
width: 100%; | |
overflow-wrap: anywhere; | |
} | |
#nav-sidebar .module th, | |
#nav-sidebar .module caption { | |
padding-left: 16px; | |
} | |
#nav-sidebar .module td { | |
white-space: nowrap; | |
} | |
[dir="rtl"] #nav-sidebar .module th, | |
[dir="rtl"] #nav-sidebar .module caption { | |
padding-left: 8px; | |
padding-right: 16px; | |
} | |
#nav-sidebar .current-app .section:link, | |
#nav-sidebar .current-app .section:visited { | |
color: #ffc; | |
font-weight: bold; | |
} | |
#nav-sidebar .current-model { | |
background: #ffc; | |
} | |
.main > #nav-sidebar + .content { | |
max-width: calc(100% - 23px); | |
} | |
.main.shifted > #nav-sidebar + .content { | |
max-width: calc(100% - 299px); | |
} | |
@media (max-width: 767px) { | |
#nav-sidebar, #toggle-nav-sidebar { | |
display: none; | |
} | |
.main > #nav-sidebar + .content, | |
.main.shifted > #nav-sidebar + .content { | |
max-width: 100%; | |
} | |
} | |
#nav-filter { | |
width: 100%; | |
box-sizing: border-box; | |
padding: 5px 16px; | |
margin: 5px 0; | |
border: none; | |
outline: none; | |
} | |
#nav-sidebar table { | |
width: 100%; | |
} |
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
{% load i18n %} | |
<button class="sticky toggle-nav-sidebar" id="toggle-nav-sidebar" aria-label="{% translate 'Toggle navigation' %}"></button> | |
<nav class="sticky" id="nav-sidebar"> | |
<input type="text" id="nav-filter" placeholder="Start typing a content name..."> | |
{% include 'admin/app_list.html' with app_list=available_apps show_changelinks=False %} | |
</nav> |
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
'use strict'; | |
{ | |
const toggleNavSidebar = document.getElementById('toggle-nav-sidebar'); | |
if (toggleNavSidebar !== null) { | |
const navLinks = document.querySelectorAll('#nav-sidebar a'); | |
function disableNavLinkTabbing() { | |
for (const navLink of navLinks) { | |
navLink.tabIndex = -1; | |
} | |
} | |
function enableNavLinkTabbing() { | |
for (const navLink of navLinks) { | |
navLink.tabIndex = 0; | |
} | |
} | |
const main = document.getElementById('main'); | |
let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen'); | |
if (navSidebarIsOpen === null) { | |
navSidebarIsOpen = 'true'; | |
} | |
if (navSidebarIsOpen === 'false') { | |
disableNavLinkTabbing(); | |
} | |
main.classList.toggle('shifted', navSidebarIsOpen === 'true'); | |
toggleNavSidebar.addEventListener('click', function() { | |
if (navSidebarIsOpen === 'true') { | |
navSidebarIsOpen = 'false'; | |
disableNavLinkTabbing(); | |
} else { | |
navSidebarIsOpen = 'true'; | |
enableNavLinkTabbing(); | |
} | |
localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen); | |
main.classList.toggle('shifted'); | |
}); | |
} | |
// init quick filter | |
(function() { | |
const options = []; | |
const navSidebar = document.getElementById('nav-sidebar'); | |
if (!navSidebar) { return; } | |
navSidebar.querySelectorAll('th[scope=row] a').forEach((container) => { | |
options.push({title: container.innerHTML, node: container}); | |
}); | |
function checkValue(e) { | |
let v = e.target.value; | |
if (v) { v = v.toLowerCase(); } | |
if (e.key === 'Escape') { v = ''; e.target.value = ''; } // clear input | |
for (const o of options) { | |
// show/hide parent <TR> | |
o.node.parentNode.parentNode.style.display = | |
(!v || o.title.toLowerCase().indexOf(v) !== -1) ? '' : 'none'; | |
} | |
} | |
const nav = document.getElementById('nav-filter'); | |
nav.addEventListener('change', checkValue, false); | |
nav.addEventListener('keyup', checkValue, false); | |
})(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment