AG Grid: Column with checkbox (boolean value)?

Hi!

I’ve been checking out the new dash Ag grid feature which soon will come to the “free” part of Dash (not only enterprise). The tables are really good looking and feels good BUT I’ve tried to create a Ag grid table where one column is checkboxes that holds a boolean True/False value without success.

Here’s a example showing what I want:

Is there a way of doing this? In Javascript you can use the “cellRenderer:” from what I’ve understood. Will this function be available for us dash users?

1 Like

Hello @Mackan,

Yes, the goal is to allow for things like this. Hopefully, we will be able to do so.

We are working hard to make sure that the application is as secure as possible. :grin:

1 Like

Yes, thats great. We are looking forward to it :slight_smile:

Hi @Mackan

We are working toward adding more components and/or making it easier to add custom components. In the meantime, a workaround might be to use the row selection feature. Note that the checkboxs can be in any column:

If you clone dash-ag-grid and run docs/app.py, you will find this app in the “Selections” section

import dash

import dash_ag_grid as dag
from dash import Dash, html, dcc, Input, Output
import requests

app = Dash(__name__)


data = requests.get(
    r"https://www.ag-grid.com/example-assets/olympic-winners.json"
).json()


columnDefs = [
    {"field": "athlete", "checkboxSelection": True, "headerCheckboxSelection": True},
    {"field": "age"},
    {"field": "country"},
    {"field": "year"},
    {"field": "date"},
    {"field": "sport"},
    {"field": "gold"},
    {"field": "silver"},
    {"field": "bronze"},
    {"field": "total"},
]

app.layout = html.Div(
    [
        dcc.Markdown("This grid has multi-select rows with checkboxes."),
        dag.AgGrid(
            id="selection-checkbox-grid",
            columnDefs=columnDefs,
            rowData=data,
            columnSize="sizeToFit",
            defaultColDef={"resizable": True, "sortable": True, "filter": True},
            rowSelection="multiple",
        ),
        html.Div(id="selections-checkbox-output"),
    ],
    style={"margin": 20},
)


@app.callback(
    Output("selections-checkbox-output", "children"),
    Input("selection-checkbox-grid", "selectionChanged"),
)
def selected(selected):
    if selected:
        selected_athlete = [s["athlete"] for s in selected]
        return f"You selected athletes: {selected_athlete}"
    return "No selections"


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


RowMenu Component
I know it’s not what you looking for exactly, but just so you know it’s available:

import dash_ag_grid as dag
import dash
from dash import Input, Output, html, dcc

app = dash.Dash(__name__)


row_menu_example = html.Div(
    [
        dcc.Markdown(
            "Custom menus can be added to rows by specifying menu options with  labels & values. Row metadata and the selected option from a menu are accessible in callbacks."
        ),
        dag.AgGrid(
            id="cell-renderer-table",
            columnSize="sizeToFit",
            columnDefs=[
                {"headerName": "Make", "field": "make", "sortable": True},
                {"headerName": "Model", "field": "model"},
                {"headerName": "Price", "field": "price"},
                {"headerName": "Menu", "field": "menu", "cellRenderer": "rowMenu"},
            ],
            rowData=[
                {
                    "make": "Toyota",
                    "model": "Celica",
                    "price": 35000,
                    "menu": [
                        {"label": "Option 1", "value": 1},
                        {"label": "Option 2", "value": 2},
                        {"label": "Option 3", "value": 3},
                    ],
                },
                {
                    "make": "Ford",
                    "model": "Mondeo",
                    "price": 32000,
                    "menu": [
                        {"label": "Option 4", "value": 4},
                        {"label": "Option 5", "value": 5},
                        {"label": "Option 6", "value": 6},
                    ],
                },
                {
                    "make": "Porsche",
                    "model": "Boxter",
                    "price": 72000,
                    "menu": [
                        {"label": "Option 7", "value": 7},
                        {"label": "Option 8", "value": 8},
                        {"label": "Option 9", "value": 9},
                    ],
                },
            ],
        ),
        html.P(id="click-data"),
        html.Hr(),
    ]
)

app.layout = html.Div(
    row_menu_example,
    style={"flexWrap": "wrap"},
)


@app.callback(
    Output("click-data", "children"),
    Input("cell-renderer-table", "clickData"),
)
def show_click_data(clickData):
    if clickData:
        return "You selected option {} from the row with make {}, model {}, and price {}.".format(
            clickData["value"],
            clickData["data"]["make"],
            clickData["data"]["model"],
            clickData["data"]["price"],
        )
    return "No menu item selected."


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

Is there any way to have multiple checkboxes per row, but only one gets selected when you click it? Currently if you check one box then all the boxes in the row are checked. I have tried adding dashGridOptions={‘suppressRowClickSelection’: True, ‘suppressRowDeselection’: True} but it doesn’t appear to help.

This would basically be independent checkboxes per row.

Hello @Croll12,

This is available via a custom component for the cellRenderer.

Check the Boolean column renderer.

Thank you, but I don’t think I explained it fully. Currently I am using a Dash DataTable and ‘tricking’ the table to think it is a checkbox. Basically just unicode to appear as checked or unchecked on click. I would like to change over to aggrid but I don’t see an easy way to render the multi header lines. The data is 3 levels deep as you see in the image below, so I have the checkbox and data grouped on the year. I am able to do this in Dash with merge_duplicate_headers=True. Is there anything similar in aggrid?

Yes. You can have grouped headers and then children of the groups, which are also columnDefs.

I am trying that but do not see the expected outcome. I am using the example under column groups and added a 3rd level. This now has 3 rows in the header. I am trying to get only 2 rows in the header. Header 2020 should be on the 2nd row, but have two columns below it. This is where merge duplicate headers came in, I would name both columns as ‘A’ and dash would merge them without displaying a blank header row. Even setting ‘field’: ‘’ displays a blank column header.

BlockquotecolumnDefs= [
{
‘headerName’: ‘Athlete Details’,
‘children’: [
{ ‘field’: ‘athlete’ },
{ ‘field’: ‘age’ },
{ ‘field’: ‘country’ },
]
},
{
‘headerName’: ‘Sports Results’,
‘children’: [
{ ‘field’: ‘sport’ },
{ ‘field’: ‘total’, ‘columnGroupShow’: ‘closed’ },
{‘headerName’: ‘2020’, ‘children’ :[{‘field’: ‘A’, ‘columnGroupShow’: ‘open’}, {‘field’: ‘B’, ‘columnGroupShow’: ‘open’}]},
{ ‘field’: ‘gold’, ‘columnGroupShow’: ‘open’ },
{ ‘field’: ‘silver’, ‘columnGroupShow’: ‘open’ },
{ ‘field’: ‘bronze’, ‘columnGroupShow’: ‘open’ },
]
}
]

Blockquote

Is it possible to hide the last header row?

Try setting the height like this:

       dag.AgGrid(            
            dashGridOptions={"headerHeight":0, "groupHeaderHeight":50},
            # other props
        )

For more info see:
Ag Grid docs: https://ag-grid.com/react-data-grid/column-headers/
Dash AG Grid docs: Dash

2 Likes

That works great, thanks!

2 Likes