Hey guys,
Just wondering if there was a way to subscribe to when any field in a table/collection changes using the LFForm object?
Thanks
Hey guys,
Just wondering if there was a way to subscribe to when any field in a table/collection changes using the LFForm object?
Thanks
Hi Jay,
Congratulations! Looks like you have figure it out. Thank you for sharing the solution.
We have added 'support subscribe event for collection/table set/row change' in product backlog and will consider support it in future release to simplify the usage.
It's a little tricky. You have to loop through all the fields in the table and apply the onFieldChange interface. Something like this should at least get you started:
var myFields = LFForm.findFieldsByClassName('myField'); myFields.forEach(function (arrayItem) { LFForm.onFieldChange(function(){ console.log('test'); }, arrayItem); });
Hi Matthew,
Thanks for your help
Is there a method or way to detect when new rows are added or removed from a table/collection?
I can't figure out how, via the LFForm object, to identify the change events that happen with adding or deleting a row on the table. I can't get it to do anything with onFieldChange or onFieldBlur against the table itself.
I thought I could loop through the rows in the table and count them to see if the count had gone up or down in order to identify if a row has been added or removed. The problem is, I can't figure out how to trigger that could to happen whenever changes happen on the table.
I can get it to trigger that count when changes happen to a specific field within the table, so we could determine when the field is changed that at some prior point, a row had been added or removed from the table.
But I'm not having any luck finding a way to identify immediately upon the table being changed if rows were added or deleted.
Ok, I've ended up looking into this further and I've come up with the following which seems to work ok.
// This function parses the data from the table field LFForm object function parseTableData(tableFieldId) { const tableFormData = LFForm.getFieldValues({ fieldId: tableFieldId }) return tableFormData.map(rowObject => { // We check each object key to see if it has a data property and stringify it return Object.keys(rowObject).map(key => { if (rowObject[key].hasOwnProperty('data')) { if (typeof rowObject[key].data === 'object') return JSON.stringify(rowObject[key].data) return rowObject[key].data.toString() } }).filter(d => d !== undefined) }) } function subscribeToChanges(tableFieldId, toWatch, toUpdate) { const initData = parseTableData(tableFieldId) // Add listeners to fields we want to watch toWatch.forEach(fieldId => { LFForm.onFieldChange(function () { const newData = parseTableData(tableFieldId) // Check if the data has changed const hasChanged = JSON.stringify(initData) !== JSON.stringify(newData) if (hasChanged) LFForm.setFieldValues({ fieldId: toUpdate }, 1) else LFForm.setFieldValues({ fieldId: toUpdate }, 0) }, { fieldId }) }) } // 76: table field, 82,77: fields to watch, 88: field to update subscribeToChanges(76, [82, 77], 88)
To sum up the above, running the LFForm.getFieldValues method on a table returns an object which has quite a bit of information on it.
{
"b59665a6-32c9-482f-a0c3-7620269d713f": {
"componentId": "b59665a6-32c9-482f-a0c3-7620269d713f",
"componentType": "DateTime",
"fieldId": 77,
"hidden": false,
"disabled": false,
"readonly": false,
"data": {
"dateStr": "06/04/2023",
"timeStr": "",
"dateTimeObj": "2023-04-05T14:00:00.000Z"
},
"valueOrigin": "DefaultData",
"trackId": "53feeb85-6fab-4bc9-bca7-04c1544d2ae3",
"lastChange": {
"timestamp": 0,
"changes": []
},
"settings": {
"required": true,
"readOnly": false,
"isPreviousDataPreserved": false,
"minWidth": 440,
"minHeight": 100,
"label": "Date",
"datePlaceholder": "DD/MM/YYYY",
"timePlaceholder": "hh:mm:ss A",
"defaultDate": "2023-04-06",
"defaultTimeOfDate": "",
"minDate": "",
"minDateForDefault": "",
"minTimeOfDate": "",
"minTimeOfDateForDefault": "",
"maxDate": "",
"maxDateForDefault": "",
"maxTimeOfDate": "",
"maxTimeOfDateForDefault": "",
"dateFormat": "DD/MM/YYYY",
"formatChanged": false,
"timeFormat": "hh:mm:ss A",
"timeFormatAMPM": "hh:mm:ss A",
"isAMPM": true,
"isTwentyfour": false,
"padding": 10,
"showTime": false,
"description": "",
"subtext": "",
"tooltip": "",
"id": "b59665a6-32c9-482f-a0c3-7620269d713f",
"componentType": "DateTime",
"fieldId": 77,
"parentId": "53108f3c-a155-4f9c-ab49-b2ab1f800f1e",
"isInCollection": false,
"isInTable": true,
"collectionId": null,
"tableId": "53108f3c-a155-4f9c-ab49-b2ab1f800f1e",
"useCurrentDate": false,
"ancestorReadonly": false,
"timeFormat24": "HH:mm:ss",
"attributeName": "Period_Date",
"useCurrentDateOrTimeForRepeatable": true,
"minEntry": null,
"maxEntry": null,
"minEntryAppend": null,
"maxEntryAppend": null,
"min": "",
"max": "",
"formattedMin": "",
"formattedMax": ""
},
"validation": {
"dateTime": {},
"dateTime-date": {}
},
"groupTrackId": "47a29939-1d29-4d1b-b2c7-b504430e25c0",
"disableUseCurrentDateTime": false
},
As I am only interested in values changing, I strip out everything except the data found in key.data when creating a variable for the initial data
I then add a listener for any fieldIds I want to watch.
In this listener, I create a new variable with the current data of the table and convert this, along with the initial data to JSON strings and then compare the two.
If there's no match, I change the value in another field to mark the change.
I haven't really tested this too much in-depth, but from what I can tell - It seems to do the job.