在 Dash 中突出显示 HTML.div 或 Dcc.Markdown 中的选定文本

Highlight selected text in HTML.div or Dcc.Markdown in Dash

我正在尝试在 Dash 中实现关键字搜索方法,如果用户键入某个关键字,它会在 HTML.div 或 dcc.Markdown 中突出显示。

我尝试使用 keyword 将关键字括在 dcc.Markdown 中,但这不是我要找的。同样出于某种原因,`` 并没有真正突出显示文本,而是让它看起来很小。

你可以使用 html.Mark 如果您将文本放在 html.Div 组件中。

你可以这样做:

import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output


app = dash.Dash(__name__)

text = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
"""

app.layout = html.Div(
    [
        html.Div(
            id="text-container",
            children=[html.Div(text)],
        ),
        dcc.Input(id="search-input"),
    ]
)


@app.callback(
    Output("text-container", "children"),
    Input("search-input", "value"),
    prevent_initial_call=True,
)
def search(search_value):
    output = html.Div([text])

    if search_value:
        sequences = text.split(search_value)
        i = 1
        while i < len(sequences):
            sequences.insert(i, html.Mark(search_value))
            i += 2

        output.children = sequences

    return output


if __name__ == "__main__":
    app.run_server()

所以上面的想法是创建一个回调,当你输入搜索时调用 值变化。当调用回调且搜索值不相等时 到一个空字符串我用搜索值作为分隔符拆分文本。

sequences = text.split(search_value)
# equals: ['\n', ' ipsum dolor sit amet, consectetur adipiscing elit.\n']
# if search_value equals: Lorem

所以现在我们有搜索值不匹配的文本序列。 在这些序列之间,我们可以放置匹配的序列 html.Mark函数包围的搜索值,即 while 循环在上面的例子中做了什么。

现在据我所知你不能这样做 Markdown 组件,因为它只需要字符串和 不是其他 Dash 组件。你可以这样做:

@app.callback(
    Output("text-container", "children"),
    Input("search-input", "value"),
    prevent_initial_call=True,
)
def search(search_value):
    new_text = text
    if search_value:
        new_text = text.replace(search_value, f"<mark>{search_value}</mark>")

    return dcc.Markdown(
        new_text,
        dangerously_allow_html=True,
    )

但是 documentation 说 以下关于 dangerously_allow_html:

A boolean to control raw HTML escaping. Setting HTML from code is risky because it's easy to inadvertently expose your users to a cross-site scripting (XSS) (https://en.wikipedia.org/wiki/Cross-site_scripting) attack.