dmc.MultiSelect as Dash AG Grid custom component

Hey guys,

I am trying to create a multiple choice dropdown for my dash ag grid table, and found dmc.MultiSelect as a good option.

In my dashAgGridComponentFunctions.js file I have the following code:

//dmc select componenet

dagcomponentfuncs.CustomMultiSelect = function (props) {
    const {setData, data} = props;
    const [selectedOptions, setSelectedOptions] = React.useState(Array.isArray(data) ? data : []);

    function onChange(value) {
        setSelectedOptions(value);
        setData(value);
    }

    return React.createElement(
        window.dash_mantine_components.MultiSelect,
        {
            data: ['a', 'b', 'c'],
            value: selectedOptions,
            onChange: onChange,
            placeholder: "Select options",
        }
    );
};

and I reference the component in my dash ag grid table like this:

columnDefs = [
    {
        "headerName": "Options",
        "cellRenderer": "CustomMultiSelect",
    },
]

dash_ag_grid.AgGrid(
                                        id="my-table",
                                        dashGridOptions={
                                            "rowHeight": 120,
                                            "rowSelection": "multiple",
                                            "undoRedoCellEditing": True,
                                            "suppressRowTransform": True,
                                        },
                                        columnDefs=columnDefs,
                                        defaultColDef={
                                            "flex": 1,
                                            "sortable": True,
                                            "filter": True,
                                        },
                                    )

I can see the options, but I cannot choose/select anything. Any idea what am I doing wrong? Thanks!

1 Like

Hello @kjurukova,

Yes, adding dash components are a little more tricky when working inside the context of the grid.

You need to tie in the setProps to update the data for the cell, I don’t think the onChange does anything because it’s not your typical select.

Basically, use the setProps and then check if the value changes, if so, use setData.

Thank you very much @jinnyzor !!!
Worked like this:

dagcomponentfuncs.CustomMultiSelect = function (props) {
    const {setData, data} = props;
    const [selectedOptions, setSelectedOptions] = React.useState(Array.isArray(data) ? data : []);

    function onChange(value) {
        setSelectedOptions(value);
        setData(value);
    }

    function setProps(value){
        data: value;
    }

    return React.createElement(
        window.dash_mantine_components.MultiSelect,
        {
            data: ['a', 'b', 'c'],
            value: selectedOptions,
            onChange,
            setProps,
            placeholder: "Select options",
        }
    );
};
2 Likes

Hello,

I’d like to do the same thing, but I can’t provide the list of possible choices.

Here’s a basic example of an app I can’t get to work :

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

df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/wind_dataset.csv")
df.loc[:, 'direction'] = 'S'

app = Dash(__name__)

columnDefs = [
    {"field": "id", "hide": True},
    {'field': 'direction', 'editable': True, "cellRenderer": "CustomMultiSelect",
     'cellEditorParams': {'value': ["N", "S", "E", "W"]}},
{'field': 'strength', 'editable': False},
{'field': 'frequency', 'editable': False},
]

grid = dag.AgGrid(
    id="get-started-example-basic",
    rowData=df.to_dict("records"),
    columnDefs=columnDefs,
)

app.layout = html.Div([grid])

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

The dashAgGridComponentFunctions.js file contains :

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


dagcomponentfuncs.CustomNoRowsOverlay = function (props) {
    return React.createElement(
        'div',
        {
            style: {
                border: '1pt solid grey',
                color: 'grey',
                padding: 10,
                fontSize: props.fontSize
            },
        },
        props.message
    );
};


dagcomponentfuncs.CustomMultiSelect = function (props) {
    const {setData, data} = props;
    const [selectedOptions, setSelectedOptions] = React.useState(Array.isArray(data) ? data : []);

    function onChange(value) {
        setSelectedOptions(value);
        setData(value);
    }

    function setProps(value){
        data: value;
    }

    return React.createElement(
        window.dash_mantine_components.MultiSelect,
        {
            data: ['a', 'b', 'c'],
            value: selectedOptions,
            onChange,
            setProps,
            placeholder: "Select options",
        }
    );
};

Thank you for your help.

Is it possible to have a very simple working example?
Because I’m still stuck.

Thanks

I’ve found the solution.
All I had to do was copy the Select example here:
https://dashaggrid.pythonanywhere.com/components/cell-editor-components
by changing the Select element to MultiSelect and deleting the filterDataOnExactSearchMatch attribute.

4 Likes

Yes. The cellEditor is easier to use than the cellRenderer. The issue was that your component wasn’t showing up because of being contained inside of the cell.

When you allow for the pop up, it adds it above the grid, so it’s no longer contained inside the cell.

1 Like

Hey @Jocelyn

Could you please share the select example? Seems like to select example was removed :weary:

Hi @kabure

You can find 3 dmc.Select examples here. Note that it currently it uses dmc== 0.12.1

1 Like

Hey @AnnMarieW Thank you so much!

I’ve already understood how it works, and it’s exactly the solution I need… The issues I see are mainly:
1- I need to apply this to the ROWS and not to the COLUMNS;
2 - My list has more than 38k options;

Do you think that is it possible to be applied to my case?

It’s late here now, I will try to implement this tomorrow, but I’m not too confident as I will need to pass the 38k list for each column

Do you know a way that I could load a json file in the .js file? I think that it would avoid the need to set the same list many times

Hey @jinnyzor I am forced to use cell renderer and I am stuck on the same problem where dmc.Select is limited by row height. Would you please help me position the pop up above ag grid? I tried with zIndex but didn’t have any luck. I have a dmc.Modal with Ag Grid inside and inside of said grid I would like to have c.Select. Thanks in advance!

Hello @dashamateur,

You need to set the cellStyle to overflow visible. I think that’s all you need. :grin:

You may run into issues at the bottom.

It didn’t work :pensive: Could it have something to do with my way of rendering cells? I am rendering a string and returning a div element which has dmc.Text and dmc.Select as children. I’ve set up my initial string to have place holders in places where I want dmc.Select component to be.

On using z-index on the dropdown of a dmc.Select, this doesn’t work…

style={"z-index":"10002"}

but this might, if you’ve not tried it…

styles={"dropdown":{"z-index":"10002"}}

You could also try (it works for putting a Select on a Drawer. so might be worth a try here)…

comboboxProps={"withinPortal": False}

I have tried all of the above but with no luck. For some reason the dropdown still has the default z-index 300.

EDIT: Solved it! Defining parameter of dmc.Select dropdownPosition solved the issue. For some reason this was the only thing necessary for dropdown to open. Thank you both for your help!

2 Likes

OK, good you’ve solved it :slight_smile:

You’re using DMC 0.13? The dropdownPosition argument no longer exists in 0.14

DMC 0.12 actually :slight_smile: haven’t got around to updating it yet…

Hi @jinnyzor,

In the case of using cellRendered and dmc.MultiSelect, what would be the solution to make the dropdown popped over the grid?

Thanks

I’m not exactly sure what you mean.

I recommend things with dropdowns to use cellEditorPopup: True