LinkedList field
Edit child-list rows inline on the parent form, repeatable mini-grids backed by a related SharePoint list.
The LinkedList field embeds child-list rows directly on the parent form, invoice line items on an Orders form, attendees on an Event form, expenses on a Reimbursement. Rows can be added, edited, and deleted inline. Each row corresponds to an item in a linked SharePoint list, joined via a Lookup column pointing back at the parent.
Writes happen in the post-save phase: the parent item is created first to get its id, then child rows are written with the parent reference.
Properties
| Property | Description |
|---|---|
childListIdGUID | Child list this composite is bound to. |
childListTitlestring | Display title of the bound child list (cached for the UI). |
relationColumnInternalNamestring | Internal name of the lookup or integer column on the child list that points back at the parent. Stamped with the parent item id on save. |
secondaryFilterColumnInternalNamestring | Optional second column for the "many child types share one list" pattern, bound alongside secondaryFilterValue to scope rows to one kind. |
secondaryFilterValuestring | Constant paired with secondaryFilterColumnInternalName. Stamped onto every new row and used as the equality filter on load. |
secondaryFilterAlsoValuesstring[] | Extra values the secondary filter matches when LOADING rows, on top of secondaryFilterValue. New rows are still stamped with secondaryFilterValue only. Use when the discriminator was renamed and older rows should still show. |
parentPrefill{ columnInternalName, template }[] | Seed columns on every NEW child row from this (parent) form. Each entry pairs a child column with a value template, e.g. Feedback: {Title}. See "Prefill new rows from this form" below. |
defaultRows{ cells: { columnInternalName, template }[] }[] | Rows the grid starts with on a NEW form. Each row sets some columns with the same value templates as parentPrefill; a row with no cells is a blank starter row. See "Default rows" below. |
rowSchemaDesignerComponent[] default: [] | Schema of one row, authored in the child-row builder (not via canvas drops). Used by the inline grid and as the row editor. |
minRowsnumber default: 0 | Minimum number of rows required to save. It only validates; to open the form with rows already in place, use defaultRows. |
maxRowsnumber | Maximum number of rows. Unbounded when unset. |
addLabelstring default: Add row | Copy on the add-row button. |
removeLabelstring default: Remove | Copy on the remove-row button. |
emptyMessagestring default: No rows yet. | Copy shown when there are zero rows. |
renderMode'inline-grid' | 'modal' default: inline-grid | Runtime layout: inline grid vs. one modal per row. |
rowFormIdstring | Existing form id opened in a modal when adding/editing a row. Used when renderMode is modal; ignored for inline-grid (which uses rowSchema). |
Attachments on each row
To let people attach files to each row, open Design list view and click Attachments (the paperclip entry) in the Child list columns list. The grid gets a paperclip column: each row shows how many files it has, and clicking the paperclip opens a small window where files can be added (browse or drag and drop), opened, or removed. The Add row, Edit row and row details (👁) windows show the same file list.
- The files are stored as SharePoint attachments on the child item for that row.
- On an existing parent item, changes save a moment after you make them, like any other cell. On a new form they save when the form is saved, because the child items don't exist until then.
- Removing a file sends it to the SharePoint recycle bin. It is not permanently deleted.
- In the list view builder you can set a maximum file size, the accepted file types (for
example
.pdf,image/*), and whether several files can be picked at once. - Attachments must be switched on for the child list (List settings, Advanced settings, Attachments: Enabled). If they are off, the upload fails and the row shows the error.
- Empty (0 byte) files are refused, because SharePoint can't store an empty file as an attachment.
- A file with the same name as one already on the row is refused, because SharePoint doesn't allow two attachments with the same name. Remove the old file first or rename the new one.
- In the form's PDF report, the rows' photos print as pictures under the table. Generating a report adds this for a list whose rows take attachments; in the report designer, add Attachments (photos) and set Files from to the linked list.
Prefill new rows from this form
When a linked list is shared across several parent forms (one Actions list serving Feedback, Objectives and Hazards, say), each parent usually wants to stamp something of its own onto every row it creates. Configure that here, on the parent form, not in the child row form.
In the properties panel, open Prefill new rows from this form, click + Add a prefill, pick the child column, and write the value you want:
| Template | Result on a new row |
|---|---|
Feedback: {Title} | Feedback: Broken guard rail |
{Title} - {Department} | Broken guard rail - Fabrication |
Raised by [Me:Title] | Raised by Alec Tecson |
{Title} ([ID]) | Broken guard rail (118) |
{Field} is a field on this form, [Today] / [Me] / [ID] are system tokens, and
anything else is written literally. This is the same placeholder vocabulary used
everywhere else, see Placeholders.
Because the template lives on the parent, the per-parent label is just text you type: the
Feedback form uses Feedback: {Title} and the Objectives form uses Objectives: {Title},
with one shared row form and no scripting.
What to expect
- Applies when a row is added on this form. Existing rows are never overwritten.
- Whoever fills the row can still change a prefilled value; it is a starting point, not a lock.
- A template that resolves to nothing is skipped, so the child field falls back to its own default value.
- Target columns are single-line text, multi-line text, choice and hyperlink. Copying a person, lookup or date column needs a real typed value rather than text, so those columns are not offered.
- A hyperlink column gets two boxes: the link address on top, the link text below.
Leave the text blank and SharePoint shows the address itself. Both accept tokens, so a
link back to the parent item looks like
https://contoso.sharepoint.com/Lists/Feedback/DispForm.aspx?ID=[ID]with the textFeedback: {Title}. On a brand new parent,[ID]is still empty at the moment you add the row (the item has no id until you save), so link back by a value that already exists, or add the row after saving the parent once. - The relation column is never offered. The runtime writes each row's link back to this item last and unconditionally, so a prefill there would be thrown away every time.
- The secondary filter column IS offered, and a prefill on it wins. The filter value is
stamped only onto rows that arrive without one, so it behaves as the fallback. That is
what makes a per-item discriminator possible: one parent form with filter values
Feedback - Compliment,Feedback - ComplaintandFeedback - Suggestioncan prefillFeedback - {FeedbackType}and have each row labelled correctly, where the filter value alone would stamp the first one on everything. For a genuinely fixed value, the filter value on its own is enough, and rows get filtered by it too. - Rows created by scanning the QR code open a standalone page with no parent form loaded, so they are not prefilled. The parent link itself still travels in the QR URL.
Default rows
Use Default rows when a new form should open with rows already in the grid: a pre-start checklist, the standard line items on a quote, the usual attendees of a recurring meeting.
In the properties panel, open Default rows, click + Add a default row, then set the columns that row should start with. Each value box takes the same templates as the prefill above:
| Row | Values |
|---|---|
| 1 | Title = Pre-start inspection |
| 2 | Title = Toolbox talk, Notes = Run by [Me:Title] |
| 3 | (no values, a blank starter row) |
Use the arrows on a row to reorder, and remove a value or a whole row with its ✕.
What to expect
- New forms only. Editing an existing item shows the rows it already has; default rows are never added to it.
- The rows are ordinary rows. The person filling the form can edit or remove them, and they are saved to the child list together with the form, exactly like rows added by hand.
- Cells a default row leaves empty still get the prefill above, so a column you prefill for every row does not need repeating in each default row.
- Templates resolve once, when the form opens, so
{Field}sees that field's starting (default) value, not what someone types later.[Today]and[Me:Title]work as usual.[ID]is always empty here, because a new item has no id until it is saved. - The same column types as the prefill are offered: single-line text, multi-line text, choice and hyperlink. The relation column is filled in for you.
- Min rows is separate. It only stops the form saving with too few rows; it does not add any rows itself.
- If your own form JavaScript adds rows before the defaults are applied, the defaults are skipped rather than doubled up.
JavaScript recipes
The handle for a linked list is f365.control(name).asLinkedList(), which returns a
LinkedListHandle (or null if the named control isn't a mounted linked list). The handle
exposes exactly two methods:
| Property | Description |
|---|---|
addRow(values)(values: Record<string, unknown>) => { __rowKey: string } | Appends one row and returns its generated key. New rows flush to SharePoint in the parent’s post-save phase. |
rows()() => ReadonlyArray<Record<string, unknown>> | Snapshot of the current rows (deleted rows excluded). |
Running total across rows
f365.events.onChange('LineItems', () => {
const total =
f365
.control('LineItems')
.asLinkedList()
?.rows()
.reduce((sum, r) => sum + (Number(r.Amount) || 0), 0) ?? 0;
f365.field('Total').value = total;
});
Add a row programmatically
const list = f365.control('LineItems').asLinkedList();
if (list) {
const { __rowKey } = list.addRow({ Description: 'Setup fee', Amount: 250 });
f365.ui.showToast(`Added row ${__rowKey}`);
}
Enforce a minimum number of rows before save
f365.events.onBeforeSave(() => {
const count = f365.control('LineItems').asLinkedList()?.rows().length ?? 0;
if (count < 1) {
f365.ui.showAlert('Add at least one line item before saving.');
return false;
}
});
Related
Related articles
- Lookup field
Search and pick from another SharePoint list, typeahead autocomplete with a configurable display column.
- Document Library field
Browse and upload files to a SharePoint Document Library, with the folder structure and metadata that brings.
- Save flow, what happens when the user clicks Submit
The two-phase save pipeline, validation, primary write, then post-save writers for attachments, signatures, images, and child rows.