I did it. Switched it to the new dash_mantine_components.Select and used creatable=True, works a treat now.
It’s very extensible this whole Dash AG Grid thing, love it!
dagfuncs.DMC_Select = class {
// gets called once before the renderer is used
init(params) {
// create the cell
this.params = params;
this.ref = React.createRef();
// function for when Dash is trying to send props back to the component / server
var setProps = (props) => {
if (typeof props.value != typeof undefined) {
// updates the value of the editor
this.value = props.value;
// re-enables keyboard event
delete params.colDef.suppressKeyboardEvent
// tells the grid to stop editing the cell
params.api.stopEditing();
// sets focus back to the grid's previously active cell
this.prevFocus.focus();
}
}
this.eInput = document.createElement('div')
// renders component into the editor element
ReactDOM.render(React.createElement(window.dash_mantine_components.Select, {
data: params.options, value: params.value, ref: this.ref, setProps, style: {width: params.column.actualWidth},
className: 'dbc',
clearable: true,
searchable: true,
creatable: true
}), this.eInput)
// allows focus event
this.eInput.tabIndex = "0"
// sets editor value to the value from the cell
this.value = params.value;
}
// gets called once when grid ready to insert the element
getGui() {
return this.eInput;
}
focusChild() {
// needed to delay and allow the component to render
setTimeout(() => {
var inp = this.eInput.getElementsByClassName('mantine-Select-input')[0]
inp.tabIndex = '1';
// disables keyboard event
this.params.colDef.suppressKeyboardEvent = (params) => {
const gridShouldDoNothing = params.editing
return gridShouldDoNothing;
}
// shows dropdown options
inp.focus();
}, 100)
}
// focus and select can be done after the gui is attached
afterGuiAttached() {
// stores the active cell
this.prevFocus = document.activeElement
// adds event listener to trigger event to go into dash component
this.eInput.addEventListener('focus', this.focusChild())
// triggers focus event
this.eInput.focus();
}
// returns the new value after editing
getValue() {
return this.value;
}
// any cleanup we need to be done here
destroy() {
// sets focus back to the grid's previously active cell
this.prevFocus.focus();
}
}
2 Likes
Hi @alistair.welch
Thanks for sharing this great custom cell editor component! I just added it to the Dash AG Grid docs.
I made a couple minor edit to make it even easier to use from Dash. You can now copy and paste the component into the dashAgGridFunctions.js
file in the assets folder, then pass props to the dmc.Select component using the cellEditorParams
prop. No need to write any JavaScript!
See the code for these examples in the docs:


2 Likes
That’s really awesome, definitely the thanks have to go to @jinnyzor for making it work!
My personal preference is to use it with clearable=True
and set up a callback from cellValueChanged to columnDefs so that any new entries added using creatable
are added to the options but with the way you’ve set it up with all the params going in I’m sure people can figure that out for themselves. And I imagine there’ll be other cellEditors people will be able to make using the ReactDOM.render
system that Bryan wrote for this.
Exciting stuff, thanks for putting so much effort into this 
2 Likes
@AnnMarieW @How to set the length and width of dmc.select to be the same as the length and width of the cell?
Hi Sylvos, you’ll need to include style: {width: params.column.actualWidth} in the JavaScript file. If you look at the post at the top of this thread it’s in there
1 Like
Hello All,
So, making an adjustment to the disabling of keyboard events, this helps the drop down be a little more intuitive, also allows for better keyboard navigation:
// disables keyboard event
this.params.colDef.suppressKeyboardEvent = (params) => {
const gridShouldDoNothing = params.editing && !(window.event.key == 'Tab' ||
window.event.key == 'Escape');
return gridShouldDoNothing;
};
One other slight modification for the style, I do this:
style: {width: params.column.actualWidth-2, ...params.style},
This helps when navigating the drop downs in edit mode, if the dropdown is the exact size of the column and you moving to the column caused the grid to scroll to a previously undisplayed column, the dropdown was rendered behind the column instead of in front. Dropping it 2, maybe even 1, seems to patch this and get it to work.
1 Like
Tacking on another trick, when using Mantine editors and components, there is a case where they will not follow the styling, here is a little trick:
function mantineWrapper(component) {
return React.createElement(window.dash_mantine_components.MantineProvider,
{
children: component,
theme: {'colorScheme': document.body.classList.contains('dark') ? 'dark' : 'light'}
}
)
}
For this to work, you need to have a clientside callback hooked to your theme switcher that will add the dark class to your document.body when it is in dark mode.
Then you just do this:
// renders component into the editor element
ReactDOM.render(
mantineWrapper(
React.createElement(window.dash_mantine_components.DatePicker, {
setProps,
...params,
value: this.value,
style: {width: params.column.actualWidth-2, zIndex: 1000, ...params.style},
})),
this.eInput
);

2 Likes
Another trick:
When using things like select, you’ll want the user to be able to navigate and select options via the keyboard. This gets frustrating when trying to push “Enter” because the event bubbles and stops the edit from manifesting in the cell.
var keyDown = (e) => {if (e.key == 'Enter') {e.stopPropagation()}}
...component(onKeyDown: keyDown)
This will prevent the event from bubbling outside to the grid and allow the component to finish passing the updated value to the cell.
2 Likes