Saving a Record
Persisting data is always your backend's responsibility. The Buildocs SDK sends form data to your endpoint — your handler validates and saves it to whatever storage you use.
After saving, your handler returns a /runevent response containing commands that tell the SDK what to do next — show a message, close the form, reload a table, or redirect.
Two save patterns
Pattern A — Save via DataRecord helper
If you are using the FormEventHandler library with DynamoDB, DataRecord provides a built-in save method:
public async Task Form_onClick(string widgetName)
{
if (widgetName != "savebtn") return;
await record.Save();
ShowMessage("success", "Record saved.");
CloseForm();
}
DataRecord.Save() handles create vs. update automatically based on whether the record exists. The record field is pre-populated with the current form data by the base Form_onInit — no manual loading required.
Pattern B — Direct database save
For any other storage (SQL Server, PostgreSQL, MongoDB, etc.) you write the persistence logic directly:
public async Task Form_onClick(string widgetName)
{
if (widgetName != "savebtn") return;
// Validate first
if (string.IsNullOrWhiteSpace(record.GetField("firstName")?.ToString()))
{
ShowMessage("warning", "First name is required.");
return;
}
if (record.IsNewByRequest())
{
var employee = new Employee
{
Id = Guid.NewGuid(),
FirstName = record.GetField("firstName")?.ToString()!,
LastName = record.GetField("lastName")?.ToString()!,
Email = record.GetField("email")?.ToString()!,
StatusId = int.Parse(record.GetField("status")?.ToString() ?? "1"),
CreatedAt = DateTime.UtcNow
};
await _db.Employees.AddAsync(employee);
}
else
{
var employee = await _db.Employees.FindAsync(Guid.Parse(record.GetRecordGuid()!));
if (employee == null)
{
ShowMessage("error", "Record not found.");
return;
}
employee.FirstName = record.GetField("firstName")?.ToString()!;
employee.LastName = record.GetField("lastName")?.ToString()!;
employee.Email = record.GetField("email")?.ToString()!;
employee.StatusId = int.Parse(record.GetField("status")?.ToString() ?? "1");
employee.UpdatedAt = DateTime.UtcNow;
_db.Employees.Update(employee);
}
await _db.SaveChangesAsync();
ShowMessage("success", "Employee saved.");
CloseForm();
}
After saving — common follow-up commands
// Show confirmation and close
cmd.SuccessMessage("Saved.");
cmd.CloseForm();
// Show confirmation and stay on the form (e.g. for continued editing)
cmd.SuccessMessage("Changes saved.");
// Refresh the current form after saving
cmd.RedrawScreen();
Returning the new GUID
When a new record is created, call cmd.SetAfterRecordSave() with the new GUID. This tells the SDK that a save has completed and provides the record's actual ID:
var newId = Guid.NewGuid();
// ... create record with newId ...
cmd.SetAfterRecordSave(newId.ToString());
SetAfterRecordSave does three things:
- Updates the form's active GUID from
"new"to the real record ID — subsequent saves will update rather than create. - Closes the modal if the form was opened in one.
- Triggers a screen redraw.
For Pattern A (DataRecord.Save()), the base class calls cmd.SetAfterRecordSave() automatically — you do not need to call it yourself.