Log updates from inline or form editing

I have been looking for an easy way to track and log changes to specific fields and am using this at the moment, thought it might help someone else.

I have a logs table as shown in screen shot, capturing old and new values amongst other things. You can add more fields if you want or have less.
image

Main code is

function checkFieldChanges(originalRecord, updatedRecord, fieldsToWatch, tableName) {
  return fieldsToWatch.reduce((changes, fieldKey) => 
    updatedRecord[fieldKey] !== originalRecord[fieldKey]
      ? [...changes, {
          fieldKey,
          oldValue: originalRecord[fieldKey],
          newValue: updatedRecord[fieldKey],
          tableName
        }]
      : changes
  , []);
}

function logChanges(changedFields, recordId, viewKey) {
  const currentUser = Knack.getUserAttributes();
  const currentDateTime = new Date().toISOString();

  changedFields.forEach(change => {
    $.ajax({
      url: `https://api.knack.com/v1/pages/scene_98/views/view_191/records`,
      type: "POST",
      headers: {
        "Authorization": Knack.getUserToken(),
        "X-Knack-Application-Id": Knack.application_id,
        "X-Knack-REST-API-KEY": "knack",
        "Content-Type": "application/json"
      },
      data: JSON.stringify({
        'field_43': currentDateTime,
        'field_432': change.tableName,
        'field_434': change.oldValue,
        'field_435': change.newValue,
        'field_508': currentUser.name,
        'field_510': recordId,
        'field_509': viewKey
      })
    });
  });
}

function setupChangeTracking({ inlineViewKey, formViewKey, fieldsToWatch, tableName }) {
  const trackChanges = (viewKey, isForm) => {
    $(document).on(`knack-view-render.${viewKey}`, (event, view, data) => {
      $(document).on(`${isForm ? 'knack-form-submit' : 'knack-cell-update'}.${viewKey}`, (event, view, updatedRecord) => {
        const originalRecord = isForm ? data : data.find(record => record.id === updatedRecord.id);
        if (originalRecord) {
          const changedFields = checkFieldChanges(originalRecord, updatedRecord, fieldsToWatch, tableName);
          changedFields.length > 0 && logChanges(changedFields, updatedRecord.id, viewKey);
        }
      });
    });
  };

  inlineViewKey ? trackChanges(inlineViewKey, false) : null;
  formViewKey ? trackChanges(formViewKey, true) : null;
}

That’s all you need, only thing you need to update is the logEntry fields to make them match your own log table ids.

Then you can use it for anything like this

$(document).ready(() => 
  setupChangeTracking({
    inlineViewKey: 'view_146',
    formViewKey: 'view_147',
    fieldsToWatch: ['field_37', 'field_47'],
    tableName: 'Client Funding'
  })
);

adding more setupChangeTracking calls as needed

Edit:
The ajax url https://api.knack.com/v1/pages/scene_98/views/view_191/records is just the url to the Logs form page. You’ll need the form to be able to insert the log records through view based requests. The you hide the log page from the menu using the page settings.

4 Likes