Dynamically button disabling not working properly

Refer to this link if you want to make it into two separate callbacks

So I’d do something like this:

You’ll need to use another component, really can be anything; something as simple as an html.Div with a children prop or dcc store or dcc interval would all be invisible to the user
Otherwise, you could use something like a dismissible alert

# Add this to your layout
dbc.Alert(
            "File Successfully Downloaded",
            id="alert",
            dismissable=True,
            is_open=False,
        )

@app.callback(
    Output("export_button", "disabled"),
    [Input("export_button", "n_clicks"),
    Input("alert", "is_open"])
def disable_enable(n_clicks,  alert):
    changed_id = [p['prop_id'] for p in callback_context.triggered][0]
    if changed_id == "export_button.n_clicks":
        if n_clicks is None:
            return no_update
        else:
            return True
    else:
        # changed_id should be alert.is_open
        # re-enable the button if the alert prop is triggered
        return False
        
@app.callback(
    [Output(f"{PAGE_ID}_download-pdf", "data"),
    Output("alert", "is_open")],
    Input(f"{PAGE_ID}_export_button", "n_clicks"),
    [State(f"{PAGE_ID}_labelsperserial", "value"),
    State(f"{PAGE_ID}_offsetlines", "value"),
    State(f"{PAGE_ID}_filename", "value"),
    State(f"{PAGE_ID}_start", "value"),
    State(f"{PAGE_ID}_devicetype", "value"),
    State(f"{PAGE_ID}_batchname", "value"),
    State(f"{PAGE_ID}_batchsize", "value"),
    State(f"{PAGE_ID}_revision", "value")],
    prevent_initial_call=True)
def download_pdf(n_clicks, labelsperserial, offsetlines, filename, start, devicetype, batchname, batchsize, revision):
    changed_id = [p['prop_id'] for p in callback_context.triggered][0]
    if changed_id != f"{PAGE_ID}_export_button.n_clicks":
        return [no_update, False]

    if n_clicks is None:
        return [no_update, False]
    
    fn = filename
    if fn is not None and not fn.endswith(".pdf"):
        fn = fn + ".pdf"
    response = requests.get(
        base_url + f"/labels/generate-microscopes-serial-sheet?labelsperserial={labelsperserial}&offsetlines={offsetlines}" +
            f"&filename={filename}&start={start}&devicetype={devicetype}&batchname={batchname}&batchsize={batchsize}&revision={revision}", 
    )
        
    return [dcc.send_bytes(response.content, fn, type="application/pdf"), True]

Let me know if this doesn’t work. I didn’t test this code, but I think it should work

1 Like