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

schema reconciliation.

Common properties

PropertyDescription
label
string
Visible label.
description
string
Helper text.
required
boolean
default: false
Marks the field required.
readOnly
boolean
default: false
Disables editing, the linked item is still shown.

Type-specific properties

PropertyDescription
lookupListId
GUID
Target list. Inherited from the SP column setting.
displayColumn
string
default: Title
Column from the target list shown in the dropdown and after selection.
filter
OData $filter
Server-side filter applied to the target list, e.g. Active eq 1. Reduces what the autocomplete searches.
displayTemplate
string
Combine multiple columns into the option text, e.g. {Name} - {JobRole}. See Display template below.
searchable
boolean
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.
sourceWebUrl
URL
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 fields
string
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.
allowMultiple
boolean
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.

PropertyDescription
allowAdd
boolean
default: false
Master toggle. When on (and the user has Add permission on the target list), the dropdown shows the "Add" command row.
addLabel
string
default: Add
Text of the in-dropdown command row. The runtime appends the typed query, e.g. Add "Acme".
addSchema
Component[]
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.
addFormId
string
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 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.