diff options
| author | Maxim Milovanov <max@milovanov.info> | 2020-12-04 14:50:11 +0300 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-03-31 09:31:37 +0200 |
| commit | d915dd1c5809d7c2bb3679751cd5277571dcd9f7 (patch) | |
| tree | f8e3f09a829b720699f3be29b1696ac9c46324af /django | |
| parent | 7248afe12f40361870388ecdd7e0038eb0d58e47 (diff) | |
Fixed #32204 -- Added quick filter to admin's navigation sidebar.
Diffstat (limited to 'django')
| -rw-r--r-- | django/contrib/admin/static/admin/css/nav_sidebar.css | 22 | ||||
| -rw-r--r-- | django/contrib/admin/static/admin/js/nav_sidebar.js | 54 | ||||
| -rw-r--r-- | django/contrib/admin/templates/admin/nav_sidebar.html | 3 |
3 files changed, 79 insertions, 0 deletions
diff --git a/django/contrib/admin/static/admin/css/nav_sidebar.css b/django/contrib/admin/static/admin/css/nav_sidebar.css index f3c2fd8042..e62838d6e3 100644 --- a/django/contrib/admin/static/admin/css/nav_sidebar.css +++ b/django/contrib/admin/static/admin/css/nav_sidebar.css @@ -118,3 +118,25 @@ max-width: 100%; } } + +#nav-filter { + width: 100%; + box-sizing: border-box; + padding: 2px 5px; + margin: 5px 0; + border: 1px solid var(--border-color); + background-color: var(--darkened-bg); + color: var(--body-fg); +} + +#nav-filter:focus { + border-color: var(--body-quiet-color); +} + +#nav-filter.no-results { + background: var(--message-error-bg); +} + +#nav-sidebar table { + width: 100%; +} diff --git a/django/contrib/admin/static/admin/js/nav_sidebar.js b/django/contrib/admin/static/admin/js/nav_sidebar.js index efaa7214b8..d262c26bb2 100644 --- a/django/contrib/admin/static/admin/js/nav_sidebar.js +++ b/django/contrib/admin/static/admin/js/nav_sidebar.js @@ -36,4 +36,58 @@ main.classList.toggle('shifted'); }); } + + function initSidebarQuickFilter() { + 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(event) { + let filterValue = event.target.value; + if (filterValue) { + filterValue = filterValue.toLowerCase(); + } + if (event.key === 'Escape') { + filterValue = ''; + event.target.value = ''; // clear input + } + let matches = false; + for (const o of options) { + let displayValue = ''; + if (filterValue) { + if (o.title.toLowerCase().indexOf(filterValue) === -1) { + displayValue = 'none'; + } else { + matches = true; + } + } + // show/hide parent <TR> + o.node.parentNode.parentNode.style.display = displayValue; + } + if (!filterValue || matches) { + event.target.classList.remove('no-results'); + } else { + event.target.classList.add('no-results'); + } + localStorage.setItem('django.admin.navSidebarFilterValue', filterValue); + } + + const nav = document.getElementById('nav-filter'); + nav.addEventListener('change', checkValue, false); + nav.addEventListener('input', checkValue, false); + nav.addEventListener('keyup', checkValue, false); + + const storedValue = localStorage.getItem('django.admin.navSidebarFilterValue'); + if (storedValue) { + nav.value = storedValue; + checkValue({target: nav, key: ''}); + } + } + window.initSidebarQuickFilter = initSidebarQuickFilter; + initSidebarQuickFilter(); } diff --git a/django/contrib/admin/templates/admin/nav_sidebar.html b/django/contrib/admin/templates/admin/nav_sidebar.html index 32c5b8f839..0a185e604f 100644 --- a/django/contrib/admin/templates/admin/nav_sidebar.html +++ b/django/contrib/admin/templates/admin/nav_sidebar.html @@ -1,5 +1,8 @@ {% 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="search" id="nav-filter" + placeholder="{% translate 'Start typing to filter...' %}" + aria-label="{% translate 'Filter navigation items' %}"> {% include 'admin/app_list.html' with app_list=available_apps show_changelinks=False %} </nav> |
