Callbacks
Read layout state and drive content from Dash callbacks.
Reading the live model
Set useStateForModel=False and the layout round-trips through Dash, so you can read the current model from any callback via Input("your-dock-id", "model"). Rearrange the panels below and watch the JSON update.
# File: docs/callbacks/example.py
import json
from dash import html, dcc, callback, Input, Output
import flexlayout_dash as dfl
# With useStateForModel=False the layout round-trips through Dash, so you can
# read the live model from a callback. Drag a tab or move a splitter and watch
# the JSON update below.
model = {
"global": {"tabEnableClose": False, "tabEnableFloat": True},
"layout": {
"type": "row",
"children": [
{
"type": "tabset",
"weight": 50,
"children": [{"type": "tab", "name": "Left", "id": "callbacks-left"}],
},
{
"type": "tabset",
"weight": 50,
"children": [{"type": "tab", "name": "Right", "id": "callbacks-right"}],
},
],
},
}
def _panel(text):
return html.Div(text, style={"padding": "16px"})
component = html.Div(
[
dfl.DashFlexLayout(
id="callbacks-dock",
model=model,
useStateForModel=False,
style={"height": "320px"},
children=[
dfl.Tab(id="callbacks-left", children=[_panel("Rearrange these panels…")]),
dfl.Tab(id="callbacks-right", children=[_panel("…and the model JSON below updates live.")]),
],
),
html.P("Live model (read via Input('callbacks-dock', 'model')):",
style={"fontWeight": 600, "marginTop": "12px"}),
dcc.Markdown(id="callbacks-model-json"),
]
)
@callback(
Output("callbacks-model-json", "children"),
Input("callbacks-dock", "model"),
)
def show_model(model):
text = json.dumps(model, indent=2)
if len(text) > 1400:
text = text[:1400] + "\n ... (truncated)"
return f"```json\n{text}\n```"
How it stays callback-friendly
flexlayout-dash renders each tab's children through a React portal into a stable container, so your tab content stays mounted across internal FlexLayout changes (tab switches, splitter drags). That keeps callbacks bound to elements inside tabs working.
As of 1.1.0, echoes of FlexLayout's own internal model changes no longer recreate the layout model, so stateful tab content (canvases, editors, in-progress drags) is not re-mounted on tab switch or splitter drag — only a model your own callbacks write rebuilds it. setProps still fires on every change, so Input(dock, "model") keeps working.
Tip: keep tabs mounted
For callbacks bound to elements inside tabs, keep every tab mounted by setting "tabEnableRenderOnDemand": False in the model's global section.
Source: /callbacks
Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs:
- /callbacks/llms.txt — LLM-friendly documentation
- /sitemap.xml
- /robots.txt