Common pattern: signatures + attachments
Capture a signature and a supporting document on the same form, and have both persist correctly through the post-save phase.
Inspection forms, consent forms, and delivery receipts all need the same combo: a signature, plus a supporting attachment (a photo, a receipt PDF, an audit document). Both write in the post-save phase, so the recipe is more interesting than it looks.
The data
In your SharePoint list:
- An Image column for the signature (e.g.
CustomerSignature) - The built-in Attachments (every list has this; no column to add)
On your form:
- A Signature field, binding mode
"image", target columnCustomerSignature - An Attachments field
The save flow
Both fields write in the post-save phase:
- Pre-flight, validation, onBeforeSave
- Primary write, the SP item is created
- Post-save phase:
- Signature uploads PNG to the Image column
- Attachments uploads files to the SP Attachments endpoint
If either post-save writer fails, the item still exists, just without that asset.
Hardening for regulated workflows
When the form is legally required to have both the signature and the attachment, add a verification step:
Verify both assets exist after save
f365.events.onSave(async ({ itemId }) => {
const item = await f365.sp.web.lists
.getByTitle('Inspections')
.items.getById(itemId)
.select('CustomerSignature', 'Attachments')
.get();
if (!item.CustomerSignature || !item.Attachments) {
// Flag it for follow-up.
await f365.sp.web.lists
.getByTitle('Inspections')
.items.getById(itemId)
.update({ NeedsReview: true });
f365.ui.showToast(
'Saved, but one or more attachments may have failed. Item flagged for review.',
'warning'
);
}
});
Even better: run a daily background scan that finds NeedsReview === true
items and notifies a moderator. That covers the silent-failure case where the
user never sees the toast (page closed too quickly).
Submit-time validation
Block submit if the user hasn't provided what's required:
Block submit when signature is empty
f365.events.onBeforeSave(() => {
if (!f365.field('CustomerSignature').value) {
f365.ui.showAlert('A signature is required to submit this form.');
f365.field('CustomerSignature').scrollIntoView();
return { cancel: true };
}
});