
Syncfusion Angular Dropdowns
- 161 installs
- Updated August 4, 2026
- syncfusion/angular-ui-components-skills
Use syncfusion-angular-dropdowns for development tasks
About
syncfusion-angular-dropdowns: A skill for development. This provides functionality for development workflows.
- syncfusion-angular-dropdowns
Syncfusion Angular Dropdowns by the numbers
- 161 all-time installs (skills.sh)
- +5 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #2,332 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/angular-ui-components-skills --skill syncfusion-angular-dropdownsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 161 |
|---|---|
| Last updated | August 4, 2026 |
| Repository | syncfusion/angular-ui-components-skills ↗ |
What it does
Use syncfusion-angular-dropdowns for development tasks
Files
Implementing Syncfusion Angular Dropdowns
Security & Trust Boundary
Default posture: local data only
All dropdown components in this skill default to local, in-memory data sources. Binding a component to a remote HTTP endpoint (via DataManager or any Observable/HTTP source) is a non-default, elevated-risk operation that requires an explicit security review before it is permitted in production code.
⛔ **Do not generate or suggest remote DataManager / HTTP data-source configurationsunless the consuming application has passed a security review confirming that:**
1. The target endpoint is owned and operated by the same team as the application.
2. The endpoint enforces authentication, authorization, and input validation.
3. All responses are sanitized before being bound to a component dataSource.4. A Content Security Policy (CSP) covering the origin is in place.
Mandatory security requirements
| # | Requirement |
|---|---|
| 1 | Local data by default. Use plain TypeScript arrays for dataSource unless a remote source has been explicitly approved. |
| 2 | No public or third-party URLs. Never configure a data source that fetches from an endpoint outside the application's own origin. |
| 3 | Sanitize all external data before binding. Any value that originates outside the application (API response, local-storage read) must be stripped of HTML/script content before assignment to dataSource or value. |
| 4 | Sanitize user filter input. Before forwarding typed text to any server query, strip non-alphanumeric characters to prevent injection. |
| 5 | No `crossDomain: true` by default. CORS relaxation in DataManager must be explicitly justified and reviewed. |
| 6 | Pin package versions. Every @syncfusion/ej2-* dependency must be locked to an exact version in package.json; verify against the lockfile after every install. |
| 7 | No CDN asset loading without SRI. CSS/JS must be resolved from node_modules at build time, not fetched from a CDN at runtime without Subresource Integrity hashes. |
| 8 | No sensitive data in local storage. enablePersistence must never store tokens, credentials, or PII; sanitize any value read back before use. |
---
AutoComplete
A text input component that provides matching suggestions as the user types. Supports free-form input, remote data, filtering strategies, grouping, virtual scrolling, and full Angular forms integration.
Component Overview & Architecture
The AutoComplete is a text input component that provides matching suggestions as the user types. It is designed for:
1. Type-ahead suggestions — shows matching items from a data source as the user types 2. Free-form input — users can type any value, not restricted to the list 3. Search/filter — multiple filter strategies (StartsWith, Contains, EndsWith) 4. Autofill — automatically completes the first matched suggestion in the input 5. Grouped suggestions — categorize items by a groupBy field 6. Virtual scrolling — efficiently handles thousands of items 7. Template customization — item, group, header, footer, and empty-state templates
Key Characteristics
| Aspect | Details |
|---|---|
| Selection | Single item; user can also type any free-form value |
| Data Sources | Local arrays, remote DataManager, OData, Web API, Observable (async pipe) |
| Filtering | Built-in filtering: StartsWith, EndsWith, Contains |
| Autofill | Completes the first match inline as the user types |
| Performance | Virtual scrolling for large datasets (1,000+ items) |
| Forms | Template-driven (ngModel) and reactive (FormControl) form integration |
| Accessibility | WCAG 2.2 compliant, full keyboard navigation, ARIA attributes |
| Customization | Item, group, header, footer, noRecords, actionFailure templates; CSS theming |
---
Documentation Navigation Guide
📄 Getting Started
Read: references/autocomplete-getting-started.md
- Install
@syncfusion/ej2-angular-dropdownspackage - Set up Angular 21+ project with standalone components
- Import
AutoCompleteModuleand required CSS themes - Create your first AutoComplete with basic data binding
- Configure popup height, width, and placeholder
- Enable two-way binding with
[(value)]
📄 Data Binding
Read: references/autocomplete-data-binding.md
- Bind to local arrays (strings, numbers, objects, complex objects)
- Map
value,text, andiconCssfields viafieldsproperty - Remote data using DataManager with OData, Web API adapters
- Async pipe pattern for RxJS Observables
- Object binding with
allowObjectBinding - Preselecting values using the
valueproperty
📄 Filtering & Search
Read: references/autocomplete-filtering-and-search.md
- Configure
filterType(StartsWith, Contains, EndsWith) - Limit suggestion count with
suggestionCount - Minimum character threshold with
minLength - Case-sensitive filtering with
ignoreCase - Diacritics/accent-insensitive filtering with
ignoreAccent - Debounce delay to optimize remote filtering with
debounceDelay - Custom filtering via the
filteringevent withupdateData
📄 Grouping & Templates
Read: references/autocomplete-grouping-and-templates.md
- Group suggestions by category using
fields.groupBy - Item templates for custom rendering
- Group header templates (inline and fixed)
- Header and footer templates for the popup
- Empty state with
noRecordsTemplate - Action failure template for remote data errors
📄 Feature Configuration
Read: references/autocomplete-feature-configuration.md
- Autofill: inline suggestion completion with
autofillproperty - Highlight matched characters with
highlightproperty - Disable individual items with
fields.disabledordisableItemmethod - Disable entire component with
enabledproperty - Resizable popup with
allowResize - Virtual scrolling for large datasets with
enableVirtualization - Show/hide popup button with
showPopupButton - Show/hide clear button with
showClearButton - RTL support with
enableRtl - Sort order with
sortOrder
📄 Form Support & Validation
Read: references/autocomplete-form-support-and-validation.md
- Template-driven forms using
ngModelandFormsModule - Reactive forms using
FormControl,FormGroup, andReactiveFormsModule - Binding and validation patterns
- Pre-selecting values via form model
📄 Accessibility & Localization
Read: references/autocomplete-accessibility-and-localization.md
- WCAG 2.2, Section 508, and ADA compliance
- Full keyboard shortcuts (Arrow keys, Tab, Enter, Escape, Alt+Down/Up)
- ARIA attributes:
aria-haspopup,aria-expanded,aria-selected,aria-autocomplete - Screen reader support and focus management
- Localization with
L10n.load()fornoRecordsTemplateandactionFailureTemplate - RTL language support
📄 Advanced Patterns & How-To
Read: references/autocomplete-advanced-patterns-how-to.md
- Autofill feature with the
autofillproperty - Highlight searched characters with the
highlightproperty - Multi-field custom filtering with
Predicate(filter by both Name and Code) - Icon support via
fields.iconCss - Suggestion list on focus from browser local storage
⚠️ Security note: Local storage is accessible to any JavaScript running on the same
origin and is a common XSS attack surface. Never store sensitive data (tokens, PII) in
local storage. Sanitize any values read from local storage before binding them to the
component'sdataSourceorvalue.
- Custom search and highlight styling
📄 API Reference
Read: references/autocomplete-api.md
- Complete properties reference with types, defaults, and descriptions
- All methods with signatures and usage
- All events with payload types and handler examples
---
Quick Start Example
// app.component.ts (Angular 21 Standalone)
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
selector: 'app-root',
standalone: true,
imports: [AutoCompleteModule],
template: `
<ejs-autocomplete
id="sports"
[dataSource]="sportsData"
placeholder="Find a sport"
[(value)]="selectedValue">
</ejs-autocomplete>
`
})
export class AppComponent {
public sportsData: string[] = [
'Badminton', 'Basketball', 'Cricket',
'Football', 'Golf', 'Hockey', 'Tennis'
];
public selectedValue: string = '';
}Install the package:
⚠️ Security note: Pin the package to a specific version to prevent unintended upgrades
to potentially compromised releases. Verify the installed version against your lockfile
(package-lock.json/yarn.lock) after installation.
ng add @syncfusion/ej2-angular-dropdowns@<version>Add CSS (styles.css):
⚠️ Security note: These imports are resolved from node_modules at build time.Ensure the installed Syncfusion packages match your pinned versions in package-lock.jsonor yarn.lock before building. Do not source these files from a CDN withoutSubresource Integrity (SRI) hashes.
@import '../node_modules/@syncfusion/ej2-base/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-lists/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material3.css';---
Common Patterns
Pattern 1: Filter with Complex Object Data
// Map fields for object array
public fields: Object = { value: 'Game' };
public sportsData: { [key: string]: Object }[] = [
{ Id: 'Game1', Game: 'Badminton' },
{ Id: 'Game2', Game: 'Cricket' }
];<ejs-autocomplete [dataSource]="sportsData" [fields]="fields" placeholder="Find a game">
</ejs-autocomplete>When to use: Whenever your data is an array of objects and you need to display one field as the suggestion text.
---
Pattern 2: Autofill + Highlight
<ejs-autocomplete
[dataSource]="data"
[autofill]="true"
[highlight]="true"
filterType="StartsWith">
</ejs-autocomplete>When to use: Search bars where users expect inline completion and visual emphasis on matched text.
---
Pattern 3: Remote Data with Debounce
🔒 Security policy — remote data is a restricted pattern.
Binding AutoComplete to a remote endpoint requires a security review (see
Security & Trust Boundary above) before use in production.
Remote data binding details and requirements are documented in
references/autocomplete-data-binding.md.
No remote `DataManager` example is provided here by default.
When to use: API-backed autocomplete where you want to reduce request frequency — only after the endpoint and data pipeline have been reviewed per the security requirements above.
---
Pattern 4: Virtual Scrolling for Large Datasets
import { AutoCompleteComponent, VirtualScroll } from '@syncfusion/ej2-angular-dropdowns';
AutoCompleteComponent.Inject(VirtualScroll);<ejs-autocomplete
[dataSource]="records"
[fields]="fields"
[enableVirtualization]="true"
popupHeight="200px">
</ejs-autocomplete>When to use: Datasets with 1,000+ items where rendering all DOM elements at once is costly.
---
Key Properties Quick Reference
| Property | Type | Default | Purpose |
|---|---|---|---|
dataSource | Array \ | DataManager | [] |
fields | FieldSettingsModel | { value: null } | Map data columns to component |
placeholder | string | null | Hint text when empty |
value | string \ | number \ | boolean \ |
filterType | FilterType | 'Contains' | How suggestions are matched |
minLength | number | 1 | Minimum chars to trigger suggestions |
suggestionCount | number | 20 | Max suggestions shown |
autofill | boolean | false | Inline completion of first match |
highlight | boolean | false | Highlight matched characters |
ignoreCase | boolean | true | Case-insensitive filtering |
ignoreAccent | boolean | — | Ignore diacritics in filtering |
debounceDelay | number | 300 | Delay (ms) before filtering fires |
enableVirtualization | boolean | false | Virtual scroll for large data |
allowResize | boolean | false | Resizable popup |
showClearButton | boolean | true | Show ✕ to clear value |
showPopupButton | boolean | false | Show dropdown toggle button |
enabled | boolean | true | Enable/disable entire component |
readonly | boolean | false | Prevent user edits |
allowObjectBinding | boolean | false | Bind value as full object |
sortOrder | SortOrder | null | Sort suggestions (Ascending/Descending) |
popupHeight | string \ | number | '300px' |
popupWidth | string \ | number | '100%' |
locale | string | 'en-US' | Localization culture |
enableRtl | boolean | false | Right-to-left rendering |
---
Workflow Decision Tree
Need to implement AutoComplete?
│
├─ What's your data source?
│ ├─ Local array → See Data Binding: "Array of string" or "Array of object"
│ └─ Remote API → See Data Binding: "Bind to remote data"
│
├─ How should filtering work?
│ ├─ Default (Contains) → No extra config needed
│ ├─ StartsWith → filterType="StartsWith"
│ ├─ Custom multi-field → See Advanced Patterns: "Custom filtering"
│ └─ Accent-insensitive → [ignoreAccent]="true"
│
├─ Need autofill (inline completion)?
│ └─ YES → [autofill]="true" + filterType="StartsWith"
│
├─ Highlight matched text?
│ └─ YES → [highlight]="true"
│
├─ Large dataset (1,000+ items)?
│ └─ YES → [enableVirtualization]="true" + inject VirtualScroll
│
├─ Using inside a form?
│ ├─ Template-driven → See Form Support: "ngModel"
│ └─ Reactive → See Form Support: "FormControl"
│
└─ Need accessibility or localization?
└─ YES → See Accessibility & Localization referenceComboBox
A flexible dropdown component that allows users to select from a predefined list or enter a custom value. Supports filtering, grouping, templates, virtual scrolling, and full Angular forms integration.
Component Overview & Architecture
The ComboBox is a flexible dropdown component that allows users to: 1. Select from a list of predefined options 2. Enter custom values when allowCustom is enabled 3. Search/filter items as they type 4. Group items by category 5. Customize display with templates for items, groups, headers, footers
Key Characteristics
| Aspect | Details |
|---|---|
| Selection | Single item from predefined list or custom value |
| Data Sources | Local arrays, remote DataManager, OData, Web API, async data |
| Filtering | Built-in filtering with configurable strategies (StartsWith, Contains, EndsWith) |
| Performance | Virtual scrolling for large datasets (10,000+ items) |
| Forms | Works with template-driven forms (ngModel) and reactive forms (FormControl) |
| Accessibility | WCAG 2.2 compliant, full keyboard navigation, ARIA attributes |
| Customization | Templates for items, groups, headers; CSS theming support |
---
Documentation Navigation Guide
📄 Getting Started
Read: references/combobox-getting-started.md
- Install
@syncfusion/ej2-angular-dropdownspackage - Set up Angular 21+ project with standalone components
- Import required modules and CSS themes
- Create your first ComboBox with minimal code
- Basic event handlers and configuration
📄 Data Binding & Sources
Read: references/combobox-data-binding.md
- Bind to local arrays (strings, numbers, objects)
- Map text and value fields for complex data
- Remote data from Web APIs, OData services
- DataManager configuration for different data adapters
- Async pipe for RxJS Observables
- Handling dynamic data updates
📄 Filtering & Search
Read: references/combobox-filtering-and-search.md
- Enable filtering with
allowFilteringproperty - Configure filter types (StartsWith, Contains, EndsWith, etc.)
- Case-sensitive filtering for strict matching
- Diacritics filtering for accent-insensitive search
- Debounce delay to optimize remote requests
- Minimum filter character requirements
- Custom filtering with remote queries
📄 Grouping & Templates
Read: references/combobox-grouping-and-templates.md
- Group items by category using
groupByfield - Item templates for custom item rendering
- Group header templates (inline and fixed)
- Footer templates for additional information
- Combining multiple templates effectively
- Template performance optimization
📄 Advanced Feature Configuration
Read: references/combobox-feature-configuration.md
- Disable specific items or the entire component
- Read-only mode for display-only scenarios
- Virtual scrolling for thousands of items
- Dynamic resize behavior
- Allow custom values not in the list
- Styling and theme integration
- RTL support for Arabic/Hebrew
📄 Form Support & Validation
Read: references/combobox-form-support-and-validation.md
- Two-way binding with template-driven forms (ngModel)
- Reactive forms with FormControl and FormGroup
- Built-in and custom validators
- Form submission and validation state
- Disabled ComboBox in form context
- Error message display patterns
📄 Accessibility & Localization
Read: references/combobox-accessibility-and-localization.md
- WCAG 2.2, Section 508, and ADA compliance
- Keyboard navigation shortcuts (arrow keys, Tab, Enter, Escape)
- Screen reader support with ARIA attributes
- Focus management and visual indicators
- Localization strings for different languages
- Right-to-left (RTL) language support
📄 Advanced Patterns & How-To Guides
Read: references/combobox-advanced-patterns-and-how-to.md
- Autofill suggestions for autocomplete behavior
- Cascading ComboBoxes with dependent dropdowns
- Icons and emoji support in list items
- Resizable popup for better visibility
- Real-world patterns (search, live data, grouping)
- Performance optimization techniques
📄 API Reference
Read: references/combobox-api.md
- Complete properties reference with types, defaults, and examples
- All methods with signatures, parameters, and usage examples
- All events with payload types and handler examples
- Notes on template syntax, two-way binding, and virtual scrolling
- Links to official Syncfusion documentation
---
Quick Start Example
Minimal Setup (5 minutes)
// app.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ComboBoxComponent, ComboBoxModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, ComboBoxModule],
template: `
<ejs-combobox
[dataSource]="data"
fields="{ text: 'text', value: 'id' }"
placeholder="Select a language"
[(ngModel)]="selectedValue">
</ejs-combobox>
`
})
export class AppComponent {
selectedValue = '';
data = [
{ id: '1', text: 'JavaScript' },
{ id: '2', text: 'TypeScript' },
{ id: '3', text: 'Angular' },
{ id: '4', text: 'React' }
];
}What's happening: 1. Import ComboBoxComponent from @syncfusion/ej2-angular-dropdowns 2. Define data array with objects (id, text) 3. Use fields to map text and value fields 4. Bind selected value with [(ngModel)] 5. Set placeholder for empty state
---
Common Patterns & Workflows
Pattern 1: Autocomplete with Autofill
[autofill]="true" // Auto-complete suggestions
[allowFiltering]="true" // Enable typing
filterType="StartsWith" // Match from beginningWhen to use: Skills, tags, email domains (user types 'j', sees 'JavaScript')
See: Advanced Patterns
---
Pattern 2: Cascading Dependent Dropdowns
// Country → State → City relationship
onCountryChange() {
this.states = this.getStatesFor(country);
}
onStateChange() {
this.cities = this.getCitiesFor(state);
}When to use: Address selection, hierarchical data (country/state/city)
See: Advanced Patterns
---
Pattern 3: Grouped Items with Icons
fields = {
text: 'Name',
value: 'Id',
groupBy: 'Category',
iconCss: 'Icon'
};When to use: Visual organization (languages with icons, file types)
See: Advanced Patterns
---
Pattern 4: Resizable Dropdown for Long Content
[allowResize]="true" // Enable resize handle
itemTemplate="customTemplate" // Show rich contentWhen to use: Product listings, descriptions, detailed information
See: Advanced Patterns
---
Key Props & Configuration
Essential Properties
| Property | Type | Default | When to Use |
|---|---|---|---|
dataSource | Array \ | DataManager | [] |
fields | Object | { text, value } | Map data structure to ComboBox |
placeholder | string | '' | Show hint when empty |
allowFiltering | boolean | false | Enable search/filter |
allowCustom | boolean | false | Allow values not in list |
readonly | boolean | false | Prevent editing |
enabled | boolean | true | Disable entire component |
[(ngModel)] | any | undefined | Two-way value binding |
Advanced Properties
| Property | Type | When to Use |
|---|---|---|
itemTemplate | string \ | TemplateRef |
groupTemplate | string \ | TemplateRef |
footerTemplate | string \ | TemplateRef |
enableVirtualization | boolean | 10,000+ items (performance) |
groupBy | string | Organize items by category |
filterType | string | StartsWith \ |
debounceDelay | number | Remote data request delay |
---
Component Lifecycle
1. CREATE: Component initialized
↓
2. DATA BIND: dataSource loaded & displayed
↓
3. USER INTERACTION: typing, clicking, keyboard
↓
4. FILTER/SEARCH: items filtered based on input
↓
5. SELECT: user chooses item or enters custom value
↓
6. VALUE UPDATE: ngModel updates, events fire
↓
7. DESTROY: component cleaned upKey events to handle:
change: When selected value changesfiltering: When user types (filter queries)select: When item is selectedfocus: When component gets focusblur: When component loses focus
---
Workflow Decision Tree
Need to implement ComboBox? Follow this decision tree:
1. Do you have data to display?
├─ YES: Go to "Data Binding & Sources" reference
└─ NO: Define your data array first
2. Do users need to search/filter?
├─ YES: Go to "Filtering & Search" reference
└─ NO: allowFiltering = false (default)
3. Do you need to group items?
├─ YES: Go to "Grouping & Templates" reference
└─ NO: Skip grouping configuration
4. Are you using a form?
├─ YES: Go to "Form Support & Validation" reference
└─ NO: Use standalone ComboBox
5. Is accessibility required?
├─ YES: Go to "Accessibility & Localization" reference
└─ NO: Still recommended for compliance
6. Performance issues with large datasets?
├─ YES: Enable virtual scrolling + pagination
└─ NO: Standard rendering is fine---
Next Steps
1. Start here: Getting Started - Set up your first ComboBox 2. Bind data: Data Binding & Sources - Connect to your data 3. Add search: Filtering & Search - Enable user filtering 4. Customize: Grouping & Templates - Style and organize display 5. Advanced: Advanced Patterns & How-To - Autofill, cascading, icons, resizing 6. Features: Feature Configuration - Enable advanced features 7. Integrate: Form Support - Connect to forms 8. Polish: Accessibility - Ensure compliance 9. Reference: API Reference - Full properties, methods, and events reference
---
Additional Resources
- Syncfusion Angular ComboBox API Reference
- Angular Version Support
- DataManager Documentation
- Component Themes & Styling
DropDownList
A single-value selection component from a predefined list. Supports local and remote data sources, filtering, grouping, custom templates, virtualization for large datasets, and full Angular forms integration.
Documentation Navigation Guide
Getting Started
📄 Read: references/dropdownlist-getting-started.md
- Installation and Angular CLI setup
- Installing
@syncfusion/ej2-angular-dropdowns - CSS/theme imports for Material3
- Adding
<ejs-dropdownlist>to the template - Basic data binding with
[dataSource] - Popup height/width configuration
- Two-way binding with
[(value)]
Data Binding
📄 Read: references/dropdownlist-data-binding.md
- Binding primitive arrays (strings, numbers)
- Binding arrays of objects with
[fields]mapping - Binding to nested/complex objects
- Remote data via
DataManager(OData, Web API) - Async pipe with Observable data streams
- Value binding (primitive and object types with
allowObjectBinding)
Filtering
📄 Read: references/dropdownlist-filtering.md
- Enabling search with
[allowFiltering] - Using the
filteringevent andupdateData()method - Minimum character threshold before filtering starts
- Filter types:
contains,startsWith,endsWith - Case-sensitive filtering
- Diacritics/accent-insensitive filtering
- Debounce delay for performance optimization
Templates
📄 Read: references/dropdownlist-templates.md
- Item template: customize each list item
- Value template: customize the selected value display
- Group template: customize group header appearance
- Header template: static element at popup top
- Footer template: static element at popup bottom
- No-records template: empty state display
- Action failure template: error state display
Grouping & Virtualization
📄 Read: references/dropdownlist-grouping-and-virtualization.md
- Grouping items with
groupByfield - Inline and fixed floating group headers
- Virtual scrolling with
[enableVirtualization]for large lists - Virtual scrolling with remote data
- Combining filtering and virtualization
- Customizing item count in virtual mode
Disabled Items & Forms
📄 Read: references/dropdownlist-disabled-items-and-forms.md
- Disabling specific items via
fields.disabled - Dynamic
disableItem()method (by value, index, or element) - Disabling the entire component with
[enabled]="false" - Template-driven forms with
[(ngModel)] - Reactive forms with
FormControlandFormGroup
Customization & Styling
📄 Read: references/dropdownlist-customization-and-styling.md
- CSS overrides for wrapper, icon, focus states
- Outline theme focus customization
- Popup appearance and list item styles
- Float label and placeholder styling
- Mandatory asterisk pattern
- Localization with
L10nclass - RTL (right-to-left) support
How-To Recipes
📄 Read: references/dropdownlist-how-to.md
- Add / remove / clear items dynamically
- Close popup programmatically
- Cascading DropDownLists
- Customize group header template
- Highlight filtered characters
- Incremental search behavior
- Modify remote data results
- Remote data item count display
- Tooltip on list items
- Value change event handling
- Icon support in list items
API Reference
📄 Read: references/dropdownlist-api.md
- Complete properties reference with types, defaults, and usage examples
- All methods with signatures, parameters, and return types
- All events with argument interfaces and usage examples
- Interface details:
FieldSettingsModel,ChangeEventArgs,SelectEventArgs,PopupEventArgs,FilteringEventArgs - Quick-reference summary tables for properties, methods, and events
Quick Start Example
import { Component, OnInit } from '@angular/core';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
standalone: true,
imports: [DropDownListModule],
selector: 'app-root',
template: `
<ejs-dropdownlist
id="ddl"
[dataSource]="sports"
[fields]="fields"
placeholder="Select a sport"
[(value)]="selectedValue"
(change)="onChange($event)">
</ejs-dropdownlist>
<p>Selected: {{ selectedValue }}</p>
`
})
export class AppComponent implements OnInit {
public sports: { id: number; name: string }[] = [];
public fields = { text: 'name', value: 'id' };
public selectedValue: number = 2;
ngOnInit() {
this.sports = [
{ id: 1, name: 'Badminton' },
{ id: 2, name: 'Cricket' },
{ id: 3, name: 'Football' },
{ id: 4, name: 'Tennis' }
];
}
onChange(args: any) {
this.selectedValue = args.value;
}
}Common Patterns
Searchable Dropdown
// Enable filtering in template
// <ejs-dropdownlist [allowFiltering]="true" (filtering)="onFilter($event)">
import { FilteringEventArgs } from '@syncfusion/ej2-angular-dropdowns';
import { Query } from '@syncfusion/ej2-data';
onFilter(args: FilteringEventArgs) {
let query = new Query();
query = args.text !== ''
? query.where('name', 'contains', args.text, true)
: query;
args.updateData(this.sports, query);
}Remote Data Dropdown
🔒 Security policy — remote data is a restricted pattern.
Binding DropDownList to a remote endpoint requires a security review (see
Security & Trust Boundary) before use in production.
Remote data binding details and requirements are documented in
references/dropdownlist-data-binding.md.
No remote `DataManager` example is provided here by default.
Reactive Form Integration
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
// In component:
form = this.fb.group({ sport: ['Cricket', Validators.required] });
// In template:
// <form [formGroup]="form">
// <ejs-dropdownlist formControlName="sport" [dataSource]="sports"></ejs-dropdownlist>
// </form>Key Props
| Property | Type | Description |
|---|---|---|
dataSource | `any[] \ | DataManager` |
fields | FieldSettingsModel | Maps text, value, groupBy, disabled, iconCss |
value | `string \ | number \ |
placeholder | string | Input placeholder text |
allowFiltering | boolean | Enable search box in popup |
filterType | `'contains' \ | 'startsWith' \ |
enableVirtualization | boolean | Virtual scrolling for large lists |
popupHeight / popupWidth | `string \ | number` |
enabled | boolean | Enable/disable entire component |
allowObjectBinding | boolean | Bind full object as value |
ignoreCase | boolean | Case-insensitive filtering (default: true) |
ignoreAccent | boolean | Diacritics-insensitive filtering |
debounceDelay | number | Delay (ms) before filter triggers |
itemTemplate | string | Template for list items |
valueTemplate | string | Template for selected value display |
noRecordsTemplate | string | Empty state message |
Common Use Cases
Form field with validation → See references/dropdownlist-disabled-items-and-forms.md
Large list (1000+ items) → Enable [enableVirtualization]="true" — see references/dropdownlist-grouping-and-virtualization.md
Country/State/City cascading → See references/dropdownlist-how-to.md
Custom item rendering (icons, multi-column) → See references/dropdownlist-templates.md
Remote API data → See references/dropdownlist-data-binding.md
ListBox
A list-based selection component enabling single or multi-item selection. Supports data binding, templates, drag-and-drop reordering and transfer, sorting, grouping, and comprehensive accessibility features.
Component Overview
The Syncfusion ListBox is a high-performance dropdown list replacement with advanced features:
| Feature | Benefit |
|---|---|
| Multiple Selection Modes | Single, multiple, or checkbox selection |
| Data Binding | Local arrays, complex objects, or remote services |
| Drag & Drop | Reorder items or transfer between lists |
| Customization | Icons, templates, grouping, sorting |
| Accessibility | WCAG 2.2, screen readers, keyboard navigation |
| Performance | Efficient rendering with large datasets |
Documentation Navigation Guide
Getting Started
📄 Read: references/listbox-getting-started.md
- Installation and package setup
- Angular standalone vs NgModule patterns
- Basic component initialization
- CSS imports and theme selection
- Binding local data sources
- Running and testing the application
Selection Modes and Interactions
📄 Read: references/listbox-selection-modes.md
- Single item selection
- Multiple item selection with SHIFT/CTRL
- Checkbox selection mode
- Select all functionality
- Handling change events
- Getting selected items programmatically
Data Binding and Field Mapping
📄 Read: references/listbox-data-binding.md
- Binding array of strings
- Binding array of objects
- Binding complex nested objects
- Remote data with DataManager and Query
- Field mapping (text, value, groupBy, iconCss)
- Troubleshooting data binding issues
Drag-and-Drop Features
📄 Read: references/listbox-drag-and-drop-features.md
- Single ListBox drag-and-drop reordering
- Dual ListBox drag-and-drop transfer
- Drag and drop events (dragStart, drag, drop)
- Scope configuration for multiple lists
- Event handling and item manipulation
- Real-world dual ListBox patterns
Customization and Styling
📄 Read: references/listbox-customization.md
- Icons and iconCss field mapping
- Custom item templates
- Grouping items by category
- Sorting items (ascending/descending)
- CSS styling and theming
- Theme Studio integration
- Responsive design
Practical Implementation Examples
📄 Read: references/listbox-practical-examples.md
- Filtering ListBox items
- Form submission with selected items
- Enable/disable items conditionally
- Scroller for large datasets
- Real-world use cases
- Common troubleshooting scenarios
How-To Guides and Common Tasks
📄 Read: references/listbox-how-to-guides.md
- Add items programmatically
- Select items programmatically
- Enable or disable items dynamically
- Enable scroller for large datasets
- Filter ListBox data with input
- Submit selected items in forms
API Reference
📄 Read: references/listbox-api.md
- All component properties with types, defaults, and examples
- All public methods with parameter signatures and usage examples
- All events with event argument interfaces and handler patterns
- Interface definitions:
FieldSettingsModel,SelectionSettingsModel,ToolbarSettingsModel - Event arg interfaces:
ListBoxChangeEventArgs,DragEventArgs,DropEventArgs,BeforeItemRenderEventArgs,FilteringEventArgs,SourceDestinationModel - Enum definitions:
SelectionMode,SortOrder,FilterType,ToolBarPosition,CheckBoxPosition
Quick Start Example
Basic ListBox with Local Data
import { Component, OnInit } from '@angular/core';
import { ListBoxModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [ListBoxModule],
standalone: true,
selector: 'app-listbox',
template: `
<ejs-listbox
[dataSource]="items"
[selectionSettings]="{ mode: 'Multiple' }">
</ejs-listbox>
`
})
export class ListBoxComponent implements OnInit {
public items: { [key: string]: Object }[] = [];
ngOnInit(): void {
this.items = [
{ text: 'Option 1', id: '1' },
{ text: 'Option 2', id: '2' },
{ text: 'Option 3', id: '3' }
];
}
}With Styles
⚠️ Security note: These imports are resolved from node_modules at build time.Ensure the installed Syncfusion packages match your pinned versions in package-lock.jsonor yarn.lock before building. Do not source these files from a CDN withoutSubresource Integrity (SRI) hashes.
/* In your global styles.css */
@import '@syncfusion/ej2-base/styles/material3.css';
@import '@syncfusion/ej2-dropdowns/styles/material3.css';
@import '@syncfusion/ej2-inputs/styles/material3.css';
@import '@syncfusion/ej2-lists/styles/material3.css';Common Patterns
Selection with Change Event
import { ListBoxChangeEventArgs } from '@syncfusion/ej2-dropdowns';
selectedValues: string[] = [];
onSelectionChange(args: ListBoxChangeEventArgs): void {
this.selectedValues = args.value as string[];
}Template:
<ejs-listbox
[dataSource]="items"
(change)="onSelectionChange($event)">
</ejs-listbox>Dual ListBox for Transfer
sourceItems = [
{ text: 'Available Item 1', id: '1' },
{ text: 'Available Item 2', id: '2' }
];
selectedItems = [];Template:
<div style="display: flex; gap: 20px;">
<div>
<h4>Available Items</h4>
<ejs-listbox
[dataSource]="sourceItems"
allowDragAndDrop="true"
scope="transfer-list">
</ejs-listbox>
</div>
<div>
<h4>Selected Items</h4>
<ejs-listbox
[dataSource]="selectedItems"
allowDragAndDrop="true"
scope="transfer-list">
</ejs-listbox>
</div>
</div>Filtered ListBox
allItems = [
{ text: 'Apple', category: 'Fruit' },
{ text: 'Carrot', category: 'Vegetable' },
{ text: 'Banana', category: 'Fruit' }
];
get filteredItems() {
return this.allItems.filter(item =>
item.text.toLowerCase().includes(this.searchTerm.toLowerCase())
);
}Key Props
Selection Configuration
- `selectionSettings`:
{ mode: 'Single' | 'Multiple', showCheckbox: boolean, showSelectAll: boolean, checkboxPosition: 'Left' | 'Right' }> Note: When usingshowCheckbox: true, you must injectCheckBoxSelection:
```typescript
import { ListBoxComponent, CheckBoxSelection, ListBoxModule } from '@syncfusion/ej2-angular-dropdowns';
ListBoxComponent.Inject(CheckBoxSelection);
@Component({ imports: [ListBoxModule] })
``- **maximumSelectionLength`**: Limit how many items can be selected- `value`: Get or set selected values (
string[] | number[] | boolean[])
Data and Display
- `dataSource`: Array or DataManager with items
- `fields`:
{ text, value, groupBy, iconCss, disabled, htmlAttributes } - `itemTemplate`: Template for rendering each list item
- `noRecordsTemplate`: Template shown when no items match
Interactions
- `allowDragAndDrop`: Enable drag-and-drop reordering/transfer
- `scope`: Identify related ListBoxes for drag-drop transfer
- `allowFiltering`: Show built-in filter search bar
- `filterBarPlaceholder`: Placeholder text for the filter bar
- `filterType`:
'StartsWith' | 'EndsWith' | 'Contains' - `toolbarSettings`: Configure toolbar buttons for dual-ListBox transfer
Appearance
- `height`: Height of the ListBox
- `sortOrder`:
'None' | 'Ascending' | 'Descending' - `enabled`: Enable/disable component
- `enableRtl`: Right-to-left rendering
- `cssClass`: Additional CSS class
Next Steps
1. Get Started: Read references/listbox-getting-started.md for setup instructions 2. Choose Selection Mode: Review references/listbox-selection-modes.md for your use case 3. Bind Data: See references/listbox-data-binding.md for data source options 4. Add Interactions: Explore references/listbox-drag-and-drop-features.md for advanced features 5. Customize: Check references/listbox-customization.md for styling options 6. See Examples: Review references/listbox-practical-examples.md for real-world implementations 7. API Reference: Consult references/listbox-api.md for the complete properties, methods, events, and interface definitions
Common Use Cases
- Selection Forms: Multi-select dropdown replacement
- Transfer Lists: Move items between lists (dual ListBox)
- Categories: Group-based item organization
- Filtering: Filter large datasets
- Data Display: Show structured list data
- Accessibility: Compliant selection interfaces
Mention
An autocomplete suggestion popup triggered by a typed character (default @) inside a target element. Supports user tagging, custom trigger characters, rich text integration, remote data, templates, and full accessibility.
Component Overview & Architecture
The Mention component renders an autocomplete suggestion popup when the user types a trigger character (default @) inside a target element (a div[contenteditable], textarea, or similar). It is designed for:
1. User tagging — tag people, teams, or resources using @ 2. Hashtag suggestions — use any custom character (#, /, etc.) as the trigger 3. Rich text integration — works with contenteditable divs and editors 4. Data binding — supports local arrays (strings, objects, complex objects) and remote DataManager sources 5. Filtering — Contains, StartsWith, EndsWith with configurable min-length, debounce, and spacing 6. Template customization — item, display, no-records, spinner, and group templates 7. Disabled items — mark individual list items as non-selectable 8. Accessibility — WCAG 2.2 compliant with full keyboard navigation and ARIA attributes
Key Characteristics
| Aspect | Details |
|---|---|
| Trigger | Any single character via mentionChar (default @) |
| Target | Any HTMLElement or CSS selector string set via target |
| Data Sources | Local arrays (strings, objects), remote DataManager (OData, Web API) |
| Filtering | Built-in: Contains, StartsWith, EndsWith; configurable minLength, allowSpaces |
| Display | showMentionChar controls whether the trigger character is shown with selected text |
| Suffix | suffixText appends a space or newline after the selected item |
| Accessibility | WCAG 2.2, Section 508, ADA; keyboard shortcuts: Arrow keys, Enter, Tab, Escape |
| Localization | L10n.load() for noRecordsTemplate locale key |
---
Documentation Navigation Guide
📄 Getting Started
Read: references/mention-getting-started.md
- Install
@syncfusion/ej2-angular-dropdownspackage - Set up Angular 21+ project with standalone components
- Import
MentionModuleand required CSS themes - Create a target
contenteditablediv - Bind
targetand basicdataSource - Display/customize the mention character with
showMentionCharandmentionChar
📄 Data Binding
Read: references/mention-data-binding.md
- Bind to local arrays of strings, JSON objects, and complex objects
- Map
text,value,groupBy, andiconCssviafieldsproperty - Remote data binding (restricted — requires security review; see Security & Trust Boundary)
- Use the
queryproperty to scope remote requests
📄 Filtering
Read: references/mention-filtering.md
- Control filter strategy with
filterType(Contains,StartsWith,EndsWith) - Set minimum input length before triggering with
minLength - Allow spaces in the middle of a mention search with
allowSpaces - Limit visible suggestion count with
suggestionCount - Tune debounce delay for remote sources with
debounceDelay
📄 Templates
Read: references/mention-templates.md
- Customize suggestion list item layout with
itemTemplate - Customize the inserted text representation with
displayTemplate - Handle empty results with
noRecordsTemplate - Show a loading indicator while fetching remote data with
spinnerTemplate - Customize grouped items with
groupTemplate
📄 Customization
Read: references/mention-customization.md
- Show/hide the trigger character alongside selected text with
showMentionChar - Append a suffix (space, newline) after selection with
suffixText - Resize the popup with
popupHeightandpopupWidth - Change the trigger character with
mentionChar - Control leading space requirement with
requireLeadingSpace - Apply custom CSS classes with
cssClass - Highlight searched characters with
highlight - Configure
ignoreCaseandignoreAccentfor search behavior
📄 Sorting & Disabled Items
Read: references/mention-sorting-and-disabled-items.md
- Sort suggestions with
sortOrder(None,Ascending,Descending) - Mark items as non-selectable via
fields.disabled - Dynamically disable items at runtime using the
disableItemmethod
📄 Accessibility & Localization
Read: references/mention-accessibility-and-localization.md
- WCAG 2.2, Section 508, and ADA compliance
- Full keyboard shortcuts (Arrow Down/Up, Enter, Tab, Escape)
- ARIA attributes:
aria-selected,aria-activedescendent,aria-owns - Localize
noRecordsTemplatewithL10n.load() - RTL support with
enableRtl
📄 API Reference
Read: references/mention-api.md
- Complete properties reference with types, defaults, and descriptions
- All methods:
addItem,disableItem,getDataByValue,getItems,hidePopup,showPopup,search,destroy - All events:
dataBound,actionFailureTemplate
---
Quick Start Example
// app.component.ts (Angular 21 Standalone)
import { Component } from '@angular/core';
import { MentionModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
selector: 'app-root',
standalone: true,
imports: [MentionModule],
template: `
<label style="font-size: 15px; font-weight: 600;">Comments</label>
<div id="mentionElement"
placeholder="Type @ and tag a user"
style="min-height: 100px; border: 1px solid #D7D7D7; border-radius: 4px; padding: 8px;">
</div>
<ejs-mention [dataSource]="userData" [target]="mentionTarget"></ejs-mention>
`
})
export class AppComponent {
public userData: string[] = ['Selma Rose', 'Garth', 'Robert', 'William', 'Joseph'];
public mentionTarget: string = '#mentionElement';
}Install the package:
⚠️ Security note: Pin the package to a specific version to prevent unintended upgrades
to potentially compromised releases. Verify the installed version against your lockfile
(package-lock.json/yarn.lock) after installation.
ng add @syncfusion/ej2-angular-dropdowns@<version>Add CSS (`styles.css`):
⚠️ Security note: These imports are resolved from node_modules at build time.Ensure the installed Syncfusion packages match your pinned versions in package-lock.jsonor yarn.lock before building. Do not source these files from a CDN withoutSubresource Integrity (SRI) hashes.
@import '../node_modules/@syncfusion/ej2-base/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-lists/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-angular-dropdowns/styles/material3.css';---
Common Patterns
Pattern 1: Object Data with Field Mapping
public userData: { [key: string]: Object }[] = [
{ Name: 'Selma Rose', EmailId: 'selma@gmail.com' },
{ Name: 'Maria', EmailId: 'maria@gmail.com' },
{ Name: 'Robert', EmailId: 'robert@gmail.com' }
];
public fields: Object = { text: 'Name' };
public mentionTarget: string = '#mentionElement';<ejs-mention [dataSource]="userData" [fields]="fields" [target]="mentionTarget"></ejs-mention>Pattern 2: Custom Trigger Character with showMentionChar
<ejs-mention
[dataSource]="userData"
[target]="mentionTarget"
[mentionChar]="'#'"
[showMentionChar]="true">
</ejs-mention>Pattern 3: Remote Data with Popup Width
🔒 Security policy — remote data is a restricted pattern.
Binding Mention to a remote endpoint requires a security review (see
Security & Trust Boundary) before use in production.
Remote data binding details and requirements are documented in
references/mention-data-binding.md.
No remote `DataManager` example is provided here by default.
Pattern 4: Allow Spaces in Mention Search
<ejs-mention
[dataSource]="userData"
[fields]="fields"
[allowSpaces]="true"
[target]="mentionTarget">
</ejs-mention>---
Key Properties Quick Reference
| Property | Type | Default | Purpose |
|---|---|---|---|
target | HTMLElement \ | string | — |
dataSource | Array \ | DataManager | [] |
fields | FieldSettingsModel | { text: null, value: null } | Map data columns to component |
mentionChar | string | '@' | Character that triggers the suggestion popup |
showMentionChar | boolean | false | Show trigger character with inserted text |
suffixText | string | null | Text appended after the selected item |
filterType | FilterType | 'Contains' | How suggestions are matched |
minLength | number | 0 | Minimum chars to trigger filtering |
allowSpaces | boolean | false | Allow spaces in mid-mention search |
suggestionCount | number | 25 | Max number of suggestions shown |
debounceDelay | number | 300 | Delay (ms) before filtering fires |
sortOrder | SortOrder | 'None' | Sort suggestions order |
popupHeight | string \ | number | '300px' |
popupWidth | string \ | number | 'auto' |
highlight | boolean | false | Highlight matched characters |
ignoreCase | boolean | true | Case-insensitive search |
ignoreAccent | boolean | — | Ignore diacritics in search |
requireLeadingSpace | boolean | true | Require space before trigger character |
cssClass | string | null | Custom CSS class(es) on the component |
locale | string | 'en-US' | Localization culture |
enableRtl | boolean | false | Right-to-left rendering |
enablePersistence | boolean | false | Persist state between reloads |
zIndex | number | 1000 | Popup z-index |
---
Workflow Decision Tree
Need to implement Mention / @mention tagging?
│
├─ What's your data source?
│ ├─ Local strings/array → See Data Binding: "Array of simple data"
│ ├─ Local objects → See Data Binding: "Array of JSON data" + fields mapping
│ └─ Remote API → See Data Binding: "Binding remote data"
│
├─ Custom trigger character (not @)?
│ └─ YES → [mentionChar]="'#'" (or any single char)
│
├─ Show trigger char in inserted text?
│ └─ YES → [showMentionChar]="true"
│
├─ Multi-word names (e.g., "John Doe")?
│ └─ YES → [allowSpaces]="true"
│
├─ Custom item layout in popup?
│ └─ YES → See Templates: itemTemplate / displayTemplate
│
├─ Need sorted suggestions?
│ └─ YES → See Sorting & Disabled Items: sortOrder
│
├─ Some items should not be selectable?
│ └─ YES → See Sorting & Disabled Items: fields.disabled / disableItem
│
├─ Filtering behavior?
│ ├─ By default (Contains) → No extra config
│ ├─ StartsWith / EndsWith → filterType="StartsWith"
│ └─ Minimum typed chars → [minLength]="3"
│
└─ Need accessibility or localization?
└─ YES → See Accessibility & Localization referenceMultiSelect
A multi-value selection dropdown (ejs-multiselect) supporting four visual modes (Default/Box/Delimiter/CheckBox), rich filtering, templates, grouping, remote data, virtualization, and full Angular form integration.
Component Overview
| Mode | Behavior | Use When |
|---|---|---|
Default | Selected items shown as chips in input | Standard multi-select |
Box | Same as Default, explicit box display | Visual clarity needed |
Delimiter | Selected items as comma-separated text | Space-constrained layouts |
CheckBox | Popup shows checkboxes per item | Bulk selection workflows |
Documentation Navigation Guide
Getting Started
📄 Read: references/multiselect-getting-started.md
- Installation and package setup (
ng add) - CSS imports and theme configuration
- Basic
<ejs-multiselect>in standalone Angular component - Popup height/width configuration
- Angular version notes (standalone default in Angular 19+)
Data Binding & Value Binding
📄 Read: references/multiselect-data-binding.md
- Local arrays (strings, numbers, objects)
fieldsmapping:text,value,groupBy,iconCss,disabled- Remote data with DataManager (OData, Web API)
- Pre-selecting values programmatically
- Object binding with
allowObjectBinding
Selection Modes, Chips & Item Control
📄 Read: references/multiselect-selection-modes.md
modeproperty: Default / Box / Delimiter / CheckBox- CheckBox mode:
CheckBoxSelection,showSelectAll,maximumSelectionLength - Chip customization via
taggingevent - Custom values with
allowCustomValue - Disabling specific items:
fields.disabled,disableItem() addTagOnBlurandchangeOnBlurbehaviors
Filtering
📄 Read: references/multiselect-filtering.md
- Enabling
allowFiltering+filteringevent +updateData() filterType:startsWith,contains,endsWith- Minimum character threshold before query fires
- Remote filtering with DataManager
- Case-insensitive matching
Templates
📄 Read: references/multiselect-templates.md
itemTemplate— custom list item rendering withng-templatevalueTemplate— customize chip/selected value displaygroupTemplate— custom group header contentheaderTemplate/footerTemplate— popup top/bottomnoRecordsTemplate/actionFailureTemplate
Grouping & Cascading
📄 Read: references/multiselect-grouping-and-items.md
fields.groupBy— organize items into categories- Fixed vs inline group headers
enableGroupCheckBoxfor group-level Select All- Cascading MultiSelect: parent
changeevent → filter child data - Country → State → City cascade pattern
Form Integration
📄 Read: references/multiselect-form-support.md
- Template-driven forms:
FormsModule,ngModel, two-way binding - Reactive forms:
ReactiveFormsModule,FormGroup,FormControl formControlNameusage and validation- Required field and custom validator patterns
Advanced Features
📄 Read: references/multiselect-advanced-features.md
- Virtualization for large datasets (
enableVirtualization) - Popup resize (
allowResize, resize events) - Icons in list items (
iconCssfield) - Localization (
L10n.load(), locale key overrides) - Accessibility: WAI-ARIA, keyboard navigation, WCAG 2.2
- RTL support
API Reference
📄 Read: references/multiselect-api.md
- Complete list of all properties with types and defaults
- All public methods with signatures, parameters, and return types
- All events with argument types and usage examples
- Module injection notes (
CheckBoxSelectionService)
Quick Start
⚠️ Security note: Pin the package to a specific version to prevent unintended upgrades
to potentially compromised releases. Verify the installed version against your lockfile
(package-lock.json/yarn.lock) after installation.
ng add @syncfusion/ej2-angular-dropdowns@<version>// app.component.ts — Standalone Angular 19+
import { Component } from '@angular/core';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
standalone: true,
imports: [MultiSelectModule],
selector: 'app-root',
template: `
<ejs-multiselect
[dataSource]="skills"
[fields]="fields"
placeholder="Select skills"
[(value)]="selectedSkills"
(change)="onChange($event)">
</ejs-multiselect>
`
})
export class AppComponent {
public skills = [
{ id: 1, name: 'Angular' },
{ id: 2, name: 'React' },
{ id: 3, name: 'TypeScript' },
{ id: 4, name: 'Node.js' },
];
public fields = { text: 'name', value: 'id' };
public selectedSkills: number[] = [1, 3]; // pre-select Angular & TypeScript
onChange(args: any): void {
this.selectedSkills = args.value;
}
}⚠️ Security note: These imports are resolved from node_modules at build time.Ensure the installed Syncfusion packages match your pinned versions in package-lock.jsonor yarn.lock before building. Do not source these files from a CDN withoutSubresource Integrity (SRI) hashes.
/* styles.css */
@import '@syncfusion/ej2-base/styles/material3.css';
@import '@syncfusion/ej2-buttons/styles/material3.css';
@import '@syncfusion/ej2-inputs/styles/material3.css';
@import '@syncfusion/ej2-lists/styles/material3.css';
@import '@syncfusion/ej2-popups/styles/material3.css';
@import '@syncfusion/ej2-dropdowns/styles/material3.css';
@import '@syncfusion/ej2-angular-dropdowns/styles/material3.css';Common Patterns
Checkbox Mode with Select All
import { MultiSelectModule, CheckBoxSelectionService } from '@syncfusion/ej2-angular-dropdowns';
@Component({
standalone: true,
imports: [MultiSelectModule],
providers: [CheckBoxSelectionService],
template: `
<ejs-multiselect
[dataSource]="items"
mode="CheckBox"
[showSelectAll]="true"
selectAllText="Select All"
unSelectAllText="Unselect All"
[maximumSelectionLength]="5">
</ejs-multiselect>
`
})Filtering with Remote Data
🔒 Security policy — remote data is a restricted pattern.
Binding MultiSelect to a remote endpoint requires a security review (see
Security & Trust Boundary) before use in production.
Remote filtering details and requirements are documented in
references/multiselect-filtering.md.
No remote `DataManager` example is provided here by default.
Reactive Form Integration
import { ReactiveFormsModule, FormControl } from '@angular/forms';
// In component:
public skillsControl = new FormControl([1, 3]); // pre-selected IDs
// In template:
// <ejs-multiselect [formControl]="skillsControl" [dataSource]="skills" [fields]="fields">
// </ejs-multiselect>Key Props
| Property | Type | Purpose |
|---|---|---|
dataSource | `any[] \ | DataManager` |
fields | FieldSettingsModel | Maps text, value, groupBy, disabled, iconCss |
value | any[] | Currently selected values (use [(value)] for two-way) |
mode | string | Default, Box, Delimiter, CheckBox |
allowFiltering | boolean | Enables search within the dropdown |
filterType | string | startsWith, contains, endsWith |
showSelectAll | boolean | Shows Select All in CheckBox mode |
maximumSelectionLength | number | Caps the number of selectable items |
allowCustomValue | boolean | Lets users add values not in the list |
enableVirtualization | boolean | Optimizes rendering for large lists |
popupHeight / popupWidth | string | Constrains popup dimensions |
allowResize | boolean | Lets users drag-resize the popup |
placeholder | string | Input hint text |
MultiColumn ComboBox
The MultiColumn ComboBox (ejs-multicolumncombobox) is a dropdown component that displays data in a multi-column grid-like popup. It supports column configuration, data binding (local/remote), filtering, sorting, grouping, templates, virtualization, events, and accessibility.
Navigation Guide
Getting Started
📄 Read: references/getting-started.md
- Installation and package setup (
ng add @syncfusion/ej2-angular-multicolumn-combobox@<version>)
⚠️ Security note: Pin the package to a specific version to prevent unintended upgrades
to potentially compromised releases. Verify the installed version against your lockfile
(package-lock.json/yarn.lock) after installation.
- CSS/theme imports for Material and other themes
- Basic standalone component usage with
<ejs-multicolumncombobox> - Binding
dataSourceandfieldsproperties - Configuring
<e-columns>and<e-column>child elements - Popup height and width configuration (
popupHeight,popupWidth)
Columns Configuration
📄 Read: references/columns.md
- Defining columns with
field,header,width - Setting text alignment with
textAlign - Using column
templatewithng-template - Displaying boolean values as checkboxes with
displayAsCheckBox - Applying custom CSS attributes via
customAttributes - Custom column headers with
headerTemplate - Formatting values with
format
Data Binding
📄 Read: references/data-binding.md
- Binding local object arrays via
dataSource - Remote data binding (restricted — requires security review; see Security & Trust Boundary)
- Mapping
fields:text,value, andgroupBy - Using the
queryproperty to filter/limit remote results
Items and Display Configuration
📄 Read: references/items.md
- Setting pre-selected text with
textproperty - Setting pre-selected value with
valueproperty - Setting selected item by index with
indexproperty - Placeholder text with
placeholder - Float label behavior with
floatLabelType(Never/Always/Auto) - Adding HTML attributes via
htmlAttributes - Setting component width with
width - Configuring popup dimensions (
popupWidth,popupHeight) - Show/hide clear button with
showClearButton - Applying custom CSS class with
cssClass - Disabled state with
disabled - Read-only mode with
readonly - Configuring grid settings (
gridSettings:gridLines,rowHeight,enableAltRow)
Filtering
📄 Read: references/filtering.md
- Enable/disable filtering with
allowFiltering - Changing filter type with
filterType(StartsWith/EndsWith/Contains)
Sorting
📄 Read: references/sorting.md
- Enable/disable sorting with
allowSorting - Setting initial sort order with
sortOrder(None/Ascending/Descending) - Sorting single vs. multiple columns with
sortType
Grouping
📄 Read: references/grouping.md
- Grouping items using the
groupByfield infieldsproperty
Templates
📄 Read: references/templates.md
- Customizing row items with
itemTemplate - Custom column headers with
headerTemplate - Group headers with
groupTemplate - Footer content with
footerTemplate - No-records placeholder with
noRecordsTemplate - Remote failure display with
actionFailureTemplate
Events
📄 Read: references/events.md
actionBegin,actionComplete,actionFailure— data lifecycle eventsselect— item selection eventchange— value change eventfiltering— text input filtering eventopen/close— popup state eventscreated— component rendered event
Virtualization
📄 Read: references/virtualization.md
- Enabling virtual scrolling with
enableVirtualization - Virtual scrolling with local and remote large datasets
Accessibility and Localization
📄 Read: references/accessibility.md
- WCAG 2.2, Section 508 compliance
- WAI-ARIA attributes used by the component
- Keyboard navigation shortcuts
- RTL support with
enableRtl - Localization of
noRecordsTemplatetext usingL10n
API Reference
📄 Read: references/api.md
- Complete list of properties, methods, and events
ColumnModelinterface propertiesGridSettingsModelinterface- Methods:
showPopup,hidePopup,focusIn,focusOut,getDataByValue,getItems,addItems
Quick Start
import { Component } from '@angular/core';
import { MultiColumnComboBoxModule } from '@syncfusion/ej2-angular-multicolumn-combobox';
@Component({
imports: [MultiColumnComboBoxModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-multicolumncombobox
id='multicolumn'
[dataSource]='empData'
[fields]='fields'
[placeholder]='waterMark'>
<e-columns>
<e-column field='EmpID' header='Employee ID' width='100'></e-column>
<e-column field='Name' header='Name' width='90'></e-column>
<e-column field='Designation' header='Designation' width='100'></e-column>
<e-column field='Country' header='Country' width='90'></e-column>
</e-columns>
</ejs-multicolumncombobox>`
})
export class AppComponent {
public empData: Object[] = [
{ EmpID: 1001, Name: 'Andrew Fuller', Designation: 'Team Lead', Country: 'England' },
{ EmpID: 1002, Name: 'Robert', Designation: 'Developer', Country: 'USA' },
{ EmpID: 1003, Name: 'Michael', Designation: 'HR', Country: 'Russia' }
];
public fields: Object = { text: 'Name', value: 'EmpID' };
public waterMark: string = 'Select an employee';
}Common Patterns
Remote data with DataManager
When data comes from an API, use DataManager → Read references/data-binding.md
Large datasets (150+ rows)
Enable enableVirtualization to avoid performance issues → Read references/virtualization.md
Rich row display
Use column template with ng-template for images, badges, or custom HTML → Read references/columns.md
Grouped dropdown
Set groupBy in fields to categorize items → Read references/grouping.md
Programmatic open/close
Use showPopup() / hidePopup() methods → Read references/api.md
Accessibility & Localization in Angular AutoComplete
Table of Contents
- Accessibility Standards Compliance
- WAI-ARIA Attributes
- Keyboard Navigation
- Focus Management
- Localization with L10n
- RTL Support
---
Accessibility Standards Compliance
The AutoComplete component follows established accessibility guidelines:
| Accessibility Criteria | Compliance |
|---|---|
| WCAG 2.2 Support | Partial |
| Section 508 Support | Partial |
| Screen Reader Support | Full |
| Right-To-Left Support | Full |
| Color Contrast | Full |
| Mobile Device Support | Full |
| Keyboard Navigation Support | Full |
| Accessibility Checker Validation | Full |
| Axe-core Accessibility Validation | Full |
---
WAI-ARIA Attributes
The AutoComplete uses the combobox ARIA role for the input and option role for each suggestion item.
| ARIA Attribute | Purpose |
|---|---|
aria-haspopup | Indicates the input has a suggestion popup |
aria-expanded | Indicates whether the popup is open |
aria-selected | Indicates the currently selected option |
aria-readonly | Indicates read-only state |
aria-disabled | Indicates disabled state |
aria-activedescendant | Points to the ID of the active suggestion item |
aria-owns | Links the input to its popup list element |
aria-autocomplete | Set to 'both' — inline completion and list |
These attributes are managed automatically by the component — no manual configuration is needed.
---
Keyboard Navigation
| Key | Action |
|---|---|
Arrow Down | Opens popup if closed; moves to next item if open |
Arrow Up | Opens popup if closed; moves to previous item if open |
Page Down | Scrolls to next page, selects first item |
Page Up | Scrolls to previous page, selects first item |
Enter | Selects focused item and sets it as the AutoComplete value |
Tab | Closes popup and moves focus to next tab-indexed element |
Shift + Tab | Closes popup and moves focus to previous tab-indexed element |
Alt + Down | Opens the popup |
Alt + Up | Toggles the popup open/closed |
Esc | Closes popup and removes selection |
Home | Moves cursor to beginning of input text |
End | Moves cursor to end of input text |
---
Focus Management
Use the focusIn() and focusOut() methods to control focus programmatically.
The following example uses Alt + T keyboard shortcut to focus the AutoComplete:
import { Component, HostListener, ViewChild } from '@angular/core';
import { AutoCompleteModule, AutoCompleteComponent } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<p>Press <kbd>Alt+T</kbd> to focus the AutoComplete</p>
<ejs-autocomplete
id="atcelement"
#samples
[dataSource]="sportsData"
[fields]="fields"
placeholder="Find a game">
</ejs-autocomplete>
`
})
export class AppComponent {
@ViewChild('samples') public sports!: AutoCompleteComponent;
public sportsData: { [key: string]: Object }[] = [
{ Id: 'Game1', Game: 'Badminton' },
{ Id: 'Game2', Game: 'Basketball' },
{ Id: 'Game3', Game: 'Cricket' },
{ Id: 'Game4', Game: 'Football' },
{ Id: 'Game5', Game: 'Golf' },
{ Id: 'Game6', Game: 'Hockey' },
{ Id: 'Game7', Game: 'Rugby' },
{ Id: 'Game8', Game: 'Snooker' },
{ Id: 'Game9', Game: 'Tennis' }
];
public fields: Object = { value: 'Game' };
@HostListener('document:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent): void {
if (event.altKey && event.keyCode === 84 /* t */) {
this.sports.focusIn();
}
}
}---
Localization with L10n
Use the L10n class from @syncfusion/ej2-base to localize static text strings in the AutoComplete.
Localizable strings:
| Locale Key | Default (en-US) | Description |
|---|---|---|
noRecordsTemplate | No Records Found | Shown when no suggestions match |
actionFailureTemplate | The Request Failed | Shown when remote request fails |
Example — French (fr-BE) localization:
import { Component, OnInit } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
import { DataManager, ODataV4Adaptor, Query } from '@syncfusion/ej2-data';
import { L10n } from '@syncfusion/ej2-base';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="data"
[query]="query"
[fields]="fields"
[locale]="locale"
placeholder="Trouver un client">
</ejs-autocomplete>
`
})
export class AppComponent implements OnInit {
public data: DataManager = new DataManager({
url: 'url',
adaptor: new ODataV4Adaptor,
crossDomain: true
});
public fields: Object = { value: 'ContactName' };
public query: Query = new Query().select(['ContactName', 'CustomerID']).take(0);
public locale: string = 'fr-BE';
ngOnInit(): void {
L10n.load({
'fr-BE': {
'dropdowns': {
'noRecordsTemplate': 'Aucun enregistrement trouvé',
'actionFailureTemplate': "Modèle d'échec d'action"
}
}
});
}
}Steps: 1. Import L10n from @syncfusion/ej2-base 2. Call L10n.load({ ... }) in ngOnInit (or before component render) 3. Set [locale]="'fr-BE'" on the component
---
RTL Support
Enable right-to-left layout for Arabic, Hebrew, Urdu, and other RTL languages:
<ejs-autocomplete
[dataSource]="data"
[enableRtl]="true"
placeholder="ابحث عن لعبة">
</ejs-autocomplete>RTL affects:
- Input text direction
- Popup alignment and scroll direction
- Icon positions
Advanced Patterns & How-To in Angular AutoComplete
Table of Contents
- Autofill While Filtering
- Highlight Searched Characters
- Custom Filtering by Multiple Fields
- Icon Support in List Items
- Suggestion List on Focus from Local Storage
- Programmatic Popup Control
- Add Items Dynamically
- Get Data by Value
---
Autofill While Filtering
Enable autofill to automatically complete the input with the first matching suggestion. Works best with filterType="StartsWith":
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="searchData"
[fields]="fields"
[autofill]="true"
placeholder="Find a country">
</ejs-autocomplete>
`
})
export class AppComponent {
public searchData: { [key: string]: Object }[] = [
{ Name: 'Australia', Code: 'AU' },
{ Name: 'Bermuda', Code: 'BM' },
{ Name: 'Canada', Code: 'CA' },
{ Name: 'Cameroon', Code: 'CM' },
{ Name: 'Denmark', Code: 'DK' },
{ Name: 'France', Code: 'FR' },
{ Name: 'Finland', Code: 'FI' },
{ Name: 'Germany', Code: 'DE' },
{ Name: 'India', Code: 'IN' },
{ Name: 'United Kingdom', Code: 'GB' },
{ Name: 'United States', Code: 'US' }
];
public fields: Object = { value: 'Name' };
}Behavior: If the user types Can, the input shows Canada with ada highlighted as the autocompleted portion. If no match is found, no completion is shown.
---
Highlight Searched Characters
Enable highlight to visually emphasize matched characters in the suggestion list using the .e-highlight CSS class:
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="searchData"
[fields]="fields"
[highlight]="true"
placeholder="Find a country">
</ejs-autocomplete>
`,
styles: [`
/* Custom highlight styling */
::ng-deep .e-highlight {
font-weight: 700;
color: #1565c0;
}
`]
})
export class AppComponent {
public searchData: { [key: string]: Object }[] = [
{ Name: 'Australia', Code: 'AU' },
{ Name: 'Bermuda', Code: 'BM' },
{ Name: 'Canada', Code: 'CA' },
{ Name: 'Denmark', Code: 'DK' },
{ Name: 'France', Code: 'FR' }
];
public fields: Object = { value: 'Name' };
}---
Custom Filtering by Multiple Fields
Use the filtering event with Predicate to filter on more than one data field simultaneously:
import { Component } from '@angular/core';
import { AutoCompleteModule, FilteringEventArgs } from '@syncfusion/ej2-angular-dropdowns';
import { Query, Predicate } from '@syncfusion/ej2-data';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="ddlelement"
[dataSource]="searchData"
[fields]="fields"
[itemTemplate]="itemTemplate"
[query]="query"
(filtering)="onFiltering($event)"
placeholder="Search by name or code">
</ejs-autocomplete>
`
})
export class AppComponent {
public searchData: { [key: string]: Object }[] = [
{ Name: 'Australia', Code: 'AU' },
{ Name: 'Bermuda', Code: 'BM' },
{ Name: 'Canada', Code: 'CA' },
{ Name: 'Cameroon', Code: 'CM' },
{ Name: 'Denmark', Code: 'DK' },
{ Name: 'France', Code: 'FR' },
{ Name: 'Finland', Code: 'FI' },
{ Name: 'Germany', Code: 'DE' },
{ Name: 'United Kingdom',Code: 'GB' },
{ Name: 'United States', Code: 'US' }
];
public fields: Object = { value: 'Code', text: 'Name' };
public itemTemplate: string = '<span><span class="name">${Name}</span> - <span class="code">${Code}</span></span>';
public query: Query = new Query();
public onFiltering(e: FilteringEventArgs): void {
// Prevent built-in filtering
e.preventDefaultAction = true;
// Build OR predicate: matches if Name OR Code contains typed text
let predicate = new Predicate('Name', 'contains', e.text);
predicate = predicate.or('Code', 'contains', e.text);
let query = new Query();
query = (e.text !== '') ? query.where(predicate) : query;
// Update the popup with filtered results
e.updateData(this.searchData, query);
}
}Use case: Let users type either a country name ("Canada") or its code ("CA") to find the same item.
---
Icon Support in List Items
Map a CSS class column using fields.iconCss to display icons alongside suggestion text:
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="sortFormatData"
[fields]="fields"
placeholder="Find a format">
</ejs-autocomplete>
`,
styles: [`
/* Define icon classes (replace with your icon font or SVG) */
.asc-sort::before { content: '↑'; margin-right: 6px; }
.dsc-sort::before { content: '↓'; margin-right: 6px; }
.filter::before { content: '⊿'; margin-right: 6px; }
.clear::before { content: '✕'; margin-right: 6px; }
`]
})
export class AppComponent {
public sortFormatData: { [key: string]: Object }[] = [
{ Class: 'asc-sort', Type: 'Sort A to Z', Id: '1' },
{ Class: 'dsc-sort', Type: 'Sort Z to A', Id: '2' },
{ Class: 'filter', Type: 'Filter', Id: '3' },
{ Class: 'clear', Type: 'Clear', Id: '4' }
];
// 'iconCss' creates a <span> with the mapped class name before each item
public fields: Object = { value: 'Type', iconCss: 'Class' };
}The iconCss field adds a <span> element with the mapped class to each list item — use any icon font (Font Awesome, Material Icons, etc.) or custom CSS.
---
Suggestion List on Focus from Local Storage
Show previously searched/selected values as suggestions when the AutoComplete is focused (browser history-style autocomplete):
import { Component, ViewChild } from '@angular/core';
import { AutoCompleteModule, AutoCompleteComponent, FilteringEventArgs } from '@syncfusion/ej2-angular-dropdowns';
import { Query } from '@syncfusion/ej2-data';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="country"
#local
[dataSource]="countries"
[fields]="localFields"
(change)="onChange()"
(filtering)="onFiltering($event)"
(focus)="onFocus()">
</ejs-autocomplete>
`
})
export class AppComponent {
@ViewChild('local') public localObj!: AutoCompleteComponent;
public suggestList: string[] = [];
public countries: { [key: string]: Object }[] = [
{ Name: 'Australia', Code: 'AU' },
{ Name: 'Bermuda', Code: 'BM' },
{ Name: 'Canada', Code: 'CA' },
{ Name: 'Cameroon', Code: 'CM' },
{ Name: 'Denmark', Code: 'DK' },
{ Name: 'France', Code: 'FR' },
{ Name: 'Finland', Code: 'FI' }
];
public localFields: Object = { value: 'Name' };
// When a value is selected or typed, store it in local storage
onChange(): void {
localStorage.setItem('value', this.localObj.value as string);
const stored = localStorage.getItem('value');
if (stored && stored !== 'null') {
this.suggestList.push(stored);
// Remove duplicates
this.suggestList = [...new Set(this.suggestList)];
}
}
// On focus, show previously stored values as suggestions
onFocus(): void {
if (this.suggestList.length > 0) {
(this.localObj.dataSource as any) = this.suggestList;
this.localObj.dataBind();
// Trigger opening the popup
const keyEventArgs: any = {
preventDefault: (): void => {},
action: 'down',
keyCode: 40,
type: null
};
(this.localObj as any).onFilterUp(keyEventArgs);
(this.localObj as any).popupObj.element.classList.add('e-suggestion');
}
}
// During filtering, use the main dataset and remove suggestion styling
onFiltering(e: FilteringEventArgs): void {
let query = new Query();
query = (e.text !== '') ? query.where('Name', 'startswith', e.text, true) : query;
e.updateData(this.countries, query);
(this.localObj as any).popupObj.element.classList.remove('e-suggestion');
}
}---
Programmatic Popup Control
Use showPopup() and hidePopup() methods to control the suggestion popup from code:
import { Component, ViewChild } from '@angular/core';
import { AutoCompleteModule, AutoCompleteComponent } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete #auto [dataSource]="data" placeholder="Find a game">
</ejs-autocomplete>
<button (click)="openPopup()">Open Popup</button>
<button (click)="closePopup()">Close Popup</button>
`
})
export class AppComponent {
@ViewChild('auto') public autoObj!: AutoCompleteComponent;
public data: string[] = ['Badminton', 'Cricket', 'Football', 'Golf', 'Hockey'];
openPopup(): void {
this.autoObj.showPopup();
}
closePopup(): void {
this.autoObj.hidePopup();
}
}---
Add Items Dynamically
Use addItem() to insert new items into the suggestion list at runtime:
import { Component, ViewChild } from '@angular/core';
import { AutoCompleteModule, AutoCompleteComponent } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete #auto [dataSource]="data" placeholder="Find a game">
</ejs-autocomplete>
<button (click)="addNewItem()">Add "Volleyball"</button>
`
})
export class AppComponent {
@ViewChild('auto') public autoObj!: AutoCompleteComponent;
public data: string[] = ['Badminton', 'Cricket', 'Football'];
addNewItem(): void {
// Append at end (no index) or specify position
this.autoObj.addItem('Volleyball' as any);
}
}---
Get Data by Value
Use getDataByValue() to retrieve the full data object for a given value string:
import { Component, ViewChild } from '@angular/core';
import { AutoCompleteModule, AutoCompleteComponent } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
#auto
[dataSource]="sportsData"
[fields]="fields"
placeholder="Find a game"
(select)="onSelect($event)">
</ejs-autocomplete>
<div *ngIf="selectedItem">
Selected ID: {{ selectedItem['Id'] }}
</div>
`
})
export class AppComponent {
@ViewChild('auto') public autoObj!: AutoCompleteComponent;
public selectedItem: { [key: string]: Object } | null = null;
public sportsData: { [key: string]: Object }[] = [
{ Id: 'Game1', Game: 'Badminton' },
{ Id: 'Game2', Game: 'Cricket' },
{ Id: 'Game3', Game: 'Football' }
];
public fields: Object = { value: 'Game' };
onSelect(e: any): void {
const data = this.autoObj.getDataByValue(e.value);
this.selectedItem = data as { [key: string]: Object };
}
}AutoComplete API Reference
Source: https://ej2.syncfusion.com/angular/documentation/api/auto-complete/index-default
Table of Contents
---
Properties
actionFailureTemplate
Type: any Default: 'Request failed'
Accepts a template string and assigns it to the popup list content when a remote data fetch request fails.
---
allowCustom
Type: boolean Default: true
Specifies whether the component allows user-defined values that do not exist in the data source.
---
allowObjectBinding
Type: boolean Default: false
When true, the value property holds the complete matched data object instead of just the value string.
// allowObjectBinding = true → value is the full object
public value = { id: 'id11', text: 'Item 11' };---
allowResize
Type: boolean Default: false
When true, a resize handle appears in the bottom-right corner of the popup, allowing users to resize its width and height. Resized dimensions are retained across sessions.
---
autofill
Type: boolean Default: false
When true, the first matched item is suggested inline in the input as the user types. If no match is found, nothing happens.
---
cssClass
Type: string Default: null
Sets CSS class(es) on the root element of the component for visual customization.
<ejs-autocomplete cssClass="my-custom-class"></ejs-autocomplete>---
dataSource
Type: { [key: string]: Object }[] | DataManager | string[] | number[] | boolean[] Default: []
Accepts list items via a local array or a remote DataManager instance.
---
debounceDelay
Type: number Default: 300
Delay in milliseconds applied before the filtering operation fires. Reduces remote API request frequency while the user is typing. Set to 0 to disable.
---
enablePersistence
Type: boolean Default: false
When true, persists the component's value state across page reloads using browser storage.
---
enableRtl
Type: boolean Default: false
When true, renders the component in right-to-left direction.
---
enableVirtualization
Type: boolean Default: false
When true, enables virtual scrolling for large datasets. Only a fixed number of DOM elements are created and recycled as the user scrolls. Requires injecting the VirtualScroll module.
import { AutoCompleteComponent, VirtualScroll } from '@syncfusion/ej2-angular-dropdowns';
AutoCompleteComponent.Inject(VirtualScroll);---
enabled
Type: boolean Default: true
When false, the component is disabled and user interactions are prevented.
---
fields
Type: FieldSettingsModel Default: { value: null, iconCss: null, groupBy: null }
Maps data source columns to the component:
| Sub-field | Description |
|---|---|
value | Column used as suggestion text and selected value |
text | Column used as display text (alternative to value) |
iconCss | Column containing CSS class names for icons |
groupBy | Column used to group items under category headers |
disabled | Column indicating item disabled state |
public fields = { value: 'Name', iconCss: 'Icon', groupBy: 'Category' };---
filterType
Type: FilterType Default: 'Contains'
Determines the matching strategy used when filtering:
| Value | Behavior |
|---|---|
'StartsWith' | Matches items beginning with typed text |
'EndsWith' | Matches items ending with typed text |
'Contains' | Matches items containing typed text |
---
floatLabelType
Type: FloatLabelType Default: 'Never'
Controls floating label behavior:
| Value | Behavior |
|---|---|
'Never' | Label never floats (stays as placeholder) |
'Always' | Label always floats above input |
'Auto' | Label floats after focusing or entering a value |
---
footerTemplate
Type: any Default: null
Template for custom content at the bottom of the popup list.
---
groupTemplate
Type: any Default: null
Template for customizing group header content. Applies to both inline and fixed group headers.
---
headerTemplate
Type: any Default: null
Template for custom static content at the top of the popup list.
---
highlight
Type: boolean Default: false
When true, matched characters in suggestion items are wrapped with the .e-highlight CSS class.
---
htmlAttributes
Type: { [key: string]: string } Default: {}
Allows additional HTML attributes (e.g., title, name, maxlength) to be set on the input element.
public htmlAttributes = { name: 'country', maxlength: '50', title: 'AutoComplete' };---
ignoreAccent
Type: boolean Default: —
When true, filtering ignores diacritic characters (accents). For example, aero matches Aeróbics.
---
ignoreCase
Type: boolean Default: true
When false, filtering is case-sensitive. By default (true), filtering is case-insensitive.
---
isDeviceFullScreen
Type: boolean Default: true
When true, the popup opens in full-screen mode on mobile devices. Set to false for consistent popup behavior across desktop and mobile.
---
itemTemplate
Type: any Default: null
Template for customizing each suggestion item's rendered content.
---
locale
Type: string Default: 'en-US'
Sets the culture/language for localizable strings (noRecordsTemplate, actionFailureTemplate). Use with L10n.load() from @syncfusion/ej2-base.
---
minLength
Type: number Default: 1
Minimum number of characters the user must type before filtering begins.
---
noRecordsTemplate
Type: any Default: 'No records found'
Template displayed in the popup when no suggestions match the typed text.
---
placeholder
Type: string Default: null
Short hint text displayed inside the input when no value is entered.
---
popupHeight
Type: string | number Default: '300px'
Controls the height of the suggestion popup list.
---
popupWidth
Type: string | number Default: '100%'
Controls the width of the suggestion popup list. Defaults to match the input width.
---
query
Type: Query Default: null
Accepts an external Query instance for filtering and shaping remote data requests.
---
readonly
Type: boolean Default: false
When true, user interaction (typing) is prevented, but the current value is still displayed.
---
showClearButton
Type: boolean Default: true
When true, shows a clear (✕) button. Clicking it resets value, text, and index to null.
---
showPopupButton
Type: boolean Default: false
When true, shows a button to toggle the popup open/closed (like a dropdown).
---
sortOrder
Type: SortOrder Default: null
Sorts the suggestion list:
| Value | Behavior |
|---|---|
'None' | No sorting (default) |
'Ascending' | A → Z |
'Descending' | Z → A |
---
suggestionCount
Type: number Default: 20
Maximum number of items shown in the suggestion popup.
---
value
Type: number | string | boolean | object | null Default: null
Gets or sets the currently selected/typed value. Supports two-way binding with [(value)].
---
width
Type: string | number Default: '100%'
Sets the width of the component input element.
---
zIndex
Type: number Default: 1000
Sets the z-index of the popup element (controls stacking order).
---
Methods
addItem
Adds a new item to the suggestion list. Appends to the end by default, or inserts at the specified index.
Parameters:
| Parameter | Type | Description |
|---|---|---|
items | `{ [key: string]: Object }[] \ | string \ |
itemIndex (optional) | number | Index at which to insert the new item |
Returns: void
this.autoObj.addItem('Volleyball' as any);
this.autoObj.addItem({ Id: 'G10', Game: 'Volleyball' } as any, 2);---
clear
Clears the currently selected value from the component.
Returns: void
this.autoObj.clear();---
destroy
Removes the component from the DOM and detaches all event handlers, attributes, and classes.
Returns: void
---
disableItem
Disables a specific item in the popup list. Only one item at a time; iterate to disable multiple.
Parameters:
| Parameter | Type | Description |
|---|---|---|
item | `string \ | number \ |
Returns: void
this.autoObj.disableItem('On Hold'); // Disable by value
this.autoObj.disableItem(2); // Disable by index---
filter
Filters data from a given data source using a query.
Parameters:
| Parameter | Type | Description |
|---|---|---|
dataSource | `{ [key: string]: Object }[] \ | DataManager \ |
query (optional) | Query | Filter query |
fields (optional) | FieldSettingsModel | Fields mapping |
Returns: void
---
focusIn
Sets focus to the component.
Returns: void
this.autoObj.focusIn();---
focusOut
Moves focus away from the component.
Returns: void
---
getDataByValue
Returns the data object that matches the given value.
Parameters:
| Parameter | Type | Description |
|---|---|---|
value | `string \ | number \ |
Returns: { [key: string]: Object } | string | number | boolean
const item = this.autoObj.getDataByValue('Cricket');---
getItems
Returns all currently rendered list item elements in the popup.
Returns: Element[]
const count = this.autoObj.getItems().length;---
hidePopup
Closes the popup if it is open.
Parameters:
| Parameter | Type | Description |
|---|---|---|
e (optional) | `MouseEvent \ | KeyboardEvent \ |
Returns: void
---
hideSpinner
Hides the loading spinner.
Returns: void
---
showPopup
Opens the popup and shows suggestions matching the current input text.
Parameters:
| Parameter | Type | Description |
|---|---|---|
e (optional) | `MouseEvent \ | KeyboardEvent \ |
Returns: void
---
showSpinner
Shows the loading spinner.
Returns: void
---
Events
actionBegin
Type: EmitType<Object>
Fires before data is fetched from a remote server (before the request is sent).
<ejs-autocomplete (actionBegin)="onActionBegin($event)"></ejs-autocomplete>---
actionComplete
Type: EmitType<Object>
Fires after data is successfully fetched from a remote server.
---
actionFailure
Type: EmitType<Object>
Fires when the remote data fetch request fails.
---
beforeOpen
Type: EmitType<Object>
Fires before the popup opens (can be used to cancel the open or modify the popup).
---
blur
Type: EmitType<Object>
Fires when focus moves out of the component.
<ejs-autocomplete (blur)="onBlur($event)"></ejs-autocomplete>---
change
Type: EmitType<ChangeEventArgs>
Fires when the selected item changes or when the model value is modified by the user.
<ejs-autocomplete (change)="onChange($event)"></ejs-autocomplete>onChange(e: ChangeEventArgs): void {
console.log('New value:', e.value);
console.log('Previous value:', e.previousValue);
}---
close
Type: EmitType<PopupEventArgs>
Fires when the popup closes.
---
created
Type: EmitType<Object>
Fires when the component has been created and rendered.
---
customValueSpecifier
Type: EmitType<CustomValueSpecifierEventArgs>
Fires when a custom value (not in the data source) is entered and allowCustom is true.
---
dataBound
Type: EmitType<Object>
Fires after the data source is populated in the popup list.
---
destroyed
Type: EmitType<Object>
Fires when the component is destroyed.
---
filtering
Type: EmitType<FilteringEventArgs>
Fires each time the user types a character. Use this event to implement custom filtering logic.
<ejs-autocomplete (filtering)="onFiltering($event)"></ejs-autocomplete>onFiltering(e: FilteringEventArgs): void {
e.preventDefaultAction = true;
// Apply custom filter and call e.updateData(dataSource, query)
}---
focus
Type: EmitType<Object>
Fires when the component receives focus.
---
open
Type: EmitType<PopupEventArgs>
Fires when the popup opens.
---
resizeStart
Type: EmitType<Object>
Fires when the user starts resizing the popup (requires allowResize: true).
---
resizeStop
Type: EmitType<Object>
Fires when the user finishes resizing the popup.
---
resizing
Type: EmitType<Object>
Fires continuously while the popup is being resized. Provides live width/height updates.
---
select
Type: EmitType<SelectEventArgs>
Fires when a suggestion item is selected from the popup (via mouse, touch, or keyboard).
<ejs-autocomplete (select)="onSelect($event)"></ejs-autocomplete>onSelect(e: SelectEventArgs): void {
console.log('Selected item:', e.item);
console.log('Selected data:', e.itemData);
}Data Binding in Angular AutoComplete
Table of Contents
- Overview
- Fields Mapping
- Local Data: Array of Strings
- Local Data: Array of Objects
- Local Data: Array of Complex Objects
- Remote Data with DataManager
- Async Pipe with Observable
- Primitive Value Binding
- Object Value Binding (allowObjectBinding)
---
Overview
The AutoComplete binds data through the dataSource property. It accepts:
string[]/number[]/boolean[]— arrays of primitives{ [key: string]: Object }[]— arrays of plain objectsDataManager— for remote/OData data services
The fields property maps which columns from your data object to use for the suggestion value, icon, or grouping.
---
Fields Mapping
| Field | Type | Description |
|---|---|---|
value | string | Column used as the suggestion text and selected value |
groupBy | string | Column used to group list items under category headers |
iconCss | string | Column containing CSS class names for icons |
disabled | string | Column indicating whether an item is disabled |
Example — mapping a `Game` column as the value:
public fields: Object = { value: 'Game' };
public sportsData: { [key: string]: Object }[] = [
{ Id: 'Game1', Game: 'Badminton' },
{ Id: 'Game2', Game: 'Basketball' },
{ Id: 'Game3', Game: 'Cricket' }
];If fields is not mapped correctly for complex data, the selected item remains undefined.---
Local Data: Array of Strings
The simplest form — no fields mapping needed:
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="sportsData"
placeholder="Find a game">
</ejs-autocomplete>
`
})
export class AppComponent {
public sportsData: string[] = [
'Badminton', 'Basketball', 'Cricket', 'Football',
'Golf', 'Gymnastics', 'Hockey', 'Tennis'
];
}---
Local Data: Array of Objects
When your data has object structure, map the value field:
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="sportsData"
[fields]="fields"
placeholder="Find a game">
</ejs-autocomplete>
`
})
export class AppComponent {
public sportsData: { [key: string]: Object }[] = [
{ Id: 'Game1', Game: 'Badminton' },
{ Id: 'Game2', Game: 'Basketball' },
{ Id: 'Game3', Game: 'Cricket' },
{ Id: 'Game4', Game: 'Football' },
{ Id: 'Game5', Game: 'Golf' },
{ Id: 'Game6', Game: 'Hockey' },
{ Id: 'Game7', Game: 'Rugby' },
{ Id: 'Game8', Game: 'Snooker' }
];
// Map the 'Game' column as the suggestion value
public fields: Object = { value: 'Game' };
}---
Local Data: Array of Complex Objects
For nested object properties, use dot notation in the value field:
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="countriesData"
[fields]="fields"
placeholder="Find a country">
</ejs-autocomplete>
`
})
export class AppComponent {
public countriesData: { [key: string]: Object }[] = [
{ Country: { Name: 'Australia' }, Code: { Id: 'AU' } },
{ Country: { Name: 'Bermuda' }, Code: { Id: 'BM' } },
{ Country: { Name: 'Canada' }, Code: { Id: 'CA' } },
{ Country: { Name: 'Denmark' }, Code: { Id: 'DK' } },
{ Country: { Name: 'France' }, Code: { Id: 'FR' } },
{ Country: { Name: 'Germany' }, Code: { Id: 'DE' } },
{ Country: { Name: 'India' }, Code: { Id: 'IN' } },
{ Country: { Name: 'Japan' }, Code: { Id: 'JP' } }
];
// Dot notation for nested property
public fields: Object = { value: 'Country.Name' };
}---
Remote Data with DataManager
Use DataManager to fetch data from a remote service. The query property controls what data is fetched:
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
import { Query, DataManager, ODataV4Adaptor } from '@syncfusion/ej2-data';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="data"
[fields]="fields"
[query]="query"
[sortOrder]="sorting"
placeholder="Find a customer">
</ejs-autocomplete>
`
})
export class AppComponent {
public data: DataManager = new DataManager({
url: 'url',
adaptor: new ODataV4Adaptor,
crossDomain: true
});
public fields: Object = { value: 'ContactName' };
public query: Query = new Query().select(['ContactName']).take(6);
public sorting: string = 'Ascending';
}Supported DataManager adaptors: ODataAdaptor, ODataV4Adaptor, WebApiAdaptor, UrlAdaptor, JsonAdaptor
---
Bind data from an RxJS Observable using Angular's async pipe:
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { AsyncPipe } from '@angular/common';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule, AsyncPipe],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="customers"
[dataSource]="data | async"
[fields]="remoteFields"
placeholder="Select a customer">
</ejs-autocomplete>
`
})
export class AppComponent {
public data: Observable<any>;
public remoteFields: Object = { value: 'CustomerID' };
constructor(private http: HttpClient) {
this.data = this.http
.get<{ [key: string]: object }[]>(
''
)
.pipe(map((results: { [key: string]: any }) => results['value']));
}
}Requires HttpClientModule to be provided in the application.---
Primitive Value Binding
Use the value property to pre-select an item at initialization:
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
[dataSource]="records"
[fields]="fields"
[value]="value"
placeholder="e.g. Item 1">
</ejs-autocomplete>
`
})
export class AppComponent {
public records: string[] = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'];
public fields: object = { value: 'text' };
public value: string = 'Item 1'; // Pre-selected primitive value
}---
Object Value Binding (allowObjectBinding)
When allowObjectBinding is true, the value property holds the entire matched data object rather than just its value string:
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
[dataSource]="records"
[fields]="fields"
[allowObjectBinding]="true"
[value]="value"
placeholder="e.g. Item 1">
</ejs-autocomplete>
`
})
export class AppComponent {
public records: { [key: string]: Object }[] = [];
constructor() {
for (let i: number = 1; i <= 150; i++) {
this.records.push({ id: 'id' + i, text: `Item ${i}` });
}
}
public fields: object = { value: 'text' };
// Pre-select by full object when allowObjectBinding is true
public value: object = { id: 'id11', text: 'Item 11' };
}When to use `allowObjectBinding`: When you need to track the full selected object (not just its display string) — for example, to pass the selected item's id field to a backend service.
Feature Configuration in Angular AutoComplete
Table of Contents
- Autofill
- Highlight Matched Characters
- Disable Individual Items
- Disable Item Dynamically
- Disable Entire Component
- Read-Only Mode
- Resizable Popup
- Virtual Scrolling
- Virtual Scrolling with Grouping
- Customizing Items Count in Virtualization
- Show Popup Button
- Show/Hide Clear Button
- RTL Support
- Sort Order
- Popup Button Visibility
- CSS Customization
---
Autofill
When autofill is true, the AutoComplete automatically completes the input with the first matching suggestion as the user types. If no match is found, nothing happens.
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="searchData"
[fields]="fields"
[autofill]="true"
placeholder="Find a country">
</ejs-autocomplete>
`
})
export class AppComponent {
public searchData: { [key: string]: Object }[] = [
{ Name: 'Australia', Code: 'AU' },
{ Name: 'Bermuda', Code: 'BM' },
{ Name: 'Canada', Code: 'CA' },
{ Name: 'Denmark', Code: 'DK' },
{ Name: 'France', Code: 'FR' },
{ Name: 'Germany', Code: 'DE' }
];
public fields: Object = { value: 'Name' };
}Works best when combined with filterType="StartsWith".
---
Highlight Matched Characters
When highlight is true, typed characters are highlighted in the suggestion list using the .e-highlight CSS class:
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="searchData"
[fields]="fields"
[highlight]="true"
placeholder="Find a country">
</ejs-autocomplete>
`
})
export class AppComponent {
public searchData: { [key: string]: Object }[] = [
{ Name: 'Australia', Code: 'AU' },
{ Name: 'Bermuda', Code: 'BM' },
{ Name: 'Canada', Code: 'CA' },
{ Name: 'Denmark', Code: 'DK' }
];
public fields: Object = { value: 'Name' };
}Customize highlighted text styling:
.e-highlight {
font-weight: bold;
color: #007bff;
}---
Disable Individual Items
Map a disabled field in fields to disable specific items so they appear in the list but cannot be selected:
import { Component } from '@angular/core';
import { AutoCompleteModule, AutoCompleteComponent } from '@syncfusion/ej2-angular-dropdowns';
import { HostListener, ViewChild } from '@angular/core';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
#samples
[dataSource]="statusData"
[fields]="fields"
placeholder="Select Status">
</ejs-autocomplete>
`
})
export class AppComponent {
@ViewChild('samples') public status!: AutoCompleteComponent;
public statusData: { [key: string]: Object }[] = [
{ Status: 'Open', State: false },
{ Status: 'Waiting for Customer',State: false },
{ Status: 'On Hold', State: true }, // disabled
{ Status: 'Follow-up', State: false },
{ Status: 'Closed', State: true }, // disabled
{ Status: 'Solved', State: false },
{ Status: 'Feature Request', State: false }
];
// Map 'State' column as the disabled field
public fields: Object = { value: 'Status', disabled: 'State' };
@HostListener('document:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.altKey && event.keyCode === 84) {
this.status.focusIn(); // Focus with Alt+T
}
}
}---
Disable Item Dynamically
Use the disableItem method to disable a specific item programmatically at runtime:
| Parameter | Type | Description |
|---|---|---|
item | HTMLLIElement | The list element to disable |
item | `string \ | number \ |
itemIndex | number | Index of the item to disable |
// Disable by value
this.autoCompleteObj.disableItem('On Hold');
// Disable by index
this.autoCompleteObj.disableItem(2);- The
disabledstate is updated in thedataSource - If the currently selected item is disabled, the selection is cleared
---
Disable Entire Component
Set enabled to false to make the entire component non-interactive:
<ejs-autocomplete
[dataSource]="data"
[enabled]="false"
placeholder="Disabled">
</ejs-autocomplete>---
Read-Only Mode
Use readonly to prevent the user from typing but still display the current value:
<ejs-autocomplete
[dataSource]="data"
[readonly]="true"
value="Cricket">
</ejs-autocomplete>---
Resizable Popup
Set allowResize to true to show a resize handle in the bottom-right corner of the popup, allowing users to resize it:
import { Component, HostListener, ViewChild } from '@angular/core';
import { AutoCompleteModule, AutoCompleteComponent } from '@syncfusion/ej2-angular-dropdowns';
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
#samples
[dataSource]="statusData"
[fields]="fields"
[allowResize]="true"
placeholder="Select Status">
</ejs-autocomplete>
`
})
export class AppComponent {
@ViewChild('samples') public status!: AutoCompleteComponent;
public statusData: { [key: string]: Object }[] = [
{ Status: 'Open', State: false },
{ Status: 'On Hold', State: true },
{ Status: 'Follow-up', State: false },
{ Status: 'Closed', State: true },
{ Status: 'Solved', State: false },
{ Status: 'In Progress', State: false },
{ Status: 'Pending', State: true }
];
public fields: Object = { value: 'Status' };
}Resized dimensions are retained across sessions. Related events: resizeStart, resizing, resizeStop.
---
Virtual Scrolling
Enable enableVirtualization for large datasets. This creates a fixed pool of DOM elements and recycles them as the user scrolls, significantly reducing memory and rendering overhead:
import { Component } from '@angular/core';
import { AutoCompleteModule, AutoCompleteComponent, VirtualScroll } from '@syncfusion/ej2-angular-dropdowns';
// Inject the VirtualScroll module
AutoCompleteComponent.Inject(VirtualScroll);
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="records"
[fields]="fields"
[enableVirtualization]="true"
popupHeight="200px"
placeholder="e.g. Item 1">
</ejs-autocomplete>
`
})
export class AppComponent {
public records: { [key: string]: Object }[] = [];
public fields: object = { value: 'text' };
constructor() {
for (let i = 1; i <= 150; i++) {
this.records.push({ id: 'id' + i, text: `Item ${i}` });
}
}
}WhenenableVirtualizationis enabled,skipandtakefrom a user-providedQueryare ignored at initial state — they are internally calculated based on popup height.
---
Virtual Scrolling with Grouping
Virtual scrolling also supports grouping. For remote data, all data is fetched once for grouping, then virtualization works like local data:
import { Component } from '@angular/core';
import { AutoCompleteModule, AutoCompleteComponent, VirtualScroll } from '@syncfusion/ej2-angular-dropdowns';
AutoCompleteComponent.Inject(VirtualScroll);
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="atcelement"
[dataSource]="records"
[fields]="fields"
[enableVirtualization]="true"
popupHeight="200px"
placeholder="e.g. Item 1">
</ejs-autocomplete>
`
})
export class AppComponent {
public records: { [key: string]: Object }[] = [];
public fields: object = { groupBy: 'group', text: 'text', value: 'id' };
constructor() {
const groups = ['Group A', 'Group B', 'Group C', 'Group D'];
for (let i = 1; i <= 150; i++) {
const group = groups[Math.floor(Math.random() * 4)];
this.records.push({ id: 'id' + i, text: `Item ${i}`, group });
}
}
}---
Customizing Items Count in Virtualization
Use query.take() or the actionBegin event to control how many items are fetched per batch during virtual scroll:
import { Component } from '@angular/core';
import { AutoCompleteModule, AutoCompleteComponent, VirtualScroll } from '@syncfusion/ej2-angular-dropdowns';
import { Query } from '@syncfusion/ej2-data';
AutoCompleteComponent.Inject(VirtualScroll);
@Component({
imports: [AutoCompleteModule],
standalone: true,
selector: 'app-root',
template: `
<ejs-autocomplete
id="autocomplete-virtualization"
[dataSource]="records"
[fields]="fields"
[query]="query"
[enableVirtualization]="true"
popupHeight="200px"
(actionBegin)="onBegin($event)"
placeholder="e.g. Item 1">
</ejs-autocomplete>
`
})
export class AppComponent {
public records: { [key: string]: Object }[] = [];
public fields: object = { text: 'text', value: 'id' };
public query: Query = new Query().take(40);
constructor() {
for (let i = 1; i <= 150; i++) {
this.records.push({ id: 'id' + i, text: `Item ${i}` });
}
}
public onBegin(e: any): void {
e.query = new Query().take(45);
}
}If the user-provided take value is less than what's needed to fill the popup, it is ignored.---
Show Popup Button
Show a toggle button to open/close the suggestion list (similar to a dropdown):
<ejs-autocomplete [dataSource]="data" [showPopupButton]="true">
</ejs-autocomplete>Default: false
---
Show/Hide Clear Button
The clear button (✕) is shown by default and resets value, text, and index to null when clicked:
<!-- Hide the clear button -->
<ejs-autocomplete [dataSource]="data" [showClearButton]="false">
</ejs-autocomplete>Default: true
---
RTL Support
Enable right-to-left rendering for Arabic, Hebrew, and other RTL languages:
<ejs-autocomplete [dataSource]="data" [enableRtl]="true">
</ejs-autocomplete>---
Sort Order
Sort the displayed suggestions:
<!-- Ascending -->
<ejs-autocomplete [dataSource]="data" sortOrder="Ascending">
</ejs-autocomplete>
<!-- Descending -->
<ejs-autocomplete [dataSource]="data" sortOrder="Descending">
</ejs-autocomplete>Values: 'None' (default), 'Ascending', 'Descending'
---
CSS Customization
Override CSS variables or class selectors to adjust the visual appearance:
/* Input text */
.e-ddl.e-input-group.e-control-wrapper .e-input {
font-size: 16px;
color: #333;
background: #f9f9f9;
}
/* Placeholder text color */
.e-ddl.e-input-group input.e-input::placeholder {
color: #aaa;
}
/* Focus underline color */
.e-ddl.e-input-group.e-control-wrapper.e-input-focus::before,
.e-ddl.e-input-group.e-control-wrapper.e-input-focus::after {
background: #1976d2;
}
/* Hover / active list item background */
.e-dropdownbase .e-list-item.e-item-focus,
.e-dropdownbase .e-list-item.e-hover {
background-color: #e3f2fd;
color: #0d47a1;
}
/* Popup item appearance */
.e-dropdownbase .e-list-item {
min-height: 32px;
}Use the cssClass property to scope customizations to a specific component instance:
<ejs-autocomplete [dataSource]="data" cssClass="custom-autocomplete">
</ejs-autocomplete>.custom-autocomplete.e-ddl.e-input-group .e-input {
border-color: #4caf50;
}Form Support & Validation in Angular AutoComplete
Table of Contents
---
Overview
The Angular AutoComplete supports both Angular form approaches:
| Approach | Module Required | Binding Syntax |
|---|---|---|
| Template-driven | FormsModule | [(ngModel)]="value" |
| Reactive | ReactiveFormsModule | [formControlName]="'fieldName'" |
---
Template-Driven Forms (ngModel)
Import FormsModule and use ngModel with a name attribute on the <ejs-autocomplete> element. The AutoComplete value is automatically included in the form model.
import { Component } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';
@Component({
imports: [AutoCompleteModule, FormsModule],
standalone: true,
selector: 'app-root',
template: `
<form #skillForm="ngForm" (ngSubmit)="onSubmit(skillForm)">
<div>
<label>Name</label>
<input type="text" name="sname" [(ngModel)]="formData.sname" required />
</div>
<div>
<label>Skill</label>
<ejs-autocomplete
id="skillField"
name="skillname"
[dataSource]="skillset"
[placeholder]="placeholder"
[(ngModel)]="formData.skillname"
required>
</ejs-autocomplete>
</div>
<div>
<label>Email</label>
<input type="email" name="smail" [(ngModel)]="formData.smail" required />
</div>
<button type="submit" [disabled]="skillForm.invalid">Submit</button>
</form>
<div *ngIf="submitted">
<p>Submitted: {{ formData | json }}</p>
</div>
`
})
export class AppComponent {
public skillset: string[] = [
'ASP.NET', 'ActionScript', 'Basic', 'C++', 'C#',
'dBase', 'Delphi', 'ESPOL', 'F#', 'FoxPro',
'Java', 'J#', 'Lisp', 'Logo', 'PHP'
];
public placeholder: string = 'e.g: ActionScript';
public submitted = false;
public formData = {
skillname: null as string | null,
sname: '',
smail: ''
};
public onSubmit(form: any): void {
if (form.valid) {
this.submitted = true;
}
}
}Key points:
- Add
nameattribute on<ejs-autocomplete>so Angular's form tracking works - Use
[(ngModel)]for two-way binding to the form model - Form validity (
skillForm.invalid) reflects whether the AutoComplete has a value whenrequired
---
Reactive Forms (FormControl)
Import ReactiveFormsModule and use FormGroup + FormControl (or FormBuilder) to manage the AutoComplete value programmatically:
import { Component, Inject } from '@angular/core';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';
import {
ReactiveFormsModule,
FormBuilder,
FormGroup,
Validators
} from '@angular/forms';
@Component({
imports: [AutoCompleteModule, ReactiveFormsModule],
standalone: true,
selector: 'app-root',
template: `
<form [formGroup]="skillForm" (ngSubmit)="onSubmit()">
<div>
<label>Name</label>
<input type="text" formControlName="sname" />
<span *ngIf="skillForm.get('sname')?.invalid && skillForm.get('sname')?.touched">
Name is required.
</span>
</div>
<div>
<label>Skill</label>
<ejs-autocomplete
id="skillField"
[dataSource]="skillset"
[placeholder]="placeholder"
formControlName="skillname">
</ejs-autocomplete>
<span *ngIf="skillForm.get('skillname')?.invalid && skillForm.get('skillname')?.touched">
Skill is required.
</span>
</div>
<div>
<label>Email</label>
<input type="email" formControlName="smail" />
<span *ngIf="skillForm.get('smail')?.invalid && skillForm.get('smail')?.touched">
Email is required.
</span>
</div>
<button type="submit" [disabled]="skillForm.invalid">Submit</button>
</form>
<div *ngIf="submitted">
<p>Form Value: {{ skillForm.value | json }}</p>
</div>
`
})
export class AppComponent {
public skillset: string[] = [
'ASP.NET', 'ActionScript', 'Basic', 'C++', 'C#',
'dBase', 'Delphi', 'ESPOL', 'F#', 'FoxPro',
'Java', 'J#', 'Lisp', 'Logo', 'PHP'
];
public placeholder: string = 'e.g: ActionScript';
public submitted = false;
public skillForm: FormGroup;
constructor(@Inject(FormBuilder) private builder: FormBuilder) {
this.skillForm = this.builder.group({
skillname: ['', Validators.required],
sname: ['', Validators.required],
smail: ['', Validators.required]
});
}
public onSubmit(): void {
if (this.skillForm.valid) {
this.submitted = true;
}
}
}Key points:
- Use
formControlName="skillname"to bind the AutoComplete to aFormControl - Set initial value in the
FormGroupdefinition to pre-select a value - Access the current value via
skillForm.get('skillname')?.value - Validators (e.g.,
Validators.required) work the same as with native inputs
---
Tips & Common Patterns
| Scenario | Solution |
|---|---|
| Pre-select a value in reactive form | Set default in FormBuilder: skillname: ['Java', ...] |
| Clear the AutoComplete from code | skillForm.patchValue({ skillname: null }) |
| Disable the field in reactive form | skillForm.get('skillname')?.disable() |
| Read current value | skillForm.value.skillname or skillForm.get('skillname')?.value |
| Validate on submit only | Mark all controls touched: skillForm.markAllAsTouched() |