mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-25 00:36:11 -06:00
Remove object type selector from search bar
This commit is contained in:
parent
4fff0996ab
commit
f69a13e05b
@ -15,21 +15,10 @@ LOOKUP_CHOICES = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def build_options(choices):
|
|
||||||
options = [{"label": choices[0][1], "items": []}]
|
|
||||||
|
|
||||||
for label, choices in choices[1:]:
|
|
||||||
items = []
|
|
||||||
|
|
||||||
for value, choice_label in choices:
|
|
||||||
items.append({"label": choice_label, "value": value})
|
|
||||||
|
|
||||||
options.append({"label": label, "items": items})
|
|
||||||
return options
|
|
||||||
|
|
||||||
|
|
||||||
class SearchForm(BootstrapMixin, forms.Form):
|
class SearchForm(BootstrapMixin, forms.Form):
|
||||||
q = forms.CharField(label='Search')
|
q = forms.CharField(
|
||||||
|
label='Search'
|
||||||
|
)
|
||||||
obj_types = forms.MultipleChoiceField(
|
obj_types = forms.MultipleChoiceField(
|
||||||
choices=[],
|
choices=[],
|
||||||
required=False,
|
required=False,
|
||||||
@ -43,15 +32,7 @@ class SearchForm(BootstrapMixin, forms.Form):
|
|||||||
widget=StaticSelect()
|
widget=StaticSelect()
|
||||||
)
|
)
|
||||||
|
|
||||||
options = None
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.fields['obj_types'].choices = search_backend.get_object_types()
|
self.fields['obj_types'].choices = search_backend.get_object_types()
|
||||||
|
|
||||||
def get_options(self):
|
|
||||||
if not self.options:
|
|
||||||
self.options = build_options(search_backend.get_object_types())
|
|
||||||
|
|
||||||
return self.options
|
|
||||||
|
BIN
netbox/project-static/dist/netbox.js
vendored
BIN
netbox/project-static/dist/netbox.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox.js.map
vendored
BIN
netbox/project-static/dist/netbox.js.map
vendored
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
import { initForms } from './forms';
|
import { initForms } from './forms';
|
||||||
import { initBootstrap } from './bs';
|
import { initBootstrap } from './bs';
|
||||||
import { initSearch } from './search';
|
import { initQuickSearch } from './search';
|
||||||
import { initSelect } from './select';
|
import { initSelect } from './select';
|
||||||
import { initButtons } from './buttons';
|
import { initButtons } from './buttons';
|
||||||
import { initColorMode } from './colorMode';
|
import { initColorMode } from './colorMode';
|
||||||
@ -20,7 +20,7 @@ function initDocument(): void {
|
|||||||
initColorMode,
|
initColorMode,
|
||||||
initMessages,
|
initMessages,
|
||||||
initForms,
|
initForms,
|
||||||
initSearch,
|
initQuickSearch,
|
||||||
initSelect,
|
initSelect,
|
||||||
initDateSelector,
|
initDateSelector,
|
||||||
initButtons,
|
initButtons,
|
||||||
|
@ -1,31 +1,4 @@
|
|||||||
import { getElements, findFirstAdjacent, isTruthy } from './util';
|
import { isTruthy } from './util';
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the display value and hidden input values of the search filter based on dropdown
|
|
||||||
* selection.
|
|
||||||
*
|
|
||||||
* @param event "click" event for each dropdown item.
|
|
||||||
* @param button Each dropdown item element.
|
|
||||||
*/
|
|
||||||
function handleSearchDropdownClick(event: Event, button: HTMLButtonElement): void {
|
|
||||||
const dropdown = event.currentTarget as HTMLButtonElement;
|
|
||||||
const selectedValue = findFirstAdjacent<HTMLSpanElement>(dropdown, 'span.search-obj-selected');
|
|
||||||
const selectedType = findFirstAdjacent<HTMLInputElement>(dropdown, 'input.search-obj-type');
|
|
||||||
const searchValue = dropdown.getAttribute('data-search-value');
|
|
||||||
let selected = '' as string;
|
|
||||||
|
|
||||||
if (selectedValue !== null && selectedType !== null) {
|
|
||||||
if (isTruthy(searchValue) && selected !== searchValue) {
|
|
||||||
selected = searchValue;
|
|
||||||
selectedValue.innerHTML = button.textContent ?? 'Error';
|
|
||||||
selectedType.value = searchValue;
|
|
||||||
} else {
|
|
||||||
selected = '';
|
|
||||||
selectedValue.innerHTML = 'All Objects';
|
|
||||||
selectedType.value = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show/hide quicksearch clear button.
|
* Show/hide quicksearch clear button.
|
||||||
@ -44,23 +17,10 @@ function quickSearchEventHandler(event: Event): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize Search Bar Elements.
|
|
||||||
*/
|
|
||||||
function initSearchBar(): void {
|
|
||||||
for (const dropdown of getElements<HTMLUListElement>('.search-obj-selector')) {
|
|
||||||
for (const button of dropdown.querySelectorAll<HTMLButtonElement>(
|
|
||||||
'li > button.dropdown-item',
|
|
||||||
)) {
|
|
||||||
button.addEventListener('click', event => handleSearchDropdownClick(event, button));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize Quicksearch Event listener/handlers.
|
* Initialize Quicksearch Event listener/handlers.
|
||||||
*/
|
*/
|
||||||
function initQuickSearch(): void {
|
export function initQuickSearch(): void {
|
||||||
const quicksearch = document.getElementById("quicksearch") as HTMLInputElement;
|
const quicksearch = document.getElementById("quicksearch") as HTMLInputElement;
|
||||||
const clearbtn = document.getElementById("quicksearch_clear") as HTMLButtonElement;
|
const clearbtn = document.getElementById("quicksearch_clear") as HTMLButtonElement;
|
||||||
if (isTruthy(quicksearch)) {
|
if (isTruthy(quicksearch)) {
|
||||||
@ -82,10 +42,3 @@ function initQuickSearch(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initSearch(): void {
|
|
||||||
for (const func of [initSearchBar]) {
|
|
||||||
func();
|
|
||||||
}
|
|
||||||
initQuickSearch();
|
|
||||||
}
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{# Base layout for the core NetBox UI w/navbar and page content #}
|
{# Base layout for the core NetBox UI w/navbar and page content #}
|
||||||
{% extends 'base/base.html' %}
|
{% extends 'base/base.html' %}
|
||||||
{% load helpers %}
|
{% load helpers %}
|
||||||
{% load search %}
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
|
||||||
{% comment %}
|
{% comment %}
|
||||||
@ -41,7 +40,7 @@ Blocks:
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex my-1 flex-grow-1 justify-content-center w-100">
|
<div class="d-flex my-1 flex-grow-1 justify-content-center w-100">
|
||||||
{% search_options request %}
|
{% include 'inc/searchbar.html' %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -53,7 +52,7 @@ Blocks:
|
|||||||
|
|
||||||
{# Search bar #}
|
{# Search bar #}
|
||||||
<div class="col-6 d-flex flex-grow-1 justify-content-center">
|
<div class="col-6 d-flex flex-grow-1 justify-content-center">
|
||||||
{% search_options request %}
|
{% include 'inc/searchbar.html' %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# Proflie/login button #}
|
{# Proflie/login button #}
|
||||||
|
6
netbox/templates/inc/searchbar.html
Normal file
6
netbox/templates/inc/searchbar.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<form class="input-group" action="{% url 'search' %}" method="get">
|
||||||
|
<input name="q" type="text" aria-label="Search" placeholder="Search" class="form-control" />
|
||||||
|
<button class="btn btn-primary" type="submit">
|
||||||
|
<i class="mdi mdi-magnify"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
@ -1,49 +0,0 @@
|
|||||||
<form class="input-group" action="{% url 'search' %}" method="get">
|
|
||||||
<input
|
|
||||||
name="q"
|
|
||||||
type="text"
|
|
||||||
aria-label="Search"
|
|
||||||
placeholder="Search"
|
|
||||||
class="form-control"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<input name="obj_types" hidden type="text" class="search-obj-type" />
|
|
||||||
|
|
||||||
<span class="input-group-text search-obj-selected">All Objects</span>
|
|
||||||
|
|
||||||
<button type="button" aria-expanded="false" data-bs-toggle="dropdown" class="btn dropdown-toggle">
|
|
||||||
<i class="mdi mdi-filter-variant"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<ul class="dropdown-menu dropdown-menu-end search-obj-selector">
|
|
||||||
{% for option in options %}
|
|
||||||
{% if option.items|length == 0 %}
|
|
||||||
<li>
|
|
||||||
<button class="dropdown-item" type="button" data-search-value="{{ option.value }}">
|
|
||||||
{{ option.label }}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
{% else %}
|
|
||||||
<li><h6 class="dropdown-header">{{ option.label }}</h6></li>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% for item in option.items %}
|
|
||||||
<li>
|
|
||||||
<button class="dropdown-item" type="button" data-search-value="{{ item.value }}">
|
|
||||||
{{ item.label }}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if forloop.counter != options|length %}
|
|
||||||
<li><hr class="dropdown-divider" /></li>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<button class="btn btn-primary" type="submit">
|
|
||||||
<i class="mdi mdi-magnify"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</form>
|
|
@ -1,18 +0,0 @@
|
|||||||
from typing import Dict
|
|
||||||
|
|
||||||
from django import template
|
|
||||||
|
|
||||||
from netbox.forms import SearchForm
|
|
||||||
|
|
||||||
register = template.Library()
|
|
||||||
search_form = SearchForm()
|
|
||||||
|
|
||||||
|
|
||||||
@register.inclusion_tag("search/searchbar.html")
|
|
||||||
def search_options(request) -> Dict:
|
|
||||||
|
|
||||||
# Provide search options to template.
|
|
||||||
return {
|
|
||||||
'options': search_form.get_options(),
|
|
||||||
'request': request,
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user