Toolbar
Beta

Autocomplete

Autocomplete for real application forms. It separates search text from form value, supports object options with primitive form values, accepts hydrated values from edit screens, and works with local search, server search, multiple selection, free text, pagination, and virtualized lists.

Import

import {FktAutocompleteComponent} from "frakton-ng/autocomplete";

Selection

Core selection behavior. The autocomplete keeps the typed query separate from the form value: search text is temporary, while selected options write normalized primitive values to the form.

Basic

Basic single selection with primitive string options. When options are already primitive values, the component does not require labelKey or valueKey.




Object options

Object options can be normalized through labelKey and valueKey. This keeps the visual label tied to the rich option object while the form stores only the stable identifier.




Function keys

labelKey, valueKey, and groupKey can also be functions. Use function keys when the visible label, primitive value, or group metadata needs to be derived from the raw option object.




Multiple selection

Multiple selection stores an array of primitive values and keeps the dropdown open after each selection. Selected options are rendered as removable chips.




Free text

freeText allows values that are not present in the option list. In multiple mode, committed free text becomes a chip; without freeText, unresolved search text is discarded on close.




Hydrated values

Hydrated values are useful on edit screens where the API returns objects before the option list is loaded. The component normalizes object values to primitives, keeps their labels as preload data, and replaces those labels when fresh options with the same value arrive.

Templates

Content customization. Header, group, item, and footer templates let the consumer shape the overlay while keeping keyboard navigation, active descendant, selection, and form behavior inside the component.

Custom content

Custom item, group, header, footer, chip, and empty-state templates. Template contexts expose normalized options and search state, so custom UI remains type-safe while the form value stays primitive. Chip templates preserve the built-in removal behavior and accessibility contract.


    
Available users Select a teammate by name, e-mail, or department.
{{ group.label }} {{ group.items.length }} users
{{ item.label }} {{ item.raw?.['email'] }}
{{ item.label }}
No teammates found {{ state.label }}

Search behavior. By default the component is server-search friendly: it emits debounced queries and displays the provided options. Use localSearch when the options in memory should be filtered by the component itself.

Default local search. localSearch enables the built-in permissive filter, which compares label, name, and group using normalized text, so accents, casing, and punctuation do not make the search brittle.




Custom local search. Passing a function to localSearch replaces the built-in filter and lets the consumer decide exactly which fields should be queried.




Server search with searchChange. The emitted query already respects minSearch and searchDebounce, so the consumer can fetch data directly without duplicating debounce logic.




Lazy fetching

Lazy fetching can be triggered from dropdownOpenChange. This is useful when the first request should happen only after the user opens the autocomplete instead of during initial page render.




Min search and debounce

minSearch delays searching until the query has enough characters. The same rule is used by local filtering and server search events, and the overlay explains the required length.




Data loading

Large and remote datasets. Infinite loading and virtual scroll are opt-in directives so normal autocomplete usage stays simple while heavy scenarios can add explicit performance behavior.

Infinite loading

Infinite loading uses a sentinel inside the options overlay. It emits loadMore when the user reaches the end and respects the component loading state to avoid repeated requests.




Virtual scroll

Virtual scroll renders only the visible option rows. This example lazy-loads ten thousand users when the dropdown opens, then renders the grouped list with explicit virtual dimensions.




Forms

Form integration. The component implements ControlValueAccessor and works with Angular Signal Forms and Reactive Forms while keeping its internal search input as a private implementation detail.

Signal forms

Signal Forms integration through Angular's [formField] directive. The autocomplete value is still normalized through valueKey, while validation and disabled state are provided by the form field.

Reactive forms

Reactive Forms integration with validation, programmatic updates, reset, and disabled state.

Field composition and validations

Field composition and validation examples. fkt-autocomplete composes fkt-field internally, so it inherits the same prefix, suffix, hint, required marker, and error projection contract. Import field slot directives from frakton-ng/field when you need to customize those regions.

Read the full field contract in the Field documentation.

Field composition

Field composition slots. Prefix, suffix, hint start, and hint end are projected into the internal fkt-field. A custom suffix replaces the autocomplete default action button.


    
    

    Search by user name or department.
    Optional



Automatic validation

Automatic validation. Without [fktError], the internal fkt-field renders the configured automatic error message and keeps the same visibility rule used by other field-based controls.

The automatic error comes from the field error resolver. Required

Manual validation

Manual validation content. Project [fktError] when the autocomplete needs custom error markup while still using the field's invalid state, spacing, and visibility behavior.

Projected error content replaces the automatic message. Required Choose an approver before continuing.

Autocomplete

API Reference

Value Model

fkt-autocomplete separates the search query from the form value.

  • The query is temporary text used to search and resolve options.
  • The form value is the selected primitive value derived from valueKey.
  • Multiple mode stores an array of primitive values.
  • Object values written programmatically are normalized to primitives.

Option Resolution

Primitive values are resolved against the current options first. If the option is not available yet, the primitive value is used as a temporary label so edit screens can render before async data arrives.

Full option objects written programmatically are treated as hydrated/preloaded values:

  • valueKey is used to normalize the form value.
  • labelKey is used to render the visible label.
  • Preloaded values do not automatically appear in the dropdown.
  • When a real option with the same value later appears in options, it replaces the preloaded label.

labelKey, valueKey, and groupKey accept property names or functions:

<fkt-autocomplete
    [labelKey]="getLabel"
    [valueKey]="getValue"
    [groupKey]="getGroup"
/>

Search

By default, the component is server-search friendly. It emits searchChange after minSearch and searchDebounce are satisfied, and renders the options provided by the consumer.

Use localSearch when the current options array should be filtered by the component:

<fkt-autocomplete localSearch />

Passing a function to localSearch replaces the built-in search:

<fkt-autocomplete [localSearch]="customSearch" />

The built-in local search checks label, name, and group using normalized text comparison.

Use dropdownOpenChange when data should be fetched lazily only after the user opens the autocomplete:

<fkt-autocomplete
    (dropdownOpenChange)="$event && fetchOptions()"
    (searchChange)="searchOptions($event)"
/>

The output reports both opening and closing transitions. It observes the dropdown lifecycle; opening, closing, focus, keyboard behavior, and typed-value commit remain managed by the Autocomplete.

Commit Behavior

When the overlay closes, typed text is resolved before the component discards it:

  • If the text matches an option by value or label, that option is applied.
  • If it does not match and freeText is false, the search field is cleared.
  • If it does not match and freeText is true, the typed value becomes the selected value.
  • In multiple mode, free text is added as a chip and the search field is cleared.

Field Composition

fkt-autocomplete composes fkt-field internally. Because of that, the same field inputs can be passed directly to the autocomplete:

  • hint
  • showError
  • size
  • requiredMarker
  • hideLabel

The autocomplete also accepts the field projection slots. Import those directives and components from frakton-ng/field:

import {
  FktErrorDirective,
  FktFieldErrorComponent,
  FktFieldPrefixDirective,
  FktFieldSuffixDirective,
  FktHintEndDirective,
  FktHintStartDirective,
} from 'frakton-ng/field';
<fkt-autocomplete label="User" formControlName="user" [options]="users">
  <fkt-icon fktFieldPrefix name="user" />
  <span fktHintStart>Search by name or department.</span>
  <span fktHintEnd>Required</span>

  <fkt-field-error fktError>
    Select a valid user.
  </fkt-field-error>
</fkt-autocomplete>

fktFieldSuffix replaces the default autocomplete action button. Use it when the trailing action area needs custom behavior.

For the full field contract, see Field documentation.

Templates

The overlay accepts projected templates for advanced rendering:

  • fktAutocompleteHeader
  • fktAutocompleteGroup
  • fktAutocompleteItem
  • fktAutocompleteFooter
  • fktAutocompleteChip
  • fktAutocompleteEmpty

Templates customize rendering only. Keyboard navigation, active descendant, selection, form value, and overlay behavior remain managed by the component.

fktAutocompleteChip receives the normalized selected option. It replaces the chip content while the autocomplete keeps the removable button, disabled state, focus handling, and accessible label.

fktAutocompleteEmpty receives an empty-state object containing label, query, minSearch, and reason. The reason is min-search, query-no-results, or no-results.

Performance Directives

fktAutocompleteInfiniteLoading adds a sentinel to the overlay and emits loadMore when the end is visible.

fktAutocompleteVirtualScroll renders only visible rows and requires explicit virtual dimensions:

<fkt-autocomplete
    fktAutocompleteVirtualScroll
    [virtualItemHeight]="40"
    [maxVirtualItems]="1000"
/>

The explicit limit prevents development-time surprises with browser scroll-height limits.