Reputation: 41
I am quite new to programming and to plotly dash as well. I have some tabs in my dashboard and in each tab i have a text input box (int) and a button that triggers some calculations using the input.
With the following script, when I select the tab, the callback is triggered and the calculation already starts with the empty value in the text, even before I click the button. I do have an if clause to return nothing when the text input box is empty. But that doesn't seem to be working. It directly goes to the final "else" clause. How can i solve this? Thank you!
@app.callback(Output('PRINTOUTPUT', 'children'),
[Input('create_button', 'n_clicks'),
Input('selection_tabs', 'value')],
[State('text-input', 'value')])
def xyz (clicks, selected_tab, textinput):
changed_id = [p['prop_id'] for p in dash.callback_context.triggered][0] #To determine if n_clicks is changed.
if 'create_button' not in changed_id:
return ""
elif 'create_button' in changed_id:
if textinput =="": #Do nothing if button is clicked and input num is blank.
return "No input"
else:
#Do some calculations based on the selected tab and input
return "Successful"
Upvotes: 1
Views: 5157
Reputation: 33770
If there is a problem in your code, it is probably elsewhere than in the part you pasted to the question. I wrote an MWE around the callback you provided and it seems it is working as you intented:
prop_id
attribute of the items in the list dash.callback_context.triggered
is of the form component_id.component_property
. Therefore, if you want to check whether it was 'create_button'
that triggered the callback, you should compare against the part before the dot (or compare to 'create_button.n_clicks'
directly).dash.callback_context.triggered
was checked. You probably want to check against all the elements in the list, although in current version of dash it can only contain properties of single component: "is a length-1 list, unless two properties of a single component update simultaneously, such as a value and a timestamp or event counter." (dash.callback_context.triggered)return
.import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
tab_div = html.Div(
dcc.Tabs(id='selection_tabs', value='tab-1', children=[
dcc.Tab(label='Tab one', value='tab-1'),
dcc.Tab(label='Tab two', value='tab-2'),
]))
app.layout = html.Div(children=[
html.H1(children='Test app'),
tab_div,
dcc.Input(id="text-input", type="text", placeholder=""),
html.Div(id='PRINTOUTPUT'),
html.Button('Click me', id='create_button')
])
@app.callback(Output('PRINTOUTPUT', 'children'),
[Input('create_button', 'n_clicks'),
Input('selection_tabs', 'value')],
[State('text-input', 'value')])
def xyz(clicks, selected_tab, textinput):
#To determine if n_clicks is changed.
changed_ids = [p['prop_id'].split('.')[0] for p in dash.callback_context.triggered]
button_pressed = 'create_button' in changed_ids
if not button_pressed:
return ""
if textinput == "": #Do nothing if button is clicked and input num is blank.
return "No input"
#Do some calculations based on the selected tab and input
return "Successful"
if __name__ == '__main__':
app.run_server(debug=True)
Upvotes: 2
Reputation: 1704
Assuming that you are using dcc.Input
component for your text input, it has an optional parameter value
which could be set while defining it. By default, this value is set to python's None
.
So if you are not setting this parameter's value to empty string ""
when defining it, then comparing it to ""
in your if
clause will result in False
, and that is why it always ends up in the else
clause.
You just need to check if your textinput is None
.
Try changing your if clause to if textinput is None: #Do nothing if button is clicked and input num is blank.
Or you can also explicitly set the default value of your input box to ""
at the place where you are defining it, but that seems a bit counter-intuitive to do.
Upvotes: 0