# Autocomplete

> Suggest values under a text field as the user types.

## Introduction

Add `autocomplete` to a text input inside `.field`. `AutoInit()` starts every `.autocomplete` except `no-autoinit`, but the default `data` list is empty — pass options (or call `init`) to give it something to suggest.

 Autocomplete

Set `isMultiSelect: true` to pick several values. A count appears on the field.

 Multiple Autocomplete

```
<div class="field">
  <span class="material-symbols prefix" aria-hidden="true">textsms</span>
  <input type="text" id="autocomplete-input" class="autocomplete" placeholder=" ">
  <label for="autocomplete-input">Autocomplete</label>
</div>
```

## Initialization

The IIFE bundle exposes `Expressive.Autocomplete`. `data` is an array of objects:

-   **id** (required) — a string or number. Used as the option text when `text` is omitted.
-   **text** — display label. The default search matches `id` and `text`.
-   **image** — image URL. Shown as a circle; not searched by default.
-   **description** — optional secondary line under the label.

Extra properties are ignored by the default search. Filter them yourself in `onSearch`.

```
document.addEventListener('DOMContentLoaded', function() {
  const elems = document.querySelectorAll('.autocomplete');
  Expressive.Autocomplete.init(elems, {
    minLength: 0,
    data: [
      { id: 12, text: 'Apple' },
      { id: 13, text: 'Microsoft' },
      { id: 42, text: 'Google', image: 'https://picsum.photos/id/64/250/250' }
    ]
  });
});
```

Multiple selection:

```
Expressive.Autocomplete.init(document.querySelector('#autocomplete-multi'), {
  minLength: 0,
  isMultiSelect: true,
  data: [
    { id: 12, text: 'Apple' },
    { id: 13, text: 'Microsoft' },
    { id: 42, text: 'Google', image: 'https://picsum.photos/id/64/250/250' }
  ]
});
```

Custom `onSearch` can load data asynchronously. When the list is ready, call `setMenuItems`. The default filter looks at `id` and `text` only:

```
onSearch: function(text, autocomplete) {
  const normSearch = text.toLocaleLowerCase();
  autocomplete.setMenuItems(
    autocomplete.options.data.filter(function(option) {
      return option.id.toString().toLocaleLowerCase().includes(normSearch)
        || (option.text && option.text.toLocaleLowerCase().includes(normSearch));
    })
  );
}
```

## Options

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `data` | Array | `[]` | Suggestion list. Each item needs an `id`; `text`, `image`, and `description` are optional. |
| `isMultiSelect` | Boolean | `false` | If true, several values can be selected. `onAutocomplete` receives an array. |
| `maxMenuHeight` | String | `'300px'` | Max height of the suggestion menu. |
| `onAutocomplete` | Function | `null` | Called after a selection (and when a default value is applied). Receives the selected entries. |
| `onSearch` | Function | filters `id` and `text` | Called when the input text changes. Load or filter data, then call `setMenuItems`. |
| `minLength` | Number | `1` | Characters required before suggestions open. `0` shows the list on click or focus. |
| `menuOptions` | Object | see note | Options for [Menu](/menu.html.md#options). Defaults include `autoFocus: false`, `closeOnClick: false`, and `coverTrigger: false`. |
| `allowUnsafeHTML` | Boolean | `false` | If true, matched text is inserted as HTML. Only use sanitized data. |
| `selected` | Array | `[]` | Initial selected ids (strings or numbers). |

## Methods

> All methods are called on the plugin instance. You can get the instance like this:

```
const instance = Expressive.Autocomplete.getInstance(elem);
instance.open();
```

### .open();

Open the suggestion menu if the input meets `minLength`.

```
instance.open();
```

### .close();

Close the suggestion menu.

```
instance.close();
```

### .selectOption();

Select (or toggle, when multi-select) the entry with this id.

```
instance.selectOption(42);
```

### .setMenuItems();

Replace the visible suggestions. Optionally pass selected ids and whether to open the menu (default `true`).

```
instance.setMenuItems([
  { id: 'Test' },
  { id: 12, text: 'Apple' },
  { id: 13, text: 'Microsoft' },
  { id: 42, text: 'Google', image: 'https://picsum.photos/id/64/250/250' }
]);
```

### .destroy();

Destroy the plugin instance, remove the menu, and tear down its event handlers.

```
instance.destroy();
```

## Properties

| Name | Type | Description |
| --- | --- | --- |
| `el` | Element | The input the plugin was initialized with. |
| `options` | Object | The options the instance was initialized with. |
| `isOpen` | Boolean | Whether the suggestion menu is open. |
| `count` | Number | Number of matching options (reset on each keyup/focus). |
| `activeIndex` | Number | Index of the keyboard-highlighted option, or `-1`. |
| `menu` | Menu | The Menu instance for this autocomplete. |
| `selectedValues` | Array | The currently selected entries. |
