Using Different Cell Editors Per Row in the Same FlexGrid Column in React
Background:
Sometimes you want a single column in a FlexGrid to use different editors depending on which row is being edited. For example, one row might require a text editor, another might need a combo box, and yet another might use a checkbox.
You can accomplish this in FlexGrid by handling the prepareCellForEdit event and dynamically swapping the default cell editor for whatever editor suits the current row.
Steps to Complete:
- Handle the
prepareCellForEditevent to check the row being edited. - Based on the row’s data, replace the default editor with a custom editor (e.g., ComboBox, CheckBox).
- Ensure the selected editor value is written back to the cell on completion.
Getting Started:
Create a FlexGrid with Data
We define sample data that includes one column (type) that determines which editor should be used for the value column. We wire up the prepareCellForEdit event in React.
import React, { useRef } from 'react';
import { FlexGrid } from '@mescius/wijmo.react.grid';
import * as wjcInput from '@mescius/wijmo.input';
export default function App() {
const gridRef = useRef(null);
const data = [
{ type: 'text', value: 'Alpha' },
{ type: 'boolean', value: true },
{ type: 'options', value: 'Option1' },
{ type: 'text', value: 'Omega' }
];
...
};
return (
<FlexGrid
ref={gridRef}
itemsSource={data}
autoGenerateColumns={false}
prepareCellForEdit={handlePrepareCellForEdit}
>
<FlexGrid.Column header="Type" binding="type" width={120} />
<FlexGrid.Column header="Value" binding="value" width="*" />
</FlexGrid>
);
}
Handle the prepareCellForEdit event to check the row being edited
This intercepts the moment a cell enters edit mode so you can inspect which row and column is being edited.
grid.prepareCellForEdit.addHandler((s, e) => {
const col = s.columns[e.col];
const rowData = s.rows[e.row].dataItem;
if (col.binding === 'value') {
console.log('Editing row type:', rowData.type);
}
});
e.row/e.col→ tells you which cell is editing.dataItem→ gives you the actual row object.
Based on the row’s data, replace the default editor with a custom editor (e.g., ComboBox, CheckBox)
This creates and assigns a different editor depending on row data.
grid.prepareCellForEdit.addHandler((s, e) => {
const col = s.columns[e.col];
const rowData = s.rows[e.row].dataItem;
if (col.binding === 'value') {
// Clean up existing editor
if (s.activeEditor?.dispose) {
s.activeEditor.dispose();
}
if (rowData.type === 'boolean') {
const chk = new wjcInput.CheckBox(s.hostElement);
chk.checked = rowData.value;
s.activeEditor = chk;
} else if (rowData.type === 'options') {
const cbo = new wjcInput.ComboBox(s.hostElement, {
itemsSource: ['Option1', 'Option2', 'Option3'],
text: rowData.value
});
s.activeEditor = cbo;
}
}
});
- You inspect
rowData.type. - You instantiate the appropriate control.
- You assign it to
s.activeEditor.
Ensure the selected editor value is written back to the cell on completion
This ensures that when the user changes the editor value, the underlying data item updates correctly.
// Example for CheckBox
chk.checkedChanged.addHandler(() => {
rowData.value = chk.checked;
});
// Example for ComboBox
cbo.textChanged.addHandler(() => {
rowData.value = cbo.text;
});
- Editors must update
rowData. - If you don’t sync data, the grid will visually update but the model won’t.
Combined File
export default function App() {
const gridRef = useRef(null);
const data = [
{ type: 'text', value: 'Alpha' },
{ type: 'boolean', value: true },
{ type: 'options', value: 'Option1' },
{ type: 'text', value: 'Omega' }
];
const handlePrepareCellForEdit = (s, e) => {
const col = s.columns[e.col];
const rowData = s.rows[e.row].dataItem;
// Only intervene for the "value" column
if (col.binding === 'value') {
// Dispose existing editor if present
if (s.activeEditor && s.activeEditor.dispose) {
s.activeEditor.dispose();
}
switch (rowData.type) {
case 'boolean':
// Create CheckBox editor
const chk = new wjcInput.CheckBox(s.hostElement);
chk.checked = rowData.value;
chk.checkedChanged.addHandler(() => {
rowData.value = chk.checked;
});
s.activeEditor = chk;
break;
case 'options':
// Create ComboBox editor
const cbo = new wjcInput.ComboBox(s.hostElement, {
itemsSource: ['Option1', 'Option2', 'Option3'],
text: rowData.value
});
cbo.textChanged.addHandler(() => {
rowData.value = cbo.text;
});
s.activeEditor = cbo;
break;
default:
// Default text editor
const input = document.createElement('input');
input.type = 'text';
input.value = rowData.value;
input.style.width = '100%';
input.addEventListener('change', () => {
rowData.value = input.value;
});
s.activeEditor = {
hostElement: input,
dispose: () => {}
};
break;
}
}
};
With this React setup:
- A single “Value” column dynamically switches editors per row.
- Users see checkboxes, combo boxes, or text inputs depending on context.
- The data model updates immediately when edits occur.
- The grid layout remains consistent while editing behavior varies intelligently.
Happy coding!
