Lookup field
Search and pick from another SharePoint list, typeahead autocomplete with a configurable display column.
The Lookup field lets the user pick a value sourced from another SharePoint list. It shows a typeahead autocomplete: as the user types, the dropdown filters the target list by the configured display column. The selected item's ID is stored as the field value.
It binds to SharePoint's Lookup column type. The target list and display column are
read from the column configuration and kept in sync via
Common properties
| Property | Description |
|---|---|
labelstring | Visible label. |
descriptionstring | Helper text. |
requiredboolean default: false | Marks the field required. |
readOnlyboolean default: false | Disables editing, the linked item is still shown. |
Type-specific properties
| Property | Description |
|---|---|
lookupListIdGUID | Target list. Inherited from the SP column setting. |
displayColumnstring default: Title | Column from the target list shown in the dropdown and after selection. |
filterOData $filter | Server-side filter applied to the target list, e.g. Active eq 1. Reduces what the autocomplete searches. |
displayTemplatestring | Combine multiple columns into the option text, e.g. {Name} - {JobRole}. See Display template below. |
searchableboolean default: true | When on, the picker is a type-to-search combobox. Turn off for a plain click-open dropdown (no search box), useful for short, fixed option lists. |
sourceWebUrlURL | Lookup control only. Another site's URL to source the list from. Stores the picked ID in a Number column (single-select). See Cross-site. |
extra select fieldsstring | Comma-separated columns to fetch beyond the display column (e.g. Email,JobRole). Not shown, but available in JS as f365.field(name).value.item.ColumnName, the way to read an Id / Email you want for reference but not display. |
allowMultipleboolean default: false | Allow selecting multiple items. |
Display template
By default the picker shows a single display column. A display template lets you compose the option text from several columns of the source list, e.g. show both a person's name and their role in one line.
Type the template in the field's Display template box using
{ColumnInternalName} tokens; everything outside the braces is literal text:
Display template examples
{Name} - {JobRole} → Joseph - Software Engineer
{Title} ({Email}) → Acme (info@acme.com)
{FirstName} {LastName} → Ada Lovelace
Rules:
- Reference columns by SharePoint internal name, not the display label.
- Columns used in the template are fetched automatically, you don't also have to list them under Extra select fields.
{Column}here resolves against the selected source-list row, not a field on your form. This is the one place{…}means a source-row column rather than a form value (see Placeholders).- Empty / unknown columns collapse to nothing. If the whole template resolves to an empty string, the picker falls back to the display column.
- Above the list view threshold the picker uses the Search API, which only knows
Title; a template referencing other columns falls back to the display column for those results.
Searchable vs. static dropdown
Leave Searchable on (the default) for the type-ahead autocomplete. Turn it off to render a plain click-open dropdown that lists the options with no search box, a better fit for short, stable lists (departments, statuses) where typing is overkill. Everything else, the display template, the stored ID, the read-only behaviour on Display forms, and On-change, works the same either way.
Cross-site, source the list from another site
By default a lookup reads its list from the same site as the form, that's a SharePoint rule: a native Lookup column can only reference a list in its own site. The unbound Lookup control (SharePoint controls palette) can get around it with a Source site (URL).
Paste another site's URL into Source site (URL) (e.g. https://contoso.sharepoint.com/sites/HR), then pick the Source list and Display column as usual, they load from that site. At runtime the options and labels are fetched from there too.
Everything else works the same, the display template, the read-only View, and reading the selected row's other columns in an On-change handler:
Cross-site: copy a column from the picked item
// value.item is the row fetched from the OTHER site, same shape as a same-site lookup.
f365.field('HrContact').on('change', (value) => {
if (value?.item) f365.field('HrEmail').value = value.item.Email;
});
Quick-add, let users create a new target-list item inline
When Allow users to add a new item is on, the picker dropdown grows an "Add" command row (alongside the search results). Clicking it opens a small modal where the user creates a new item in the target list; the item is saved immediately and then auto-selected, so they never leave the form. Off by default.
Configure it in the property pane under Quick-add. There are two modes, basic (a generated mini-form from the target-list columns you choose) and advanced (a saved Forms 365 form bound to the target list). Advanced takes precedence when set, mirroring the linked-list row-editor model.
| Property | Description |
|---|---|
allowAddboolean default: false | Master toggle. When on (and the user has Add permission on the target list), the dropdown shows the "Add" command row. |
addLabelstring default: Add | Text of the in-dropdown command row. The runtime appends the typed query, e.g. Add "Acme". |
addSchemaComponent[] | BASIC mode, the target-list columns the create form shows. Authored via the "Choose fields…" builder; the display column is always included. Ignored when addFormId is set. |
addFormIdstring | ADVANCED mode, id of a saved form (bound to the target list) opened as the create modal. Takes precedence over addSchema. |
JavaScript recipes
Read the linked item id
const clientId = f365.field('Client').value as number | null;
// ^ for allowMultiple, returns number[] instead.
Set programmatically by id
f365.field('Client').value = 42;
// or, batch:
f365.field('Tags').value = [1, 7, 12];
Cascade, filter one lookup by another
f365.events.onChange('Region', async (regionId) => {
// Re-target the City lookup to only show cities in the chosen region.
const handle = f365.field('City').asLookup();
handle.filter = regionId ? `RegionId eq ${regionId}` : '';
handle.value = null; // clear stale selection
});
On change, copy the selected row's columns into other fields
// The picked value carries the whole fetched row on `.item`, including any
// columns you listed under "Extra select fields". No extra REST call needed.
f365.events.onChange('Staff', (value) => {
if (!value || !value.item) return;
f365.field('StaffId').value = value.item.Id; // the reference id
f365.field('StaffEmail').value = value.item.Email; // a reference column
});
Fetch a related field from the linked item (when it isn't pre-fetched)
f365.events.onChange('Client', async (clientId) => {
if (!clientId) return;
const item = await f365.sp.web.lists
.getById('{client-list-guid}')
.items.getById(clientId)
.select('AccountManager', 'Tier')
.get();
f365.field('AccountManager').value = item.AccountManager;
f365.field('Tier').value = item.Tier;
});
Related
Related articles
- User (People picker) field
Search and select one or more Microsoft 365 / Entra users via the People Picker, backed by SharePoint's User column.
- LinkedList field
Edit child-list rows inline on the parent form, repeatable mini-grids backed by a related SharePoint list.