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