Black Lives Matter. Please consider donating to Black Girls Code today.
https://www.blackgirlscode.com

Updating HTML Tables via Interval Callback

Hello!

I’m working on building a live-updating table (from a SQL db), and have had great success with the datatable option as so

app.layout = html.Div([
    html.Div(
        id='controls',
        children=[
           html.Button(
                "Print",
                id='las-print'
            ),
        ]
    ),

    html.Div(
        id='frontpage',
        className='page',
        # children=generate_frontpage()
    ),

    html.Div(className='section', children=[
            html.Div(
                className='section-title',
                children="LAS well"
            ),

            html.Div(
                className='page',
                children=[
                    html.Div([dash_table.DataTable(id='pr-table',
                                                    # sort_action='native',
                                                    # filter_action='native',
                                                    # row_deletable=True,
                                                    style_cell={
                                                        'padding': '15px',
                                                        'width': 'auto',
                                                        'textAlign': 'center'
                                                    },
                                                   style_data={'whiteSpace': 'normal'},
                                                   css=[{'selector': '.dash-cell div.dash-cell-value',
                                                         'rule': 'display: inline; white-space: inherit; overflow: inherit; text-overflow: inherit;'}],
                                                    columns=[{"name": i, "id": i} for i in df.columns],
                                                    data=df.to_dict("rows")
                                            ),
                       dcc.Interval(id='interval_component',
                                    interval=1000,
                                    n_intervals=0
                                    )
                       ], className="row pretty_container table"),
                    html.Div(
                        id='pr-table-print'
                    )]
            )
    ]),
])

@app.callback(Output('pr-table', 'data'), [Input('interval_component', 'n_intervals')])
def update_table(n_intervals):
    con = sqlite3.connect('database.db')
    df = pd.read_sql_query("SELECT title, link, ticker, release_date FROM globenewswire", con)
    data = df.to_dict('records')
    return data

What I would like however, is the interval update functionality for a standard HTML table as in

[html.Tr([html.Th(col) for col in df.columns])] +, id='table', style=dict(margin="auto")),

Have tried searching up and down for a way to do it, so not sure if it’s even possible.
Any help would be much appreciated!

Hi @danielhhowell you can create an html.Table as described in this Stack Overflow answer, and then your callback can update the children property of the html.Table.

Hello @Emmanuelle thanks for the help! I have gotten HTML tables to work with callbacks using this method, the difficulty is I’m not sure how to get the dcc.interval component to interface here.

Hum, why would you need to use the dcc.Interval differently whether the output is a Dash DataTable or an html.Table? An Interval can just be used to trigger a callback, that’s its only purpose.

Hm, thank you. I guess I was having trouble positioning the dcc.interval to be within the children. So this now kind of works but instead of replacing the table it is loading a new one on top and appending it for an infinitely loading table. Not sure where I messed up this time?

def generate_table(max_rows=26):
        con = sqlite3.connect('database.db')
        df = pd.read_sql_query("SELECT title, link, ticker, release_date, price, market_cap, avg_volume FROM pressreleases", con)
        return html.Table(
            # Header
            [html.Tr([html.Th(col) for col in dataframe.columns], id='pr-table') ] +
            # Body
            [html.Tr([
                html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
            ]) for i in range(min(len(dataframe), max_rows))]
        )

app = dash.Dash(__name__, )

app.layout = html.Div(children=[
    generate_table(),
    dcc.Interval(id='interval_component',
                 interval=1000,
                 n_intervals=0
                 )

])

@app.callback(Output('pr-table', 'children'), [Input('interval_component', 'n_intervals')])
def update_table(n_intervals):
    return generate_table()

EDIT: I see my problem now! Just needed to make sure the table ID was in the layout instead of the generator function. Thanks for the guidance!

Working code below for those in need:

def generate_table(max_rows=26):
        con = sqlite3.connect('database.db')
        df = pd.read_sql_query("SELECT title, link, ticker, release_date, price, market_cap, avg_volume FROM pressreleases", con)
        return html.Table(
            [html.Tr([
                html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
            ]) for i in range(min(len(dataframe), max_rows))]
        )

app = dash.Dash(__name__, )

app.layout = html.Div([
                html.Div([
                    html.Div(
                        [html.Tr([html.Th(col) for col in df.columns])], id='pr-table', style=dict(margin="auto")),
                       dcc.Interval(id='interval_component',
                                    interval=1000,
                                    n_intervals=0
                                    )
                ], className="pretty_container", style=dict(align_items="center")),
            ], className="six columns", style=dict(align_items="center"))

@app.callback(Output('pr-table', 'children'), [Input('interval_component', 'n_intervals')])
def update_table(n_intervals):
    return generate_table()