使用按钮使用破折号在下拉菜单中设置值

Use a button to set values in drop down using dash

我想知道是否可以使用按钮将多个值设置为下拉值。我想要做的是过滤下拉列表,然后如果用户按下提交按钮,所有包含 search_value 的选项都将添加为下拉值。例如,在我的代码中,如果您在下拉搜索栏中输入 'a',则会出现 'Montreal' 和 'San Francisco'。如果用户随后按下提交按钮,则这两个选项都应作为值立即添加到下拉列表中。目前我可以将最近的搜索值保存到用户输入的位置,但我无法动态更改下拉值。任何帮助将不胜感激!!这是我的代码:仅供参考:我在 Colab 笔记本中 运行 这个

**正确答案

from jupyter_dash import JupyterDash  # pip install dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Output, Input, State
import pandas as pd  # pip install pandas
import plotly.express as px
import dash_table
import math

from dash import no_update

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = JupyterDash(__name__, external_stylesheets=external_stylesheets)

options = [
    {"label": "New York City", "value": "NYC"},
    {"label": "Montreal", "value": "MTL"},
    {"label": "San Francisco", "value": "SF"},
]
app.layout = html.Div([
        html.Div(id='output_data'),
        html.Div(id="hidden-search-value", style={"visibility":"hidden"}),
        html.Div(id="value-test", style={'color':'white'}),
        html.Div(html.Button('Submit', id = 'button', n_clicks=0), style={'width':'49%', 'display':'inline-block'}),


    html.Div(
        dcc.Dropdown(id="my-multi-dynamic-dropdown", multi=True, clearable = True, options = options, style={'width':'49%', 'display':'inline-block'})),
])


@app.callback(
    [Output("hidden-search-value", "children"),
    Output("value-test", "children")],
    Input(component_id="my-multi-dynamic-dropdown", component_property="search_value"),
)
# save previous search value in hidden variable 
def update_hidden_value(value):
    if value == "":
        raise PreventUpdate
    return value, "Select all values containing '{}'".format(value)

@app.callback(
        Output("my-multi-dynamic-dropdown", "value"),
        Input(component_id="button", component_property="n_clicks"),
    [
        State(component_id="output_data", component_property="children"),
        State(component_id="hidden-search-value", component_property="children")
    ]
)
# submit button logic: use saved search value to update drop_down value 
def update_multi_options(n_clicks, children, search_value):
    # submit button pressed
    if int(n_clicks) > 0:
      values = []
      for o in options:
        # all values containing search value
        if search_value.lower() in o["label"].lower():
          values.append(o["value"])
        else:
          continue
      return values
    else:
      return no_update

app.run_server(mode='inline', port=8030)

我认为您的回调输入参数顺序错误 update_multi_options。应该是:

@app.callback(
    Output("my-multi-dynamic-dropdown", "value"),
    Input(component_id="button", component_property="n_clicks"), 
    State(component_id="output_data", component_property="children")
)
def update_multi_options(n_clicks, children):

现在,关于使用搜索功能的动态更新,事实证明,每当您点击搜索栏外时,search_value 就会被清除。所以我建议也许在临时隐藏变量中跟踪 search_value, 如果 这对您的应用程序来说是一个低风险选项。执行此操作的方法如下:

app.layout = html.Div([
        html.Div(id='output_data'),
        html.Div(html.Button('Submit', id = 'button', n_clicks=0)),
        html.Div(id="hidden-search-value", style={"visibility":"hidden"}),

    html.Div([
        "Multi dynamic Dropdown",
        dcc.Dropdown(id="my-multi-dynamic-dropdown", multi=True, clearable = True, options = options),
    ]),
])
.
.
.
@app.callback(
    Output("my-multi-dynamic-dropdown", "value"),
    [
        Input(component_id="button", component_property="n_clicks"),
    ],
    [
        State(component_id="output_data", component_property="children"),
        State(component_id="hidden-search-value", component_property="children")
    ]
)
def update_multi_options(n_clicks, children, search_value):
    # Make sure that the set values are in the option list, else they will disappear
    # from the shown select list, but still part of the `value`.
    if int(n_clicks) > 0:
      values = []
      for o in options:
        if search_value in o["label"]:
          values.append(o)
        else:
          continue
      return values
    else:
      return no_update

@app.callback(
    Output("hidden-search-value", "children"),
    Input(component_id="my-multi-dynamic-dropdown", component_property="search_value"),
)
def update_hidden_value(value):
    print(value, type(value))
    if value == "":
        raise PreventUpdate
    return value

这种方法的唯一限制是,当您在搜索中输入内容并单击提交时,您手动删除搜索值,并且 re-click 在提交时,它会停留在最后输入的位置在价值上。但是,我认为这不是问题,因为如果不需要,您可以用另一个回调覆盖它。

总而言之,您需要跟踪输入的值(例如 dcc.Dropdown.search_value),然后触发过滤。