This should get you started:
dynamicOptions = async function (search) {
try {
let response = await fetch('./dynamicOptions', {method: 'POST', headers: {'content-type': 'application/json'}, body: JSON.stringify({'searchValue':search})})
if (!response.ok) {
console.log(`HTTP error: ${response.status}`);
}
const responseData = await response.json();
return responseData;
} catch (e) {
console.log(e);
}
}
dagfuncs.DMC_Select2 = class {
// gets called once before the renderer is used
init(params) {
var options = [];
// create the cell
this.params = params;
// 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();
}
if (typeof props.searchValue != typeof undefined) {
dynamicOptions(props.searchValue).then((opts) =>
ReactDOM.render(
React.createElement(window.dash_mantine_components.Select, {
data: opts,
value: params.value,
setProps,
style: {width: params.column.actualWidth-2, ...params.style},
className: params.className,
clearable: params.clearable,
searchable: params.searchable || true,
creatable: params.creatable,
debounce: params.debounce,
disabled: params.disabled,
filterDataOnExactSearchMatch:
params.filterDataOnExactSearchMatch,
limit: params.limit,
maxDropdownHeight: params.maxDropdownHeight,
nothingFound: params.nothingFound,
placeholder: params.placeholder,
required: params.required,
searchValue: params.searchValue,
shadow: params.shadow,
size: params.size,
styles: params.styles,
switchDirectionOnFlip: params.switchDirectionOnFlip,
variant: params.variant,
}),
this.eInput
)
)
}
};
this.eInput = document.createElement('div');
ReactDOM.render(
React.createElement(window.dash_mantine_components.Select, {
data: options,
value: params.value,
setProps,
style: {width: params.column.actualWidth-2, ...params.style},
className: params.className,
clearable: params.clearable,
searchable: params.searchable || true,
creatable: params.creatable,
debounce: params.debounce,
disabled: params.disabled,
filterDataOnExactSearchMatch:
params.filterDataOnExactSearchMatch,
limit: params.limit,
maxDropdownHeight: params.maxDropdownHeight,
nothingFound: params.nothingFound,
placeholder: params.placeholder,
required: params.required,
searchValue: params.searchValue,
shadow: params.shadow,
size: params.size,
styles: params.styles,
switchDirectionOnFlip: params.switchDirectionOnFlip,
variant: params.variant,
}),
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();
}
};
import dash
from dash import html, dcc
import pandas as pd
from dash.dependencies import Input, Output
import dash_ag_grid as dag
import dash_mantine_components as dmc
import requests
from flask import request
# Create a DataFrame
df = pd.DataFrame({
'Name': ['Person' + str(i) for i in range(20)],
'favorite_word': ["" for _ in range(20)],
})
# Initialize the Dash app
app = dash.Dash(__name__)
# Define the layout of the app
app.layout = html.Div([
dag.AgGrid(
id='table',
rowData=df.to_dict('records'),
columnDefs=[{"headerName": i, "field": i,
"cellEditor": {"function": "DMC_Select2"},
"editable": True,
"cellEditorParams": {"creatable": True, "searchable": True},
"cellEditorPopup": True,
} for i in df.columns],
defaultColDef={'flex': 1},
)
])
@app.server.route('/dynamicOptions', methods=['POST'])
def dynamicOptions():
try:
url = f'https://random-word-form.repl.co/random/noun/{request.json.get("searchValue")}?count=10'
resp = requests.get(url).json()
return resp
except:
return []
# Run the app
if __name__ == '__main__':
app.run_server(debug=True, port=8080)