Checkbox column in Dash AG Grid

Hello,

I would like to use the dash ag grid to display a data frame, and I would like one of the boolean columns to show as a checkbox.

I would like the checkbox to be editable, so that the user can change the value by checking/unchecking.

This is different than the “checkbox as selector” example in the documentation, because I want the checkbox to display the boolean value, regardless of whether the row is selected.

Is this possible, and if so, can someone point me at an example?
Thanks!

Hello @zack_nc,

Sure, this is available, check out here:

In AG Grid, v30, this will be inferred, we havent released v30 yet as this will cause some issues with the docs not working quite right, and potentially wreck havoc on developers unless they know to watch out for. In inferring that something is Boolean, they will automatically put a checkbox.

2 Likes

hello @jinnyzor ,
As an extensive application, is it possible to change checkbox to “toggle switch” and the switch will change to On/Off when the user clicks on it?
Thank you in advance.

Hello @wen,

Welcome to the community!

You mean something like this?

Yes, you should be able to use any already made dash component following the same pattern. :grin:

hi @jinnyzor ,

Thank you!! I’m glad being part of community :grinning:

Yes, I want to use the Switch component like you show as a whole column.
I’m trying to mimic React code in Cell Renderer Components (Cell Renderer Components | Dash for Python Documentation | Plotly) but I fail to find out feasible solution.
Following are two main approaches I tried, it would be nice if you can share some comments or any code details. Thank you very much :slight_smile:

Approach 1: Following Example 3: Cell Renderer with dbc.Button and change Button to Switch
So my React code is revised as follows but switch has no change to On/Off when I click on it.

var dagcomponentfuncs = window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {};

dagcomponentfuncs.DBC_Button_Simple = function (props) {
const {setData, data} = props;

function onClick() {
    setData();
}
return React.createElement(
    window.dash_bootstrap_components.**Switch**,
    {
        onClick: onClick,
        color: props.color,
    },
    props.value
);

};

Approach 2: Following Example 6: Including extra data in cellRenderData and add customize checkbox as switch so my idea is to add classname to input, but not really sure how to achieve this…

Hi @wen

Here is an example of using a dbc.Switch component in Dash AG Grid

import json
import dash_ag_grid as dag
from dash import Dash, html, dcc, Input, Output, callback
import pandas as pd
import dash_bootstrap_components as dbc



data = {
    "ticker": ["AAPL", "MSFT", "AMZN", "GOOGL"],
    "company": ["Apple", "Microsoft", "Amazon", "Alphabet"],
    "price": [154.99, 268.65, 100.47, 96.75],
    "buy": [False, True, True, True],
}
df = pd.DataFrame(data)

columnDefs = [
    {
        "headerName": "Stock Ticker",
        "field": "ticker",
    },
    {"headerName": "Company", "field": "company", "filter": True},
    {
        "headerName": "Last Close Price",
        "type": "rightAligned",
        "field": "price",
        "valueFormatter": {"function": """d3.format("($,.2f")(params.value)"""},
        "editable": True,
    },
    {
        "field": "buy",
        "cellRenderer": "DBC_Switch",
        "cellRendererParams": {"color": "success"},
    },
]


defaultColDef = {
    "resizable": True,
    "sortable": True,
    "editable": False,
}


grid = dag.AgGrid(
    id="dbc-switch-grid",
    columnDefs=columnDefs,
    rowData=df.to_dict("records"),
    columnSize="autoSize",
    defaultColDef=defaultColDef,
    dashGridOptions={"rowHeight": 48},
)


app = Dash(__name__, external_stylesheets=[dbc.themes.SPACELAB])

app.layout = html.Div(
    [
        dcc.Markdown("Example of cellRenderer with custom dash-bootstrap-components Switch "),
        grid,
        html.Div(id="dbc-switch-value-changed"),
    ],
    style={"margin": 20},
)


@callback(
    Output("dbc-switch-value-changed", "children"),
    Input("dbc-switch-grid", "cellRendererData"),
)
def showChange(n):
    return json.dumps(n)


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


"""
Put the following in the dashAgGridComponentFunctions.js file in the assets folder

---------------

var dagcomponentfuncs = window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {};


// custom component to display boolean data as a DBC Switch
dagcomponentfuncs.DBC_Switch = function (props) {
    const {setData, value} = props;

    // updated the dbc component
    setProps = ({value}) => {
       // update the grid
        props.node.setDataValue(props.column.colId, value);
        // update to trigger a dash callback
        setData(value)
    }

    return React.createElement(
        window.dash_bootstrap_components.Switch, {
            value: value,
            checked: value,
            setProps,
            style: {"paddingTop": 6},
        }
    )
};


"""


Hi @AnnMarieW ,

Thank you very much!!! It works perfectly :heart_eyes:

I’m new to React and from what I understand, the current method can only update one component per click, is that correct? The reason I ask is because I’m also trying to create a radio button column so that users can only select one row at a time. However, based on my understanding of the React part, it only sets the data value to the clicked colID. Is it possible to get all colIDs and set the value for all of them? Or do you have any suggestions on how to implement a radio button?

Hi @wen

To select a single row, it’s not necessary to make a custom component.

In the columnDefs, you can set: { "checkboxSelection": True} on a column to show a checkbox.

Then to select only a single row, set:

 dashGridOptions={"rowSelection":"single"},

You can find more information in the Selection section of the Dash AG Grid docs, starting with this page:

Try running this example:



import dash_ag_grid as dag
from dash import Dash, html, dcc, Input, Output, callback
import pandas as pd

app = Dash(__name__)


df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)


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

app.layout = html.Div(
    [
        dcc.Markdown("This grid has single-select rows."),
        html.Div(id="selections-single-output"),
        dag.AgGrid(
            id="selection-single-grid",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            columnSize="sizeToFit",
            defaultColDef={"resizable": True, "sortable": True, "filter": True, "minWidth": 125},
            dashGridOptions={"rowSelection":"single"},
        ),
    ],
    style={"margin": 20},
)


@callback(
    Output("selections-single-output", "children"),
    Input("selection-single-grid", "selectedRows"),
)
def selected(selected):
    if selected:
        return f"You selected: {selected[0]}"
    return "No selections"


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



Hi @AnnMarieW ,

I see!!! Thank you very much :smiling_face_with_three_hearts:

1 Like

4 posts were split to a new topic: Customized Selections (Allowing for Single / Multiple dependent upon column)

Hi @AnnMarieW ,

Thanks for your help, your answer works perfectly for me.
Now I’m facing a new challenge which is to make a cell using textarea but I fail to keep placeholder value when users change cell value.
Moreover, as an extension, I’m trying to save the value of users’ input textarea as new tags, and I want the AG Grid table to load those saved tags as new cell values but the placeholder still keeps the original value (to remind users when they forget original value).
I imagine it might be necessary to give two values (one is for value and the other is for placeholder) to the textarea but I don’t know how to achieve that using Dash AG Grid.
Do you have any suggestions for me? Thank you in advance.

dagcomponentfuncs.TextArea = function (props) {
     return React.createElement(
        'textarea', {
            value: props.value,
            placeholder: props.placeholder,
        }
    )
};

Hi @wen
I’m not sure I understand your question. Can you please provide more details, including some type of minimal example to illustrate? And since this is a new topic, can you create a new post?

Hi @AnnMarieW ,

Sorry for bringing you any inconvenience.
I created a new post shown in follows and FYI to you.

I appreciate your kindness. Thank you.

1 Like