I’m not quite sure why your attempt isn’t working, but if it’s helpful I was able to achieve what you’re trying to do with a callback instead of JavaScript. Something like this:
import dash
import dash_html_components as html
from dash.dependencies import Input, Output
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div(
[
html.Div(
[
html.Button("Button 1", id="btn-1", className="btn"),
html.Button("Button 2", id="btn-2", className="btn active"),
html.Button("Button 3", id="btn-3", className="btn"),
],
id="myDIV",
)
]
)
@app.callback(
[Output(f"btn-{i}", "className") for i in range(1, 4)],
[Input(f"btn-{i}", "n_clicks") for i in range(1, 4)],
)
def set_active(*args):
ctx = dash.callback_context
if not ctx.triggered or not any(args):
return ["btn" for _ in range(1, 4)]
# get id of triggering button
button_id = ctx.triggered[0]["prop_id"].split(".")[0]
return [
"btn active" if button_id == f"btn-{i}" else "btn" for i in range(1, 4)
]
if __name__ == "__main__":
app.run_server(debug=True)
You might have to do a bit of playing around to get the initial state right. At the moment I have it so that no button is active to begin with.
Hi tcbegley, do you know how to implement this in R? I had the question a long time and finally found your solution. But I don’t know how to carry that over to R.
Not sure I’m afraid, I haven’t played around with dashR all that much. The section “How do I determine which Input has changed” here in the docs should help. You can get a similar callback context object by doing something like ctx <- app$callback_context(). Then it’s just a case of figuring out which button was last clicked and setting the classnames appropriately. In my example above I used a few Pythonic things like list comprehensions and *args so I didn’t have to think about the number of function arguments, but the logic is pretty generic.