Dash Datatable - Pagination Button positioning Error

Hello,

First of all, I’m a great fan of Dash. It is amazing and I.m learning everyday about it.
Currently I got stuck with a problem for few days and looking a working solution for it.
I’m populating a Dash datatable but the pagination buttons are not placed correctly. I’m using Dash login framework and added a new page where the datatable resides.

Scenario 1:

  1. The datatable is loaded with pagination_mode=‘be’ [Ref: https://dash.plot.ly/datatable/callbacks]. With the update_table(pagination_settings) callback, it is loading the data. But the pagination buttons are placed after the first row. So if the table is having more than one row, the buttons are been covered by the rows and become invisible (unless you delete all the rows):

***With page size set as 3

***With rows deleted:

  1. If pagination_mode=‘fe’ is been used [Ref: https://dash.plot.ly/datatable/interactivity] along with callback, then it does not load any data in the table and no pagination button as well.

I’m not sure what I’m doing wrong. I tried to change possible all the CSS (classname) to make the desired effect and failed shamelessly before raising this request in here. Could somebody please help!

Below is the code for the same:

USER_TABLE.py

import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State

from server import app, User
from flask_login import current_user
from werkzeug.security import check_password_hash

import dash
import dash_table
import pandas as pd
import sqlite3
import users_mgt

conn = sqlite3.connect("users.db", check_same_thread=False)
df = pd.read_sql_query("select username, email, (select replace(password, (select password from user), '****') from user) as password from user;", conn)



PAGE_SIZE = 3

layout = html.Div(
                            id='editable_datatable_container',
                            className="datatable-container",
                            n_clicks=0,
                            style={'text-transform':'uppercase'},
                            children=[
                            dash_table.DataTable(
                                id='editable-table',
                                columns=[{"name": i, "id": i, 'deletable': True} for i in df.columns],
                                data=df.to_dict('records'),
                                pagination_mode='fe',
                                editable=True,
                                row_selectable='multi',
                                row_deletable=True,
                                style_cell={'textAlign': 'left'},
                                style_cell_conditional=[
                                  {
                                     'if': {'row_index': 'odd'},
                                     'backgroundColor': 'rgb(248, 248, 248)'
                                   }
                                ],
                               style_header={
                                    'backgroundColor': 'rgb(248, 248, 248)',
                                    'fontWeight': 'bold'
                                },
                                style_data_conditional=[{
                                    "if": {"row_index": 1},
                                    "backgroundColor": "rgb(0, 151, 58)",
                                    'color': 'white'
                                }],
                                pagination_settings={
                                    'current_page': 0,
                                    'page_size': PAGE_SIZE,
                                },
                                css=[
                                    { 'selector': '.previous-page, .next-page', 'rule': 'background-color: rgb(0, 151, 58);' }
                                 ],
                                #navigation="page",
                              ),
                             dcc.ConfirmDialog(
                             id='confirm',
                             message='Danger danger! Are you sure you want to continue?',
                             ),
                               html.Div(id='output')
                             ] 
                          ),




#Datatable Pagination
@app.callback(
    Output('editable-table', 'data'),
    [Input('editable-table', 'pagination_settings')])
def update_table(pagination_settings):
    return df.iloc[
        pagination_settings['current_page']*pagination_settings['page_size']:
        (pagination_settings['current_page'] + 1)*pagination_settings['page_size']
    ].to_dict('records')


    
# Callback for making datatable editable 

@app.callback(Output('output', 'children'),
              [Input('editable-table', 'data_previous')],
              [State('editable-table', 'data')])
def show_removed_rows(previous, current):
    if previous is None:
        print ('No previous row is selected')
        dash.exceptions.PreventUpdate()
    else:
        #return [f'Just removed {row}' for row in previous if row not in current]
        if current_user.username == 'admin':
            return 'User deleted successfully'
        else:
            #return 'You do not have sufficient permission to delete user'
            return ''
        return ''

This USER_TABLE is been embedded within the Dash login framework which looks like this [app.py]:

index page

import os
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

from server import app, server
from flask_login import logout_user, current_user
from views import success, dashboard, login, login_fd, logout, user, user_table


header = html.Div(
    className='header',
    children=html.Div(
        className='header-width',
        style={'height': '100%', 'width': '95%', 'margin-left':'auto', 'margin-right':'auto'},
        children=[
            html.Img(
                src='assets/Marvin-Banner.svg',
                className='logo'
            ),
            html.Div(className='links', children=[
                html.Div(id='dashboard', className='link'),
                html.Div(id='add-user', className='link'),
                html.Div(id='user-name', className='link'),
                html.Div(id='logout', className='link')
            ])
        ]
    )
)

app.layout = html.Div(
    [
        header,
        html.Div([
            html.Div(
                html.Div(id='page-content', className='content'),
                className='content-container',
            ),
        ], className='container-width-body', style={'height': '100%', 'width': '97%', 'margin-left':'auto', 'margin-right':'auto'},), 
        dcc.Location(id='url', refresh=False),  
    ]
)
app.config.supress_callback_exceptions = True

@app.callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/':
        return login.layout
    elif pathname == '/login':
        return login.layout
    elif pathname == '/dashboard':
        if current_user.is_authenticated:
            return dashboard.layout
        else:
            return login_fd.layout
    elif pathname == '/logout':
        if current_user.is_authenticated:
            logout_user()
            return logout.layout
        else:
            return logout.layout
    elif pathname == '/user':
        if current_user.is_authenticated:
            return user.layout
        else:
            return login.layout
    else:
        return '404'


@app.callback(
    Output('user-name', 'children'),
    [Input('page-content', 'children')])
def cur_user(input1):
    if current_user.is_authenticated:
        return html.Div('Signed in: ' + current_user.username)
        # 'User authenticated' return username in get_id()
    else:
        return ''



@app.callback(
    Output('add-user', 'children'),
    [Input('page-content', 'children')])
def add_user(input1):
    if current_user.is_authenticated:
       return html.A('Users', href='/user')
    else:
        return ''
  

if __name__ == '__main__':
    #app.run_server(debug=True)
    port = int(os.getenv('PORT', 8050))
    app.run_server(debug=True, host='0.0.0.0', port=port, threaded=True)

Hello,

Any help in here please?
Could someone would be kind enough to look into this?

Best Regards,
Swapratim Roy

1 Like