Search code examples
pythoncallbackplotly-dash

Dash callback active cell only on specific column


I am using the callback as below to open a modal when clicking on any cell in my Dash DataTable. However, instead of every cell opening the modal, I only want the modal to open when I click on a cell in the first column. Any tips on how to apply this callback only to the active cells in the first column?

@app.callback(Output('modal', 'is_open'),
              [Input('Data_Table', 'active_cell'),
               Input('close', 'n_clicks')],
              [State("modal", "is_open")])
def toggle_modal(n1, n2, is_open):
    if n1 or n2:
        return not is_open
    return is_open

Solution

  • You can access the position of the active cell in data tables like this:

    active_cell['column'] # column number (int)
    active_cell['row'] # row number (int)
    active_cell['column_id'] # column name (str)
    

    Here's a full working example where the value of a cell from only the first column is returned in the modal when that cell is clicked:

    from dash import Dash, html, Input, Output, State, dash_table, no_update
    import dash_bootstrap_components as dbc
    import pandas as pd
    
    df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/solar.csv')
    
    app = Dash(__name__,external_stylesheets=[dbc.themes.BOOTSTRAP])
    
    modal = html.Div(
        [
            dbc.Modal(
                [
                    dbc.ModalHeader(dbc.ModalTitle("Header")),
                    dbc.ModalBody(id='modal-body'),
                    dbc.ModalFooter(
                        dbc.Button(
                            "Close", id="close", className="ms-auto", n_clicks=0
                        )
                    ),
                ],
                id="modal",
                is_open=False,
            ),
        ]
    )
    
    app.layout = html.Div(
        [
            modal,
            dash_table.DataTable(id='datatable',data=df.to_dict('records'), columns=[{"name": i, "id": i} for i in df.columns])
    
        ]
    )
    
    @app.callback(
        [Output('modal','is_open'),Output('modal-body','children')],
        Input('datatable','active_cell'),
        State("modal", "is_open")
    
    )
    def open_modal(active_cell,is_open):
        if active_cell['column'] == 0:
            return [not is_open, df[active_cell['column_id']][active_cell['row']]]
        return [no_update,no_update]
    
    
    if __name__ == '__main__':
        app.run(debug=True)