Dash Data Table not displayed on full page

Hi everyone,

I have a following code (css in assets folder followed by the actual app code. Please see it below. (I included on relevant parts, not the full code as it is also importing parsed data from a module in the same folder).
The problem:
The table is displayed only on half of the screen. For some reason bottom half of the page is empty. Despite data containing 65 rows, only 8 rows are displayed at a time. How do I make the table extend to the whole screen?

CSS in separate “assets” folder:

.dash-spreadsheet .row {
flex-wrap: nowrap;
}
.dash-spreadsheet.dash-freeze-left {
max-width: none !important;
}
.dash-spreadsheet .row {
margin-left: 0px;
margin-right: 0px;
}

The WebApp code in the main folder:

import dash
from dash import dcc
from dash import html
from dash.dependencies import Input,Output
from dash import dash_table
import pandas as pd
import dash_bootstrap_components as dbc
from imdb import url_parser

app=dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP],
#following line with meta-tags allows the content to be viewable on mobile devices 
meta_tags=[{"name":"viewpoints","content":"width=device-width,initial-scale=1.0"}])

app.layout=dbc.Container([
    dcc.Dropdown(id="list1"),
    html.Div(id="data_table")
],fluid = True)

@app.callback(
    Output("data_table","children"),
    Input("list1","value"),
    prevent_initial_call=True
)

def store_data(dropdown_value):
    if dropdown_value=="Movies":
        url="https://www.imdb.com/list/..."
        data=url_parser(url)
        data_table=dash_table.DataTable(
            columns=[{'name': i, 'id': i,"type":"numeric","format":{"prefix":1000000,"specifier":",.0f"}} for i in data.columns],
            data=data.to_dict("records"),
            filter_action="native",
            sort_action="native",
            sort_mode="single",
            fixed_rows={'headers': True, 'data': 0},
            page_action="native",
            page_current=0,
            page_size=100,
            style_table={'minWidth': '100%', "height":300,"overflowY":"auto"},
            style_header={"backgroundColor":"rgb(153, 203, 255)","fontWeight":"bold"},
            style_cell={"backgroundColor":"rgb(239, 239, 243)","font-family": "Arial"},
            style_as_list_view=True
        )
    elif:
        ...
    return data_table

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

Hi @mrel

You could try increasing the height in this prop:

style_table={'minWidth': '100%', "height":300,"overflowY":"auto"},

However, it looks like it may be how you have defined the layout. Could you post a complete minimal example with sample data that reproduces the issue?

1 Like

Hi @AnnMarieW !

Sure.
This is CSS in separate “assets” folder:

.dash-spreadsheet .row {
flex-wrap: nowrap;
}
.dash-spreadsheet.dash-freeze-left {
max-width: none !important;
}
.dash-spreadsheet .row {
margin-left: 0px;
margin-right: 0px;
}

And this it the full code of the WebApp. What this code does is it parses 4 different links depending on the dropdown option chosen (only 4 respective options available in dropdown) and then returns the Data_Table as html.Div(id=“data_table”)
I tried to change and experiment with the style_table{} parameter as you suggested but couldn’t find a solution.

import dash
from dash import dcc
from dash import html
from dash.dependencies import Input,Output
from dash import dash_table
import pandas as pd
import dash_bootstrap_components as dbc
from imdb import url_parser #module

app=dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP],
#following line with meta-tags allows the content to be viewable on mobile devices 
meta_tags=[{"name":"viewpoints","content":"width=device-width,initial-scale=1.0"}])

app.layout=dbc.Container([
    html.Div([
        html.H1(
            "Test Dashboard with Dash",
            style={
                "text-align":"center",
                "color":"#503D36",
                "font-size": 40
            }
        ),
        html.Div(id="memory-output1",style={"display":"none"})
    ]),
    html.Br(),
    dcc.Dropdown(
        id="list1",
        options=[
            {"label":"Movies","value":"Movies"},
            {"label":"Series","value":"Series"},
            {"label":"Cartoons","value":"Cartoons"},
            {"label":"Anime","value":"Anime"}
        ],
        style={'color': 'black'}
    ),
    html.Br(),
    html.Div(id="data_table"),
],fluid = True)

@app.callback(
    Output("data_table","children"),
    Input("list1","value"),
    prevent_initial_call=True
)

def store_data(dropdown_value):
    if dropdown_value=="Movies":
        url="https://www.imdb.com/list/..."
        data=url_parser(url) #parse via imported module
        data_table=dash_table.DataTable(
            columns=[{'name': i, 'id': i,"type":"numeric","format":{"prefix":1000000,"specifier":",.0f"}} for i in data.columns],
            data=data.to_dict("records"),
            filter_action="native",
            sort_action="native",
            sort_mode="single",
            # fixed_columns={'headers': True,'data': 1},
            fixed_rows={'headers': True, 'data': 0},
            page_action="native",
            page_current=0,
            page_size=100,
            style_table={'minWidth': '100%', "height":300,"overflowY":"auto"},
            style_header={"backgroundColor":"rgb(153, 203, 255)","fontWeight":"bold"},
            style_cell={"backgroundColor":"rgb(239, 239, 243)","font-family": "Arial"},
            style_as_list_view=True
        )
    elif dropdown_value=="Series":
        url="https://www.imdb.com/list/..."
        data=url_parser(url) #parse via imported module
        data_table=dash_table.DataTable(
            columns=[{'name': i, 'id': i,"type":"numeric","format":{"prefix":1000000,"specifier":",.0f"}} for i in data.columns],
            data=data.to_dict("records"),
            filter_action="native",
            sort_action="native",
            sort_mode="single",
            # fixed_columns={'headers': True,'data': 1},
            fixed_rows={'headers': True, 'data': 0},
            page_action="native",
            page_current=0,
            page_size=100,
            style_table={'minWidth': '100%', "height":300,"overflowY":"auto"},
            style_header={"backgroundColor":"rgb(153, 203, 255)","fontWeight":"bold"},
            style_cell={"backgroundColor":"rgb(239, 239, 243)","font-family": "Arial"},
            style_as_list_view=True
        )
    elif dropdown_value=="Cartoons":
        url="https://www.imdb.com/list/..."
        data=url_parser(url) #parse via imported module
        data_table=dash_table.DataTable(
            columns=[{'name': i, 'id': i,"type":"numeric","format":{"prefix":1000000,"specifier":",.0f"}} for i in data.columns],
            data=data.to_dict("records"),
            filter_action="native",
            sort_action="native",
            sort_mode="single",
            # fixed_columns={'headers': True,'data': 1},
            fixed_rows={'headers': True, 'data': 0},
            page_action="native",
            page_current=0,
            page_size=100,
            style_table={'minWidth': '100%', "height":300,"overflowY":"auto"},
            style_header={"backgroundColor":"rgb(153, 203, 255)","fontWeight":"bold"},
            style_cell={"backgroundColor":"rgb(239, 239, 243)","font-family": "Arial"},
            style_as_list_view=True
        )
    elif dropdown_value=="Anime":
        url="https://www.imdb.com/list/..."
        data=url_parser(url) #parse via imported module
        data_table=dash_table.DataTable(
            columns=[{'name': i, 'id': i,"type":"numeric","format":{"prefix":1000000,"specifier":",.0f"}} for i in data.columns],
            data=data.to_dict("records"),
            filter_action="native",
            sort_action="native",
            sort_mode="single",
            # fixed_columns={'headers': True,'data': 1},
            fixed_rows={'headers': True, 'data': 0},
            page_action="native",
            page_current=0,
            page_size=100,
            style_table={'minWidth': '100%', "height":300,"overflowY":"auto"},
            style_data={
                'width': '150px', 'minWidth': '150px', 'maxWidth': '150px',
                'overflow': 'hidden',
                'textOverflow': 'ellipsis',
            },
            style_header={"backgroundColor":"rgb(153, 203, 255)","fontWeight":"bold"},
            style_cell={"backgroundColor":"rgb(239, 239, 243)","font-family": "Arial"},
            style_as_list_view=True
        )
    return data_table

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

Hi @mrel

Thanks for posting the code, but could you please format it it’s more readable? You can do that by enclosing it in three back ticks ```

See more info in this post How to Get your Questions Answered on the Plotly Forum

Apologies, @AnnMarieW .
I formatted and, hopefully, it is more useful now.

Note: the data is coming from a different module which parses a website (URL) protected by login/password.

Hi @mrel

Thanks, that’s readable now :tada:

As described in the post I sent you, it’s really hard to help without a minimal working example - with data - that someone can copy, paste and run locally to recreate the issue.

This error is likely caused by how the table is defined. Any sample data should work, so it’s not necessary to use you own data. To make a MWE, a good place to start is with the Dash Example Index and search for an example with a DataTable.

This app is a good start. It uses a slider instead of a dropdown, but that doesn’t matter. It can aslo be simplified to eliminate the download component - so now we have this MWE:

import dash
from dash import Dash, dash_table, dcc, html, Input, Output, State
import plotly.express as px

app = Dash(__name__)

df = px.data.gapminder()

range_slider = dcc.RangeSlider(
    value=[1987, 2007],
    step=5,
    marks={i: str(i) for i in range(1952, 2012, 5)},
)

dtable = dash_table.DataTable(
    columns=[{"name": i, "id": i} for i in sorted(df.columns)],
    sort_action="native",
    page_size=20,
    style_table={"overflowX": "auto"},
)

app.layout = html.Div(
    [
        html.H2("Gapminder", style={"marginBottom": 20}),
        range_slider,
        dtable,
    ]
)

@app.callback(
    Output(dtable, "data"),
    Input(range_slider, "value"),
)
def update_table(slider_value):
    if not slider_value:
        return dash.no_update
    dff = df[df.year.between(slider_value[0], slider_value[1])]
    return dff.to_dict("records")


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

Now you can start making changes to the DataTable definition one prop at a time until you can recreate your issue.

Note that it’s not necessary to redefine the DataTable for every dropdown option - you can just update the data prop with the new filter data.

I hope this helps

Hi @AnnMarieW ,

I finally found what the issue is.
The fixed_rows parameter is what is causing the problem. It doesn’t allow the table to be scaled/displayed on the whole screen. As soon as I removed it, the table is scaling and covering the whole screen.
I didn’t expect this line to create the issue. Probably some bug.
I will bypass it somehow (maybe create a separate div above the table with table headers and fix it in the app layout, so outside the table, not inside the table).

fixed_rows={'headers': True, 'data': 0}

Note: I tried two versions of that parameter (with and without “data”:0). Same bug, table is not scaling and not covering the whole screen. Only top half of the screen.
fixed_rows={'headers': True, 'data': 0}
fixed_rows={'headers': True}

@mrel,

You could also freeze the header row by adding this to your css stylesheet:

#filters table tr th {
        position: sticky;
        top: -1px;
        z-index: 900;
    }

Where “#filters” is the id of the table you want to configure. The z-index is to bring it overtop of the row data as you scroll down.

Hi, @jinnyzor ,

Thank you for your input. I have just tried it but it didn’t work.
id of my table is “data_table” and is defined in the callback (below).

@app.callback(
    Output("data_table","children"),
    Input("list1","value"),
    prevent_initial_call=True
)

So now it looks like this, but it didn’t work. Am I missing something?

#data_table table tr th {
        position: sticky;
        top: 0;
        z-index: 900;
    }

Did you make a css file in the assets folder underneath the app main folder.

app.py
assets
header.css

The header.css file is where you put the code that I gave you. You’ll also need to remove the fixed_rows for the table.

@jinnyzor , yes, that is exactly what I did. I have a css file under assets folder in the main folder.
And, yes, I removed the “fixed_rows” line from the code as it was creating problems. Still not working.

Do you still have the height argument in your setup as well?

@jinnyzor , no, I don’t have the height argument anymore.
These are the only lines I have in css.

.dash-spreadsheet .row {
  flex-wrap: nowrap;
}
.dash-spreadsheet.dash-freeze-left {
    max-width: none !important;
}
.dash-spreadsheet .row {
  margin-left: 0px;
  margin-right: 0px;
}
#data_table table tr th {
        position: sticky;
        top: 0;
        z-index: 900;
}

This is my full code in the main app.py (excl. some imported modules).

import dash
from dash import dcc
from dash import html
from dash.dependencies import Input,Output
from dash import dash_table
import pandas as pd
import dash_bootstrap_components as dbc
from imdb import url_parser

app=dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP],
#following line with meta-tags allows the content to be viewable on mobile devices 
meta_tags=[{"name":"viewpoints","content":"width=device-width,initial-scale=1.0"}])

app.layout=dbc.Container([
    html.Div([
        html.H1(
            "Test Dashboard with Dash",
            style={
                "text-align":"center",
                "color":"#503D36",
                "font-size": 40
            }
        ),
        html.Div(id="memory-output1",style={"display":"none"})
    ]),
    html.Br(),
    dcc.Dropdown(
        id="list1",
        options=[
            {"label":"Movies","value":"Movies"},
            {"label":"Series","value":"Series"},
            {"label":"Cartoons","value":"Cartoons"},
            {"label":"Anime","value":"Anime"}
        ],
        style={'color': 'black'}
    ),
    html.Br(),
    html.Div(id="data_table"),
],fluid = True)

@app.callback(
    Output("data_table","children"),
    Input("list1","value"),
    prevent_initial_call=True
)

def store_data(dropdown_value):
    if dropdown_value=="Movies":
        url="https://www.imdb.com" #parse via imported module
        data=url_parser(url)
        data_table=dash_table.DataTable(
            columns=[{'name': i, 'id': i} for i in data.columns],
            data=data.to_dict("records"),
            filter_action="native",
            sort_action="native",
            sort_mode="single",
            # fixed_columns={'headers': True,'data': 1},
            # fixed_rows={'headers': True},
            page_action="native",
            page_current=0,
            page_size=100,
            style_table={"overflowY":"auto"},
            style_header={"backgroundColor":"rgb(153, 203, 255)","fontWeight":"bold"},
            style_cell={"backgroundColor":"rgb(239, 239, 243)","font-family": "Arial"},
            style_as_list_view=True
        )
    elif dropdown_value=="Series":
        url="https://www.imdb.com"
        data=url_parser(url) #parse via imported module
        data_table=dash_table.DataTable(
            columns=[{'name': i, 'id': i} for i in data.columns],
            data=data.to_dict("records"),
            filter_action="native",
            sort_action="native",
            sort_mode="single",
            # fixed_columns={'headers': True,'data': 1},
            # fixed_rows={'headers': True},
            page_action="native",
            page_current=0,
            page_size=100,
            style_table={"overflowY":"auto"},
            style_header={"backgroundColor":"rgb(153, 203, 255)","fontWeight":"bold"},
            style_cell={"backgroundColor":"rgb(239, 239, 243)","font-family": "Arial"},
            style_as_list_view=True
        )
    elif dropdown_value=="Cartoons":
        url="https://www.imdb.com" 
        data=url_parser(url) #parse via imported module
        data_table=dash_table.DataTable(
            columns=[{'name': i, 'id': i} for i in data.columns],
            data=data.to_dict("records"),
            filter_action="native",
            sort_action="native",
            sort_mode="single",
            # fixed_columns={'headers': True,'data': 1},
            # fixed_rows={'headers': True},
            page_action="native",
            page_current=0,
            page_size=100,
            style_table={"overflowY":"auto"},
            style_header={"backgroundColor":"rgb(153, 203, 255)","fontWeight":"bold"},
            style_cell={"backgroundColor":"rgb(239, 239, 243)","font-family": "Arial"},
            style_as_list_view=True
        )
    elif dropdown_value=="Anime":
        url="https://www.imdb.com"
        data=url_parser(url) #parse via imported module
        data_table=dash_table.DataTable(
            columns=[{'name': i, 'id': i} for i in data.columns],
            data=data.to_dict("records"),
            filter_action="native",
            sort_action="native",
            sort_mode="single",
            # fixed_columns={'headers': True,'data': 1},
            # fixed_rows={'headers': True},
            page_action="native",
            page_current=0,
            page_size=100,
            style_table={"overflowY":"auto"},
            style_data={
                'width': '150px', 'minWidth': '150px', 'maxWidth': '150px',
                'overflow': 'hidden',
                'textOverflow': 'ellipsis',
            },
            style_header={"backgroundColor":"rgb(153, 203, 255)","fontWeight":"bold"},
            style_cell={"backgroundColor":"rgb(239, 239, 243)","font-family": "Arial"},
            style_as_list_view=True
        )
    return data_table

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

@mrel,

I altered the data_table style_table to be this:

style_table={"overflowY":"auto",'maxHeight':'75vh'},

This made it fit my screen. With a scroll bar and the pages showing at the bottom. I also had to make a change the to css for the position.

.dash-spreadsheet table tr th {
        position: sticky;
        top: 0;
        z-index: 900;
}

@jinnyzor , worked like a charm. Thank you!
I didn’t know about 'maxHeight':'75vh'. Was interesting to learn about it. I also changed it to 85hv as when it was 75 it was leaving an empty space at the bottom of the table after the table.
Thank you!