Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Changing dcc.Checklist.options triggers callbacks with inputs dcc.Checklist.value #2411

Closed
mclarty3 opened this issue Feb 2, 2023 · 5 comments · Fixed by #2429
Closed

Comments

@mclarty3
Copy link

mclarty3 commented Feb 2, 2023

Describe your context
Please provide us your environment, so we can easily reproduce the issue.

dash                      2.8.1
dash-bootstrap-components 1.3.1
dash-core-components      2.0.0
dash-daq                  0.5.0
dash-html-components      2.0.0
dash-table                5.0.0

Note that this also occurs with Dash 2.8.0, but not 2.7.0.

  • if frontend related, tell us your Browser, Version and OS

    • OS: Ubuntu 22.04
    • Browser: Chrome
    • Version: 109.0.5414.119

Describe the bug

When outputting to the options property of a dcc.Checklist, it triggers callbacks with inputs dcc.Checklist.value.

Expected behavior

Callbacks with input dcc.Checklist.value should only be triggered if that checklist's value is explicitly changed (either through callback or user input), not if only the checklist options are changed.

Minimal reproducible example

I've tried to create a simple example app to show exactly what the issue is. I tried taking a screen recording though unfortunately Ubuntu is not helping out currently.

In essence, when running with Dash <= 2.7.0, only selecting/deselecting a city should increment the counter below the checklist. With Dash >= 2.8.0, however, the counter is also incremented when typing in the search bar above the checklist (not desired behaviour)

DashBugMRE.zip

@alexcjohnson
Copy link
Collaborator

Thanks @mclarty3 - to my eye there are two bugs here:

  1. If you alter options, but the checked items are still present afterward, value doesn't change so any callback attached to it also shouldn't fire. But right now it does.
  2. If you alter options and thereby delete an item that was checked, it should be removed from value (and callbacks should fire). Right now that item is still included in value and there's no way to get rid of it.

Minimum app to reproduce both of these:

  1. First off, on page load None is printed twice, should be only once. Then click "1" (['1'] is correctly printed in the Python console), then "3<->2" (['1'] is printed again, it should not be.)
  2. Reload, click "2", then "3<->2" (the output div still says "2", that should have been removed because there's no longer a "2" checkbox, and the callback should have fired with [] as the value)
from dash import Dash, dcc, html, Input, Output

app = Dash(__name__)

app.layout = html.Div([
    html.Button("3<->2", id="a"),
    dcc.Checklist(id="b"),
    html.Div(id="c")
])

@app.callback(Output('b', 'options'), Input('a', 'n_clicks'))
def opts(n):
    n_out = 3 - (n or 0) % 2
    return [str(i) for i in range(n_out)]

@app.callback(Output('c','children'), Input('b','value'))
def fin(val):
    print(val)
    return val

if __name__ == '__main__':
    app.run(debug=True)

@mclarty3
Copy link
Author

mclarty3 commented Feb 4, 2023

Thanks @mclarty3 - to my eye there are two bugs here:

  1. If you alter options, but the checked items are still present afterward, value doesn't change so any callback attached to it also shouldn't fire. But right now it does.
  2. If you alter options and thereby delete an item that was checked, it should be removed from value (and callbacks should fire). Right now that item is still included in value and there's no way to get rid of it.

Thanks for the thoughtful response and the simpler example app. Funnily I had considered the second bug a feature, as my use-case is similar to the example app I provided, in that I'm filtering out options to allow the user to search within the checklist. That said, if that behavior is "fixed" I'm sure it'd be doable to recreate that functionality some other way.

@alexcjohnson
Copy link
Collaborator

Might be able to hide the filtered-out options with some sort of CSS trick… or we could add a feature to continue listing all the options but mark some as hidden. But yeah, definitely counts as a bug 😄

@ned2
Copy link
Contributor

ned2 commented Feb 5, 2023

Testing your minimal app @alexcjohnson, it looks like this regression was actually introduced in 2.7.1.

Looking at CHANGELOG.md, I wonder if it might be associated with #2344, which was a fix for a bug relating to dependent callbacks.

@alexcjohnson
Copy link
Collaborator

@T4rk1n would you be able to look at this one as well after partial props?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants