Dash#

ITables includes a Dash component since v2.3.0.

Displaying a DataFrame#

If you wish to display a DataFrame which content is fixed (not reacting to the other controls in the application), you just need to import ITable from itables.dash and add it to your layout like here:

from dash import Dash, html

from itables.dash import ITable
from itables.sample_dfs import get_countries

app = Dash(__name__)

df = get_countries(html=False)

app.layout = html.Div(
    [
        html.H1("ITables in a Dash application"),
        ITable(id="my_dataframe", df=df, caption="A DataFrame displayed with ITables"),
    ]
)

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

Selected rows#

Listening to the selected rows is simply done by adding select=True to the ITable call, and then implementing a callback on Input("my_dataframe", "selected_rows").

from dash import Dash, Input, Output, callback, html

from itables.dash import ITable
from itables.sample_dfs import get_countries

app = Dash(__name__)

df = get_countries(html=False)

app.layout = html.Div(
    [
        html.H1("ITables in a Dash application"),
        ITable(
            id="my_dataframe",
            df=df,
            caption="A DataFrame displayed with ITables",
            select=True,
        ),
        html.Div(id="output"),
    ]
)


@callback(
    Output("output", "children"),
    Input("my_dataframe", "selected_rows"),
)
def show_selection(selected_rows):
    return f"Selected rows: {selected_rows}"


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

Updating the DataFrame#

The ITable fonction returns an ITableComponent that has many properties. These properties (data, columns, selected rows etc) need to be updated in a consistent way. Therefore we recommend that you list the outputs with ITableOutputs("my_dataframe") in your callback, and update them with updated_itable_outputs which takes the same arguments as show, e.g. df, caption,selected_rows, etc, like in the below (extracted from this example app):

from itables.dash import ITable, ITableOutputs, updated_itable_outputs

# (...)

@callback(
    ITableOutputs("my_dataframe"),
    [
        Input("checklist", "value"),
        Input("caption", "value"),
        State("my_dataframe", "selected_rows"),
        State("my_dataframe", "dt_args"),
    ],
)
def update_table(checklist, caption, selected_rows, dt_args):
    if checklist is None:
        checklist = []

    kwargs = {}

    # When df=None and when the dt_args don't change, the table is not updated
    if callback_context.triggered_id == "checklist":
        kwargs["df"] = get_countries(html="HTML" in checklist)

    kwargs["select"] = "Select" in checklist
    if "Buttons" in checklist:
        kwargs["buttons"] = ["copyHtml5", "csvHtml5", "excelHtml5"]

    return updated_itable_outputs(
        caption=caption, selected_rows=selected_rows, current_dt_args=dt_args, **kwargs
    )

Limitations#

Compared to show, the ITable component has the same limitations as the Jupyter Widget or the Streamlit component, e.g. structured headers are not available, you can’t pass JavaScript callback, etc.