plotly / dash-table-experiments

NO LONGER SUPPORTED - use https://github.com/plotly/dash-table instead
MIT License
174 stars 57 forks source link

Cannot dynamically create tables #28

Closed mewais closed 6 years ago

mewais commented 6 years ago

Hello,

Tables are great, they work fine when used in a layout directly, something like this is OK:

app.layout = html.Div([
    html.Div(id='div1'),
    html.Div(id='div2'),
    html.Div(id='div3',children=[dt.DataTable(id='users table', rows=[{}], columns=['', 'col1', 'col2', 'col3', 'col4', 'col5'], filterable=True, sortable=True)])
])

But if you have a function create the table dynamically and assign it to the layout, tables do not even show up. This is needed for cases where you change the page content dynamically based on other inputs, for example If you decide whether to make a table or plot some figure based on a button, or if you want to have tables inside a tab body or so you'd have to do something like this:

app.layout = html.Div([
    html.Div(id='div1'),
    html.Div(id='div2'),
    html.Div(id='div3')
])

@app.callback(Output(div3', 'children'),
            [Input('dropdown1', 'value')])
def display_table(dropdown1_value):
    return dt.DataTable(id='users table', rows=[{}], columns=['', 'col1', 'col2', 'col3', 'col4', 'col5'], filterable=True, sortable=True)

This doesn't work, The table doesn't show up at all, and no error messages are printed.

chriddyp commented 6 years ago

@mewais - did you post the question here? https://community.plot.ly/t/data-tables-with-multi-pages/7282/3

chriddyp commented 6 years ago

Also, does it work if the DataTable has non-empty rows?

chriddyp commented 6 years ago

Also, this example works for me:

import dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_core_components as dcc
from dash_table_experiments import DataTable
import json

app = dash.Dash()
app.config['suppress_callback_exceptions'] = True
app.layout = html.Div([
    html.Button(id='button', n_clicks=0, children='Show table'),
    html.Div(id='content'),
    html.Div(DataTable(rows=[{}]), style={'display': 'none'})
])

@app.callback(Output('content', 'children'), [Input('button', 'n_clicks')])
def display_output(n_clicks):
    if n_clicks > 0:
        return html.Div([
            html.Div(id='datatable-output'),
            DataTable(
                id='datatable',
                rows=[{'Column 1': i} for i in range(5)]
            )
        ])

@app.callback(
    Output('datatable-output', 'children'),
    [Input('datatable', 'rows')])
def update_output(rows):
    return html.Pre(
        json.dumps(rows, indent=2)
    )

if __name__ == '__main__':
    app.run_server(debug=True)

image

(Taken from this thread in the community forum: https://community.plot.ly/t/dash-datatable-updating-the-number-of-rows/6448/2?u=chriddyp)

mewais commented 6 years ago

Hey Chris, no that's not me I did not post the question.

I just tried the example you posted here, It works! however, this line: html.Div(id='content') seemed useless to me so I tried removing it, all I could see was the button but the table didn't show up!

I tried adding this seemingly useless line to my code and it also did work, the tables now shows up fine.

So, my problem is now solved, but what is happening exactly? why does it work with this line? or why does it not work without it?!

chriddyp commented 6 years ago

html.Div(id='content') seemed useless to me so I tried removing it

Did you see the callback below?


@app.callback(Output('content', 'children'), [Input('button', 'n_clicks')])
def display_output(n_clicks):
    if n_clicks > 0:
        return html.Div([
            html.Div(id='datatable-output'),
            DataTable(
                id='datatable',
                rows=[{'Column 1': i} for i in range(5)]
            )
        ])

That callback is populating the children property of the component with the id content, in this case html.Div(id='content').

For more about how callbacks work, read through the first section of the user guide: https://plot.ly/dash/getting-started-part-2

mewais commented 6 years ago

Sorry, I meant to copy the line below it, which is truely useless as it's a hidden table with empty rows.

html.Div(DataTable(rows=[{}]), style={'display': 'none'})

chriddyp commented 6 years ago
html.Div(DataTable(rows=[{}]), style={'display': 'none'})

see the comment in the community forum here: https://community.plot.ly/t/display-tables-in-dash/4707/40?u=chriddyp (similarly https://github.com/plotly/dash-table-experiments/issues/19 )

mewais commented 6 years ago

Thanks