Skip to content

Instantly share code, notes, and snippets.

@hartzell
Created June 6, 2020 16:26
Show Gist options
  • Save hartzell/f2c1992f3594fe13d6178dbc241e06bb to your computer and use it in GitHub Desktop.
Save hartzell/f2c1992f3594fe13d6178dbc241e06bb to your computer and use it in GitHub Desktop.
Demo of the dropdown's value not being reset when it is removed from the list of options.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
from flask import Flask, send_file
server = Flask(__name__)
app = dash.Dash(server=server)
app.layout = html.Div(
children=[
dcc.Store(id="jobs", storage_type="memory"),
html.H1("Jobs"),
html.Div(id="jobs-list"),
html.H2("Upload your files"),
dcc.Upload(
id="upload-data",
children=html.Div(
["Drag and drop or click to select a file to upload."]
),
style={
# "width": "100%",
"height": "60px",
"lineHeight": "60px",
"borderWidth": "1px",
"borderStyle": "dashed",
"borderRadius": "5px",
"textAlign": "center",
"margin": "10px",
},
multiple=True,
),
html.H2("Delete jobs"),
dcc.Dropdown(id="jobs-to-delete", multi=True),
html.Button("Delete Me!", id="delete-jobs-button", n_clicks=0),
html.H2("Select a job for detailed display"),
dcc.Dropdown(id="current-job"),
html.H2("Jobs Details"),
html.Div(id="current-job-details"),
],
style={"max-width": "500px"},
)
@app.callback(
Output("jobs-list", "children"), [Input("jobs", "data")],
)
def display_jobs(jobs):
return [html.Div(f"Job: {j}") for j in jobs]
@app.callback(
Output("jobs", "data"),
[
Input("upload-data", "filename"),
Input("delete-jobs-button", "n_clicks"),
],
[State("jobs-to-delete", "value"), State("jobs", "data")],
)
def update_jobs(new_jobs, button, delible_jobs, jobs):
if new_jobs is None and delible_jobs is None:
raise PreventUpdate
triggers = dash.callback_context.triggered
jobs = jobs or []
butt_prop = "delete-jobs-button.n_clicks"
if any([t["prop_id"] == butt_prop for t in triggers]):
jobs = [j for j in jobs if j not in delible_jobs]
up_prop = "upload-data.filename"
if any([t["prop_id"] == up_prop for t in triggers]):
jobs += new_jobs
return jobs
@app.callback(
[Output("current-job", "options"), Output("jobs-to-delete", "options")],
[Input("jobs", "data")],
)
def update_selectable_jobs(jobs):
if jobs is None:
raise PreventUpdate
options = [{"label": f"Job: {j}", "value": j} for j in jobs]
return [options, options]
@app.callback(
Output("current-job-details", "children"),
# FIXES_IT [Input("current-job", "value"), Input("current-job", "options"),],
[Input("current-job", "value"), Input("current-job", "options"),],
[State("current-job-details", "children")],
)
# FIXES_IT def display_current_job(job_id, options, divs):
def display_current_job(job_id, options, divs):
print(f"DISPLAY: {job_id} -> {options}")
# There's nothing to do.
if job_id is None and divs is None:
raise PreventUpdate
# There's no current selection but there's something being
# displayed, so clear the display.
if job_id is None:
return []
# FIXES_IT if all([job_id != o["value"] for o in options]):
# FIXES_IT return []
divs = []
divs.append(html.Div(children=[f"Detailed explanation of {job_id}"]))
return divs
if __name__ == "__main__":
app.run_server(debug=True, port=8888, host="172.16.193.97")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment