diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index bd8ae108c..f4ec02d6c 100644 Binary files a/netbox/project-static/dist/netbox.js and b/netbox/project-static/dist/netbox.js differ diff --git a/netbox/project-static/dist/netbox.js.map b/netbox/project-static/dist/netbox.js.map index f74047f4e..13c4a6bd2 100644 Binary files a/netbox/project-static/dist/netbox.js.map and b/netbox/project-static/dist/netbox.js.map differ diff --git a/netbox/project-static/src/netbox.ts b/netbox/project-static/src/netbox.ts index 465ecdf9f..1ff0c9ecb 100644 --- a/netbox/project-static/src/netbox.ts +++ b/netbox/project-static/src/netbox.ts @@ -6,7 +6,7 @@ import { initMessageToasts } from './toast'; import { initSpeedSelector, initForms } from './forms'; import { initRackElevation } from './buttons'; import { initClipboard } from './clipboard'; -import { initSearchBar } from './search'; +import { initSearchBar, initInterfaceFilter } from './search'; import { initGenerateKeyPair, initLockUnlock, initGetSessionKey } from './secrets'; import { getElements } from './util'; @@ -24,6 +24,7 @@ const INITIALIZERS = [ initGenerateKeyPair, initLockUnlock, initGetSessionKey, + initInterfaceFilter, ] as (() => void)[]; /** diff --git a/netbox/project-static/src/search.ts b/netbox/project-static/src/search.ts index 20cf0c99a..2f8670053 100644 --- a/netbox/project-static/src/search.ts +++ b/netbox/project-static/src/search.ts @@ -1,3 +1,5 @@ +import { getElements } from './util'; + interface SearchFilterButton extends EventTarget { dataset: { searchValue: string }; } @@ -35,3 +37,45 @@ export function initSearchBar() { } } } + +/** + * Initialize Interface Table Filter Elements. + */ +export function initInterfaceFilter() { + for (const element of getElements('input.interface-filter')) { + /** + * Filter on-page table by input text. + */ + function handleInput(event: Event) { + const target = event.target as HTMLInputElement; + // Create a regex pattern from the input search text to match against. + const filter = new RegExp(target.value); + + // Each row represents an interface and its attributes. + for (const row of getElements('table > tbody > tr')) { + // The data-name attribute's value contains the interface name. + const name = row.getAttribute('data-name'); + + // Find the row's checkbox and deselect it, so that it is not accidentally included in form + // submissions. + const checkBox = row.querySelector('input[type="checkbox"][name="pk"]'); + if (checkBox !== null) { + checkBox.checked = false; + } + + if (typeof name === 'string') { + if (filter.test(name)) { + // If this row matches the search pattern, but is already hidden, unhide it. + if (row.classList.contains('d-none')) { + row.classList.remove('d-none'); + } + } else { + // If this row doesn't match the search pattern, hide it. + row.classList.add('d-none'); + } + } + } + } + element.addEventListener('keyup', handleInput); + } +}