Disable the button before the callback function is finished

I know someone has been posted related question before. But there isn’t yet a solution that seems to work. So I wanna ask again.

I would like to disable the submit button when the pattern-matching callback function is running, which does heavy computation.

Does anyone has idea how to do that? Thank you in advance.

@app.long_callback(
    output=Output("paragraph_id", "children"),
    inputs=Input("button_id", "n_clicks"),
    running=[
        (Output("button_id", "disabled"), True, False),
        (Output("cancel_button_id", "disabled"), False, True),
    ],
    cancel=[Input("cancel_button_id", "n_clicks")],
)
def callback(n_clicks):
    time.sleep(2.0)
    return [f"Clicked {n_clicks} times"]


if __name__ == "__main__":
    app.run_server(debug=True)

Thanks but long_callback cannot use pattern-matching inputs. I need the callback function has dynamic outputs.

Ok. We can use dcc.Loading to pretend we already support this feature.

import time
from dash import Dash, html, dcc, Input, Output, State, ClientsideFunction

app = Dash(__name__)

app.layout = html.Div(
    [dcc.Loading([btn := html.Button('Submit'), output := html.Div()])])


@app.callback(Output(output, 'children'),
              Input(btn, 'n_clicks'),
              prevent_initial_call=True)
def do_something(n):
    time.sleep(2)
    return n


if __name__ == "__main__":
    app.run_server(debug=True)