summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorMaxim Milovanov <max@milovanov.info>2020-12-04 14:50:11 +0300
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-03-31 09:31:37 +0200
commitd915dd1c5809d7c2bb3679751cd5277571dcd9f7 (patch)
treef8e3f09a829b720699f3be29b1696ac9c46324af /django
parent7248afe12f40361870388ecdd7e0038eb0d58e47 (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.css22
-rw-r--r--django/contrib/admin/static/admin/js/nav_sidebar.js54
-rw-r--r--django/contrib/admin/templates/admin/nav_sidebar.html3
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>