Skip to main content

Do Complete

Last updated 26/03/2026

Overview

The Do Complete event is a server-side event that executes when the user clicks the Save button on a top-level form, just before the data is committed to the database. It runs after all form and sub-form data has been processed, but while the transaction is still pending, allowing final validation or logic to determine whether the changes should be committed or rolled back.

How it Works

When the Save button is clicked:

  1. The form data, including sub-forms is sent to the server.
  2. The server processes all changes as part of a transaction.
  3. The Do Complete server-side event executes.
  4. At this point, the data has been written but not yet committed to the database.
  5. If the event returns an error, the entire transaction is rolled back.
  6. If the event returns success, the transaction is committed and the data is saved permanently.

The event provides access to all affected records through the

context.Transactions
array, allowing you to inspect and validate every change before finalizing.

Use Cases

  • Final validation across multiple records or sub-forms
  • Preventing invalid or inconsistent data from being saved
  • Performing last minute updates or adjustments before commit
  • Ensuring business rules are enforced across the entire transaction
  • Rolling back all changes if any condition fails

Example

This function executes when the user clicks the top-level Save button, and it loops through all pending changes to validate data, perform additional updates, and either commit everything or rollback the entire transaction if any check fails.

JavaScript
Verifies the changes before committing or reverting to the database
function DoComplete(five, context, result)  {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// When DoComplete is called, all data has been updated in the database, however, it has not been committed
// yet, so as a last resort, if this function returns an error, all the data will be rolled back from the database
// Any 'before' table events that have been executed will roll back as well
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

const formRecords = context.Transactions; // An array of FormRecord objects
for (let i = 0; i < formRecords.length; i++) {
const formRecord = formRecords[i];

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// formRecord.ActionID <-- is available to know which form is being created/updated/deleted
// formRecord.Type <-- contains the actual action being performed. 'CREATE', 'UPDATE', 'DELETE'
// formRecord.Key <-- is the primary key of the record being created, updated, or deleted
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (formRecord.Type === 'CREATE') {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// checking to ensure the FieldFromForm does not contain integer values to demonstrate an error
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (/\d/.test(formRecord.Values['FieldFromForm'])) {
return five.createError('Data for Field From Form cannot include digits');
}

const createResult = five.executeQuery('UPDATE Demonstration SET FieldFromCode=? WHERE DemonstrationKey=?', 0, 'Data saved from this function', formRecord.Key);
if (createResult.isOk() === false) {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Since we are returning an error, the database will be rolled back
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
return five.createError(createResult, 'Failed to update record');
}
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Returning a success result here will automatically commit the data into the database.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
return five.success(result);
}