You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否为Bokeh的Select/MultiSelect组件添加搜索过滤功能?

Adding Search Filter to Bokeh's Select and MultiSelect Components

Absolutely—this is a super common pain point when working with large datasets, and Bokeh gives you all the tools to build this seamlessly. Let's break down how to implement search functionality for both Select and MultiSelect components:

For Single Select Component

The core idea is pairing your Select with a TextInput search box, then using a CustomJS callback to filter options in real-time based on user input. We'll also store the full list of original options so we can revert back when the search box is cleared.

Here's a complete working example:

from bokeh.models import Select, TextInput, CustomJS
from bokeh.layouts import column
from bokeh.plotting import show, figure
import pandas as pd

# Simulate your 500+ column dataset
data = pd.DataFrame({f"Column_{i}": range(10) for i in range(500)})
all_columns = list(data.columns)

# Create search input and select component
search_input = TextInput(placeholder="Search columns...", title="Filter:")
select = Select(options=all_columns, value=all_columns[0], title="Select Column:")

# CustomJS callback to filter options
callback = CustomJS(args=dict(select=select, search_input=search_input, original_options=all_columns), code="""
    const search_term = search_input.value.toLowerCase();
    // Filter options to match search term (case-insensitive)
    const filtered = original_options.filter(opt => opt.toLowerCase().includes(search_term));
    // Update select options—avoid empty list if no matches
    select.options = filtered.length > 0 ? filtered : original_options;
    // Reset selected value if it's no longer in filtered list
    if (!filtered.includes(select.value)) {
        select.value = filtered[0] || original_options[0];
    }
""")

# Link search input changes to the callback
search_input.js_on_change("value", callback)

# Optional: Add a plot to demonstrate selection works
p = figure()
p.line(x=range(10), y=data[select.value])
# Update plot when selection changes
select.js_on_change("value", CustomJS(args=dict(p=p, data=data), code="""
    p.renderers[0].data_source.data.y = data[cb_obj.value];
"""))

# Show the final layout
show(column(search_input, select, p))

For MultiSelect Component

The implementation is nearly identical—we just adjust the callback to handle the multi-select's selected values properly. Here's how to adapt it:

from bokeh.models import MultiSelect, TextInput, CustomJS
from bokeh.layouts import column
from bokeh.plotting import show
import pandas as pd

data = pd.DataFrame({f"Column_{i}": range(10) for i in range(500)})
all_columns = list(data.columns)

search_input = TextInput(placeholder="Search columns...", title="Filter:")
multi_select = MultiSelect(options=all_columns, value=[all_columns[0], all_columns[1]], title="Select Columns:")

callback = CustomJS(args=dict(multi_select=multi_select, search_input=search_input, original_options=all_columns), code="""
    const search_term = search_input.value.toLowerCase();
    const filtered = original_options.filter(opt => opt.toLowerCase().includes(search_term));
    multi_select.options = filtered.length > 0 ? filtered : original_options;
    
    // Keep only selected values that are still in the filtered list
    const updated_selected = multi_select.value.filter(val => filtered.includes(val));
    // Fallback to first two filtered options if no selections remain
    multi_select.value = updated_selected.length > 0 ? updated_selected : filtered.slice(0, 2);
""")

search_input.js_on_change("value", callback)

show(column(search_input, multi_select))

Extra Tips

  • Case Sensitivity: Remove the toLowerCase() calls if you want case-sensitive search matches.
  • Bokeh Server: If you're using Bokeh Server, you can replace CustomJS with a Python callback instead—great if you need to integrate with other backend logic. The filtering logic stays the same, just written in Python.
  • Empty State: The code ensures the component never has an empty option list, but you can tweak this if you prefer to show nothing when there are no matches.

内容的提问来源于stack exchange,提问作者SivaM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:14:34