Implement Pagination on Dash Bootstrap Table Component

Nur Yaumi
2 min readSep 17, 2023

--

When I built an analytic dashboard using Python Dash, I found a problem with the data table. I used dash-bootstrap table component but I didn’t find any documentation about how to implement pagination on the table. Dash actually has a default component called data_table to load data into the table and we can set up the pagination, but I’m not too fond of the Dash data_table style and it’s too hard to modify the table styling.

So I did some research and finally found the solution. I generally use Dash callback to get the active page from dash-bootstrap component and filter the data based on the active page, then load the data into dash-bootstrap table component.

Here’s the step-by-step:

Create a function to get the total page based on page size. I create a constant variable to set page size.

def get_total_page(page_size, total_data):
data_div_page_size = total_data // page_size
data_mod_page_size = total_data % page_size
total_page = data_div_page_size if data_mod_page_size == 0 else (data_div_page_size+1)

return total_page

Create a function to load data into dash-bootstrap table component

def get_student_score_list(scores, counter):

table_header = [
html.Thead(
html.Tr([
html.Th("No."),
html.Th("Math Score"),
html.Th("Reading Score"),
html.Th("Writing Score"),
html.Th("Avg Score"),
])
)
]

table_rows = []
for score in scores:
table_row = html.Tr([
html.Td(counter),
html.Td(score['MathScore']),
html.Td(score['ReadingScore']),
html.Td(score['WritingScore']),
html.Td(score['avg_score']),
])
table_rows.append(table_row)
counter += 1

table_body = [html.Tbody(table_rows)]
table = dbc.Table(table_header + table_body, striped=True, bordered=True, hover=True, className='p-3')

return table

Create table component on Dash layout. Each component table and pagination should have an ID, which we will use on the callback function.

dbc.Row(
[
dbc.Table(id="score-list"),
dbc.Pagination(id="pagination", max_value=get_total_page(PAGE_SIZE, 100), fully_expanded=False),
]
)

Then create the callback function to update data on the table based on the active page in the pagination component.

# load data source
df = pd.read_csv('data/data.csv')
top_100_scores = df.sort_values(by='avg_score', ascending=False).head(100).to_dict('records')

# create callback
@callback(
Output('score-list', 'children'),
Input('pagination', 'active_page'),
)
def update_list_scores(page):

# convert active_page data to integer and set default value to 1
int_page = 1 if not page else int(page)

# define filter index range based on active page
filter_index_1 = (int_page-1) * PAGE_SIZE
filter_index_2 = (int_page) * PAGE_SIZE

# get data by filter range based on active page number
fitler_scores = top_100_scores[filter_index_1:filter_index_2]

# load data to dash bootstrap table component
table = get_student_score_list(fitler_scores, (filter_index_1 + 1))

return table

And here’s the result

Dash data_table has a lot of functionality than dash-bootstrap table component, but if I only need to show the list of the data without any complex interactivity, I will choose to use dash-bootstrap because of the table visual :D

Thank You for reading ^.^

Github source code: https://github.com/yaumianwar/student-exam-score-dashboard

--

--