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
- Another might use a checkbox
You can accomplish this in FlexGrid by handling the prepareCellForEdit event and dynamically swapping the default cell editor based on the row’s data.
Steps to Complete:
- Handle the
prepareCellForEditevent to determine which row is being edited. - Replace the default editor with a custom editor depending on the row’s data.
- Ensure the selected editor value is written back to the underlying data item.
Getting Started:
Handle the prepareCellForEdit event to determine which row is being edited
We define sample data where one column (type) determines what kind of editor should be used in the value column.
<template>
<wj-flex-grid
ref="flex"
:itemsSource="data"
:autoGenerateColumns="false"
:prepareCellForEdit="onPrepareCellForEdit"
:cellEditEnded="onCellEditEnded"
>
<wj-flex-grid-column
header="Type"
binding="type"
width="120">
</wj-flex-grid-column>
<wj-flex-grid-column
header="Value"
binding="value"
width="*">
</wj-flex-grid-column>
</wj-flex-grid>
</template>
<script>
import { WjFlexGrid, WjFlexGridColumn } from '@mescius/wijmo.vue2.grid';
import * as wjcInput from '@mescius/wijmo.input';
export default {
components: {
WjFlexGrid,
WjFlexGridColumn
},
data() {
return {
data: [
{ type: 'text', value: 'Alpha' },
{ type: 'boolean', value: true },
{ type: 'options', value: 'Option1' },
{ type: 'text', value: 'Omega' }
]
};
},
methods: { ...
autoGenerateColumns="false"ensures we define columns manually.prepareCellForEditallows us to intercept editing.cellEditEndedensures values persist properly.
Replace the default editor with a custom editor depending on the row’s data
When editing begins, we inspect the row’s type and create a different editor accordingly.
onPrepareCellForEdit(s, e) {
const col = s.columns[e.col];
const rowData = s.rows[e.row].dataItem;
// Only override editor for "value" column
if (col.binding !== 'value') return;
// Clean up previous editor if necessary
if (s.activeEditor?.dispose) {
s.activeEditor.dispose();
}
switch (rowData.type) {
case 'boolean':
const chk = new wjcInput.CheckBox(s.hostElement);
chk.checked = rowData.value;
chk.checkedChanged.addHandler(() => {
rowData.value = chk.checked;
});
s.activeEditor = chk;
break;
case 'options':
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:
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;
}
},
- We only modify the
"value"column. - We inspect
rowData.type.
Ensure the selected editor value is written back to the underlying data item
Although we update values inside change handlers, we also handle cellEditEnded to ensure the grid’s data model stays synchronized.
onCellEditEnded(s, e) {
const item = s.rows[e.row].dataItem;
const col = s.columns[e.col];
item[col.binding] = s.getCellData(e.row, e.col);
}
}
};
</script>
- This guarantees the underlying data reflects the final edited value.
With this Vue implementation:
- The Value column dynamically switches editors per row.
- Boolean rows show checkboxes.
- Option rows show combo boxes.
- Text rows use text inputs.
- Data remains synchronized and consistent.
- The grid layout stays uniform while editing behavior adapts intelligently.
Happy coding!
Andrew Peterson
Technical Engagement Engineer
