I use formio javascript library to create my forms and I simply need for a dropdown to get its current value and its previous value on change event.
The challenge here is that the dropdown can be in a datagrid and more dropdowns are added when adding row. Like with this simple form configuration:
{ display : 'form'
, components:
[ { label : 'Data Grid'
, reorder : false
, addAnotherPosition : 'bottom'
, layoutFixed : false
, enableRowGroups : false
, initEmpty : false
, tableView : false
, defaultValue : [ { } ]
, key : 'dataGrid'
, type : 'datagrid'
, input : true
, components:
[ { label : 'Test drop down'
, widget : 'choicesjs'
, tableView : true
, data:
{ values:
[ { label: 'Test 1', value: 'test1' }
, { label: 'Test 2', value: 'test2' }
, { label: 'Test 3', value: 'test3' }
]
}
, key : 'testDropDown'
, type : 'select'
, input : true
} ] } ] }
To handle fetching the present and past values of a dropdown in a DataGrid element with the formio, you need to use event listeners for monitoring value change.
To achieve this :
const formConfig = {
display: 'form',
components: [{
label: 'Data Grid',
reorder: false,
addAnotherPosition: 'bottom',
layoutFixed: false,
enableRowGroups: false,
initEmpty: false,
tableView: false,
defaultValue: [{}],
key: 'dataGrid',
type: 'datagrid',
input: true,
components: [{
label: 'Test drop down',
widget: 'choicesjs',
tableView: true,
data: {
values: [{
label: 'Test 1',
value: 'test1'
},
{
label: 'Test 2',
value: 'test2'
},
{
label: 'Test 3',
value: 'test3'
},
],
},
key: 'testDropDown',
type: 'select',
input: true,
}, ],
}, ],
};
Formio.createForm(document.getElementById('formio'), formConfig).then(
(form) => {
attachEventListeners(form);
}
);
function attachEventListeners(form) {
// Store previous and current values for each component
const componentStates = new Map();
// Function to handle the change event for dropdowns
const handleChange = (component, rowIndex) => {
const path = `${component.path}[${rowIndex}]`;
let state = componentStates.get(path);
if (!state) {
state = {
previousValue: null,
currentValue: ''
};
componentStates.set(path, state);
}
component.on('change', () => {
state.previousValue = state.currentValue;
state.currentValue = component.getValue();
// if (rowIndex)
console.log(
`For::${path} Previous Value: ${state.previousValue} , Current Value: ${state.currentValue}`
);
});
};
// Attach event listeners to existing dropdowns
form.everyComponent((component) => {
if (component.component.key === 'testDropDown') {
handleChange(component, 0);
}
});
// Attach event listeners to new rows in the DataGrid
form.on('change', (event) => {
if (
event.changed &&
event.changed.component &&
event.changed.component.key === 'dataGrid'
) {
console.log('fired');
const dataGridComponent = event.changed.instance;
dataGridComponent.rows.forEach((row, rowIndex) => {
if (row.testDropDown.component.key === 'testDropDown') {
handleChange(row.testDropDown, rowIndex);
}
});
}
});
}
<script src="https://cdn.form.io/formiojs/formio.full.min.js"></script>
<div id="formio"></div>