侧边栏搜索插件
SidebarSearch 会在你输入的时候实时过滤侧边栏菜单。匹配的条目保留下来,其他的一律隐藏,而任何包含匹配项的子菜单都会被展开,这样结果才真的看得见。清空输入框后,菜单会精确恢复到原来的样子——包括之前哪些子菜单是展开的。
本页侧边栏里的搜索框就是一个现成的实例。
用法
该插件通过 data 属性激活。
Data 属性
把
data-lte-toggle="sidebar-search"
加到一个文本输入框上。把它放在
.sidebar-wrapper 外面,这样菜单在它下面滚动时,它能保持不动。
<div class="sidebar-search" role="search">
<label for="sidebar-search-input" class="visually-hidden">Filter menu</label>
<input
type="search"
id="sidebar-search-input"
class="form-control form-control-sm"
placeholder="搜索菜单…"
autocomplete="off"
data-lte-toggle="sidebar-search"
data-lte-target="#navigation"
>
<p class="fs-7 text-secondary mt-2 mb-0" data-lte-search-empty role="status" hidden>
没有匹配到页面。
</p>
</div>
| 属性 | 说明 |
|---|---|
data-lte-toggle="sidebar-search" |
把这个输入框标记为菜单筛选器。 |
data-lte-target |
要筛选的菜单的选择器。可选——不加的话,就用该输入框所在的
.app-sidebar 里的 .sidebar-menu。
|
data-lte-search-empty |
可选元素,只在查询没有任何匹配时显示。给它加上
role="status",这样结果会被播报出来。
|
用 type="search" 是值得的:浏览器自带的清除按钮会触发
input 事件,所以能免费帮你把菜单恢复原状。在输入框里按
ESC 也是同样的效果。
匹配规则
-
匹配不区分大小写,而且在
.nav-link的文字里任意位置都能匹配,不只是开头。 - 只要有一个后代匹配,父级就会保留下来,并且会被展开以露出那个匹配项。
- 如果父级自己的名字就匹配上了,那它整棵子树都会保留,所以展开它绝不会是死路一条。
-
筛选期间,
.nav-header的区块标题会被隐藏,因为它们所标注的那些分组已经不再完整了。
事件
| 事件 | 描述 |
|---|---|
filtered.lte.sidebar-search |
每次筛选执行完后,在输入框上触发。event.detail 是
{ query, matches };当筛选被清空时,matches
为 -1。
|
document.addEventListener("filtered.lte.sidebar-search", event => {
console.log(event.detail.query, event.detail.matches)
})
调用方式
import { SidebarSearch } from "admin-lte"
const input = document.querySelector('[data-lte-toggle="sidebar-search"]')
const search = SidebarSearch.getOrCreateInstance(input)
search.search("layout") // 筛选菜单
search.clear() // 恢复它
search.dispose() // 恢复后,再删除该实例
方法
| 方法 | 返回值 | 描述 |
|---|---|---|
search(term) |
void |
把菜单筛选到只显示匹配
term 的条目。传入空字符串或纯空白字符时,会自动调用
clear()。
|
clear() |
void |
取消隐藏所有条目,并把每个子菜单恢复到搜索前的展开状态。 |
dispose() |
void |
先清空筛选,再把该实例从注册表中移除。 |
SidebarSearch.getInstance(el) |
SidebarSearch | null |
返回某个元素对应的现有实例,如果没有则返回 null。 |
SidebarSearch.getOrCreateInstance(el) |
SidebarSearch |
返回现有实例,没有就新建一个。 |
构造函数不接受任何配置——目标菜单来自 data-lte-target。
注意事项
-
条目是用
hidden属性隐藏的,而不是加个类,所以它们会同时从无障碍树和布局里消失。你的 CSS 完全不需要知道有筛选这回事。 -
插件会在你敲下第一个键之前,先把每个子菜单的展开状态以及它的内联
display都拍个快照。这两样都重要:因为 Treeview 在滑动展开或收起菜单时会写入内联display,否则搜索之后这个内联样式会盖过.menu-open > .nav-treeview的规则。 -
因为搜索会重写
.menu-open,所以在筛选生效期间,别用你自己的代码去操作同一批子菜单——先把筛选清掉再说。 - 在迷你侧边栏模式下,这个输入框是隐藏的,因为一条窄窄的侧边栏里塞个文本输入框根本没法用。鼠标悬停时它会回来,连同它要筛选的那些标签一起显示。
-
两个监听器都委托在
document上,所以页面加载之后才渲染出来的侧边栏——比如 Turbo Frame 或客户端路由生成的——都不需要重新初始化。