From 24967030ca4785f4696cdca61050fde32b6c9ee2 Mon Sep 17 00:00:00 2001 From: Ivan Minchev Date: Mon, 9 Nov 2026 19:16:12 +0200 Subject: [PATCH] feat(combo): update features topic content --- .../content/en/components/combo-features.mdx | 242 ------- .../content/en/components/combo-remote.mdx | 256 ------- .../content/en/components/combo-templates.mdx | 4 +- .../src/content/en/components/combo.mdx | 14 +- .../content/en/components/simple-combo.mdx | 6 +- .../src/content/en/components/toc.json | 9 +- .../en/components/inputs/combo/features.mdx | 663 +++++++++++++----- docs/xplat/src/content/en/toc.json | 9 + 8 files changed, 502 insertions(+), 701 deletions(-) delete mode 100644 docs/angular/src/content/en/components/combo-features.mdx delete mode 100644 docs/angular/src/content/en/components/combo-remote.mdx diff --git a/docs/angular/src/content/en/components/combo-features.mdx b/docs/angular/src/content/en/components/combo-features.mdx deleted file mode 100644 index c0a432346e..0000000000 --- a/docs/angular/src/content/en/components/combo-features.mdx +++ /dev/null @@ -1,242 +0,0 @@ ---- -title: ComboBox Features - MIT license -description: Combo control exposes several of features including data and value binding, custom values, filtering, grouping, etc. -keywords: Ignite UI for Angular, UI controls, Angular widgets, web widgets, UI widgets, Angular, Native Angular Components Suite, Native Angular Controls, Native Angular Components Library, Angular Combo components, Angular Features, Angular Combo Features, Angular Combo Data Binding, Angular Combo Value Binding, Angular Combo Data Filtering, Angular Combo Grouping, Angular Combo Custom Values -license: MIT -llms: - description: "The Ignite UI for Angular ComboBox control exposes several features including data and value binding, custom values, filtering, grouping, etc." ---- - -import DocsAside from 'igniteui-astro-components/components/mdx/DocsAside.astro'; -import Sample from 'igniteui-astro-components/components/mdx/Sample.astro'; -import ApiLink from 'igniteui-astro-components/components/mdx/ApiLink.astro'; - -# ComboBox Features - -
- -The Ignite UI for Angular ComboBox control exposes several features including data and value binding, custom values, filtering, grouping, etc. -
- -## Angular ComboBox Features Example - -The following demo demonstrates some of the combobox features that are enabled/disabled at runtime: - - - -
- -## Usage - -### First Steps - -To get started with the combobox component, first you need to import the `IgxComboModule` in your **app.module.ts** file. Our sample also uses the component to toggle combobox properties' values, so we will need the `IgxSwitchModule` as well: - -```typescript -import { IgxComboModule } from 'igniteui-angular/combo'; -import { IgxSwitchModule } from 'igniteui-angular/switch'; -// import { IgxComboModule, IgxSwitchModule } from '@infragistics/igniteui-angular'; for licensed package - -@NgModule({ - imports: [ - ... - IgxComboModule, - IgxSwitchModule, - ... - ] -}) -export class AppModule {} -``` - -### Template Configuration - -```html -
- - - -
-
- - Allow Custom Values - Enable Grouping - Disable Combo - Disable Filtering - @if (!disableFiltering) { - Show Case-sensitive Icon - } -
-``` - -### Component Definition - -Note that grouping is enabled/disabled by setting the property to a corresponding data source entity or setting it to an empty string. - -```typescript - @ViewChild('combo', { read: IgxComboComponent }) public combo: IgxComboComponent; - - public disableFiltering = false; - public showSearchCaseIcon = true; - public customValues = true; - public disabled = false; - - public enableGroups(event) { - this.combo.groupKey = event.checked ? 'region' : ''; - } -``` - -## Features - -### Data Binding - -The following code snippet illustrates a basic usage of the bound to a local data source. The specifies which property of the data entries will be stored for the combobox's selection and the specifies which property will be used for the combobox text: - -```html - -``` - -```typescript -import { localData } from './local-data'; - -export class ComboDemo implements OnInit { - public lData: any[]; - - public ngOnInit() { - this.lData = localData; - } -} -``` - - -If the `displayKey` property is omitted then the `valueKey` entity will be used instead. - - -Follow the [ComboBox Remote Binding topic](/combo-remote) for more details about binding the combobox component with remote data. - -### Custom Overlay Settings - -The combobox component allows users to change the way a list of items is shown. This can be done by defining and passing them to the input: - -```typescript -export class CustomOverlayCombo { - ... - public customSettings: OverlaySettings = { - positionStrategy: new GlobalPositionStrategy( - { - openAnimation: scaleInCenter, - closeAnimation: scaleOutCenter - }), - modal: true, - closeOnOutsideClick: true, - }; -} -``` - -```html - -``` - -If everything is set up correctly, the combobox's list will display centered, using the [GlobalPositionStrategy](/overlay-position#global): - - - -
- - -The combobox component uses the as a default position strategy. - - -### Filtering - -By default, filtering in the combobox is enabled. It can be disabled by setting the property to true. - -Filtering options can be further enhanced by enabling the search case sensitivity. To display the case-sensitive icon in the search input, set the property to true: - -```html - -``` - -
- -### Custom Values - -The property controls whether custom values can be added to the collection. If it is enabled, a missing item could be included using the UI of the combobox. - -```html - -``` - -
- -### Search Input Focus - -The combobox's property controls if the search input should receive focus when a combobox's dropdown list is opened. By default, the property is set to `true`. When set to `false`, the focus goes to the combobox's items container. For mobile devices, this can be used to prevent the software keyboard from popping up when opening the combobox's dropdown list. - -```html - -``` - -
- -### Disable ComboBox - -You can disable a combobox using the following code: - -```html - -``` - -
- -### Grouping - -Defining a combobox's `groupKey` option will group the items, according to the provided key: - -```html - -``` - -You can set whether groups should be sorted in ascending or descending order. By default the sorting order is ascending. - -```html - -``` - -```typescript -... -import { SortingDirection } from 'igniteui-angular/core' -// import { SortingDirection } from '@infragistics/igniteui-angular'; for licensed package - -export class ComboDemo { - ... - public groupSortingDirection: SortingDirection = SortingDirection.Asc; -} -``` - -
- -## API References -
-- -- -Additional components and/or directives with relative APIs that were used: -- -## Additional Resources - -
- -- [ComboBox Component](/combo) -- [ComboBox Remote Binding](/combo-remote) -- [ComboBox Templates](/combo-templates) -- [Template Driven Forms Integration](/input-group) -- [Reactive Forms Integration](/angular-reactive-form-validation) -- [Single Select ComboBox](/simple-combo) - -Our community is active and always welcoming to new ideas. - -- [Ignite UI for Angular **Forums**](https://www.infragistics.com/community/forums/f/ignite-ui-for-angular) -- [Ignite UI for Angular **GitHub**](https://github.com/IgniteUI/igniteui-angular) diff --git a/docs/angular/src/content/en/components/combo-remote.mdx b/docs/angular/src/content/en/components/combo-remote.mdx deleted file mode 100644 index 401d31c32e..0000000000 --- a/docs/angular/src/content/en/components/combo-remote.mdx +++ /dev/null @@ -1,256 +0,0 @@ ---- -title: ComboBox Remote Binding - MIT license -description: The igx-combo exposes API that allows to bind a combo to a remote service and retrieve data on demand. -keywords: Ignite UI for Angular, UI controls, Angular widgets, web widgets, UI widgets, Angular, Native Angular Components Suite, Native Angular Controls, Native Angular Components Library, Angular Combo components, Angular Combo controls, Angular Combo Remote Binding -license: MIT -llms: - description: "The Ignite UI for Angular ComboBox Component exposes an API that allows binding a combobox to a remote service and retrieving data on demand." ---- - -import DocsAside from 'igniteui-astro-components/components/mdx/DocsAside.astro'; -import Sample from 'igniteui-astro-components/components/mdx/Sample.astro'; -import ApiLink from 'igniteui-astro-components/components/mdx/ApiLink.astro'; - -# ComboBox Remote Binding - -
- -The Ignite UI for Angular ComboBox Component exposes an API that allows binding a combobox to a remote service and retrieving data on demand. -
- -## Angular ComboBox Remote Binding Example - -The sample below demonstrates remote binding using the property to load new chunk of remote data: - - - -## Usage - -To get started with the ComboBox component, first you need to import the `IgxComboModule` in your **app.module.ts** file. In this demo, a remote service is used for server requests, therefore, we also need to include the `HttpClientModule`: - -```typescript -import { IgxComboModule } from 'igniteui-angular/combo'; -// import { IgxComboModule } from '@infragistics/igniteui-angular'; for licensed package - -import { HttpClientModule } from '@angular/common/http'; - -@NgModule({ - imports: [ - ... - IgxComboModule, - HttpClientModule, - ... - ] -}) -export class AppModule {} -``` - -### Define Remote Service - -When binding a combobox to remote data, we need to have an available service that will load data on demand from a server. The combobox component exposes the property which gives the current state of a combobox - the first index and the number of items that need to be loaded. In order to show properly the scroll size, the property should have value that corresponds to the total items on the server. - -The code below defines a simple service that has a `getData()` method, which receives combobox's current state information and returns data as an observable: - -```typescript -import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { IForOfState } from 'igniteui-angular/directives'; -// import { IForOfState } from '@infragistics/igniteui-angular'; for licensed package -import { BehaviorSubject, Observable } from 'rxjs'; - -@Injectable() -export class RemoteService { - public remoteData: Observable; - private _remoteData: BehaviorSubject; - - constructor(private http: HttpClient) { - this._remoteData = new BehaviorSubject([]); - this.remoteData = this._remoteData.asObservable(); - } - - // Use combobox current virtualization state and search text to build URL and request the new data. - public getData(data?: IForOfState, searchText?: string, cb?: (any) => void): any { } -} -``` - -### Binding ComboBox to Remote Service - -When data is returned from a service as an observable, we can set it to the combobox component using the [async](https://angular.io/api/common/AsyncPipe) pipe: - -```html - - -``` - -Here are some common cases when the combobox component needs to request new data: - - when the combobox is initialized - - when we scroll combobox's list - it will emit `dataPreLoad` along with the new combobox `virtualizationState`, which allows making a new request to the remote service. - - when searching in a combobox - we need to make request to filter remote results. - - when combobox is opened - we need to clear the results from any previous filter operations. - -Below are listed the handlers that listen to the already defined actions and execute requests to the server: - -```typescript -import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core'; -import { IgxComboComponent } from 'igniteui-angular/combo'; -// import { IgxComboComponent } from '@infragistics/igniteui-angular'; for licensed package - -import { RemoteService } from '../../grid/services/remote.service'; - -@Component({ - providers: [RemoteService], - selector: 'app-combo-remote', - styleUrls: ['./combo-remote.component.scss'], - templateUrl: './combo-remote.component.html' -}) -export class ComboRemoteComponent implements OnInit { - @ViewChild('remoteCombo', { read: IgxComboComponent }) public remoteCombo: IgxComboComponent; - - public prevRequest: any; - public rData: any; - - private searchText: string = null; - private defaultVirtState: IForOfState = { chunkSize: 6, startIndex: 0 }; - - private currentVirtState: IForOfState = { chunkSize: 6, startIndex: 0 }; - private itemID: number = 1; - private itemCount: number = 0; - private hasSelection: boolean; - private additionalScroll: number = 0; - - constructor(private remoteService: RemoteService, public cdr: ChangeDetectorRef) { } - - public ngOnInit() { - this.rData = this.remoteService.remoteData; - } - - public ngAfterViewInit() { - const initSize = { - startIndex: 0, - chunkSize: Math.ceil(250 / this.remoteCombo.itemHeight) - }; - this.remoteService.getData(initSize, null, (data) => { - this.remoteCombo.totalItemCount = data['@odata.count']; - this.itemCount = this.remoteCombo.totalItemCount; - }); - } - - public dataLoading(evt) { - if (this.prevRequest) { - this.prevRequest.unsubscribe(); - } - this.prevRequest = this.remoteService.getData( - this.remoteCombo.virtualizationState, - this.searchText, - (data) => { - this.remoteCombo.totalItemCount = data['@odata.count']; - this.cdr.detectChanges(); - }); - } - - public handleSearchInputUpdate(searchData: IComboSearchInputEventArgs) { - this.currentVirtState.startIndex = 0; - this.currentVirtState.chunkSize = Math.ceil(this.remoteCombo.itemsMaxHeight / this.remoteCombo.itemHeight); - this.searchText = searchData?.searchText || ''; - this.remoteService.getData( - this.searchText ? this.currentVirtState : this.defaultVirtState, - this.searchText, - (data) => { - this.remoteCombo.totalItemCount = data['@odata.count']; - } - ); - } - - public onOpened() { - const scroll: number = this.remoteCombo.virtualScrollContainer.getScrollForIndex(this.itemID - 1); - this.remoteCombo.virtualScrollContainer.scrollPosition = scroll + this.additionalScroll; - this.cdr.detectChanges(); - } - - public onClosing() { - this.searchText = ''; - } - - public onClosed() { - this.currentVirtState.startIndex = (this.itemID || 1) - 1; - this.remoteService.getData( - this.currentVirtState, - this.searchText, - (data) => { - this.remoteCombo.totalItemCount = data['@odata.count']; - this.cdr.detectChanges(); - } - ); - } - - public handleSelectionChanging(evt: IComboSelectionChangingEventArgs) { - this.hasSelection = !!evt?.newSelection.length; - - if (!this.hasSelection) { - this.itemID = 1; - this.currentVirtState = this.defaultVirtState; - return; - } - - const currentSelection = evt.newSelection[evt.newSelection.length - 1] - this.currentVirtState.chunkSize = Math.ceil(this.remoteCombo.itemsMaxHeight / this.remoteCombo.itemHeight); - - this.itemCount === currentSelection ? - this.additionalScroll = this.remoteCombo.itemHeight : - this.additionalScroll = 0; - - if (this.itemCount - currentSelection >= this.currentVirtState.chunkSize - 1) { - this.itemID = this.currentVirtState.startIndex = currentSelection; - } else { - this.itemID = this.currentVirtState.startIndex = this.itemCount - (this.currentVirtState.chunkSize - 1); - } - } -} -``` - - -Anytime new data is loaded, we update the `totalItemCount` property, in order to have proper size of the list's scroll bar. In that case, the service returns total size using the property `@odata.count`. - - - -A service needs to be included as a provider. - - -### Handling Selection - -When using a combobox bound to remote data loaded in chunks and dealing with a more complex data type (e.g. objects), it is necessary to define a `valueKey`. As stated in the [combobox topic](/combo#data-value-and-display-properties), when no `valueKey` is specified, the combobox will try to handle selection by `equality (===)`. Since the objects that will be marked as selected will not be the same as the object that are continuously loaded, the selection will fail. - - -When binding a combobox to remote data, make sure to specify a `valueKey`, representing a property that is unique to each item. - - -When the combobox is bound to remote data, setting value/selected items through API will only take into account the items that are loaded in the current chunk. If you want to set an initial value, make sure those specific items are loaded before selecting. - -## API References -
-- -- -## Additional Resources - -
- -- [ComboBox Component](/combo) -- [ComboBox Features](/combo-features) -- [ComboBox Templates](/combo-templates) -- [Template Driven Forms Integration](/input-group) -- [Reactive Forms Integration](/angular-reactive-form-validation) -- [Single Select ComboBox](/simple-combo) - -Our community is active and always welcoming to new ideas. - -- [Ignite UI for Angular **Forums**](https://www.infragistics.com/community/forums/f/ignite-ui-for-angular) -- [Ignite UI for Angular **GitHub**](https://github.com/IgniteUI/igniteui-angular) diff --git a/docs/angular/src/content/en/components/combo-templates.mdx b/docs/angular/src/content/en/components/combo-templates.mdx index 6bbf09f852..1d002966ac 100644 --- a/docs/angular/src/content/en/components/combo-templates.mdx +++ b/docs/angular/src/content/en/components/combo-templates.mdx @@ -178,8 +178,8 @@ When used with templates, the `igxComboClearIcon` and the `igxComboToggleIcon` s
- [ComboBox Component](/combo) -- [ComboBox Features](/combo-features) -- [ComboBox Remote Binding](/combo-remote) +- [ComboBox Features](/inputs/combo/features) +- [ComboBox Remote Binding](/inputs/combo/features#remote-binding) - [Template Driven Forms Integration](/input-group) - [Reactive Forms Integration](/angular-reactive-form-validation) - [Single Select ComboBox](/simple-combo) diff --git a/docs/angular/src/content/en/components/combo.mdx b/docs/angular/src/content/en/components/combo.mdx index 7f127f9b65..a109f6d280 100644 --- a/docs/angular/src/content/en/components/combo.mdx +++ b/docs/angular/src/content/en/components/combo.mdx @@ -27,11 +27,11 @@ In this Angular ComboBox example, you can see how users can filter items and per The combobox control exposes the following features: -- Data Binding - local data and [remote data](/combo-remote) -- [Value Binding](/combo-features#data-binding) -- [Filtering](/combo-features#filtering) -- [Grouping](/combo-features#grouping) -- [Custom Values](/combo-features#custom-values) +- Data Binding - local data and [remote data](/inputs/combo/features#remote-binding) +- [Value Binding](/inputs/combo/features#data-binding) +- [Filtering](/inputs/combo/features#filtering) +- [Grouping](/inputs/combo/features#grouping) +- [Custom Values](/inputs/combo/features#custom-values) - [Templates](/combo-templates) - Integration with [Template Driven Forms](/input-group) and [Reactive Forms](/angular-reactive-form-validation) @@ -451,8 +451,8 @@ Additional [angular components](https://www.infragistics.com/products/ignite-ui-
-- [ComboBox Features](/combo-features) -- [ComboBox Remote Binding](/combo-remote) +- [ComboBox Features](/inputs/combo/features) +- [ComboBox Remote Binding](/inputs/combo/features#remote-binding) - [ComboBox Templates](/combo-templates) - [Template Driven Forms Integration](/input-group) - [Reactive Forms Integration](/angular-reactive-form-validation) diff --git a/docs/angular/src/content/en/components/simple-combo.mdx b/docs/angular/src/content/en/components/simple-combo.mdx index 2611067d5d..d98781c53b 100644 --- a/docs/angular/src/content/en/components/simple-combo.mdx +++ b/docs/angular/src/content/en/components/simple-combo.mdx @@ -317,7 +317,7 @@ The Ignite UI for Angular Simple ComboBox Component exposes an API that allows b ### Demo -The sample below demonstrates remote binding using the property to load new chunk of remote data and following the steps described in [ComboBox Remote Binding](/combo-remote): +The sample below demonstrates remote binding using the property to load new chunk of remote data and following the steps described in [ComboBox Remote Binding](/inputs/combo/features#remote-binding): @@ -410,8 +410,8 @@ Additional components and/or directives with relative APIs that were used:
-- [ComboBox Features](/combo-features) -- [ComboBox Remote Binding](/combo-remote) +- [ComboBox Features](/inputs/combo/features) +- [ComboBox Remote Binding](/inputs/combo/features#remote-binding) - [ComboBox Templates](/combo-templates) - [Template Driven Forms Integration](/input-group) - [Reactive Forms Integration](/angular-reactive-form-validation) diff --git a/docs/angular/src/content/en/components/toc.json b/docs/angular/src/content/en/components/toc.json index 9e3f6d8ceb..aab55e993b 100644 --- a/docs/angular/src/content/en/components/toc.json +++ b/docs/angular/src/content/en/components/toc.json @@ -1321,13 +1321,8 @@ "items": [ { "name": "Features", - "href": "combo-features.mdx", - "new": false - }, - { - "name": "Remote Binding", - "href": "combo-remote.mdx", - "new": false + "href": "inputs/combo/features.mdx", + "updated": true }, { "name": "Templates", diff --git a/docs/xplat/src/content/en/components/inputs/combo/features.mdx b/docs/xplat/src/content/en/components/inputs/combo/features.mdx index c58e3f2348..536ac1bffd 100644 --- a/docs/xplat/src/content/en/components/inputs/combo/features.mdx +++ b/docs/xplat/src/content/en/components/inputs/combo/features.mdx @@ -1,11 +1,13 @@ --- -title: "{Platform} ComboBox Component – {ProductName}" -description: "{ProductName} ComboBox Component Features" -keywords: "{ProductName}, UI controls, {Platform} widgets, web widgets, UI widgets, {Platform}, Native {Platform} Components Suite, Native {Platform} Controls, Native {Platform} Components Library, {Platform} ComboBox Component Features" +title: "{Platform} Combo Features" +description: "The {Platform} Combo binds to local data, filters its options as the user types, groups them by a data field, and can be disabled." +keywords: "{ProductName}, UI controls, {Platform} widgets, web widgets, UI widgets, {Platform}, Native {Platform} Components Suite, Native {Platform} Controls, Native {Platform} Components Library, {Platform} Combo Features, {Platform} Combo Data Binding, {Platform} Combo Filtering, {Platform} Combo Grouping" license: MIT -mentionedTypes: ["Combo", "ComboList", "ComboItem"] +last_updated: "2026-11-09" +platformType: web-only +mentionedTypes: ["Combo"] llms: - description: "The {ProductName} ComboBox component exposes several features such as filtering and grouping." + description: "The {Platform} Combo binds to local data, filters its options as the user types, groups them by a data field, and can be disabled." --- import DocsAside from 'igniteui-astro-components/components/mdx/DocsAside.astro'; import PlatformBlock from 'igniteui-astro-components/components/mdx/PlatformBlock.astro'; @@ -13,194 +15,353 @@ import Sample from 'igniteui-astro-components/components/mdx/Sample.astro'; import ApiLink from 'igniteui-astro-components/components/mdx/ApiLink.astro'; -# {Platform} ComboBox Features +# Combo Component Features -The {ProductName} ComboBox component exposes several features such as filtering and grouping. +The {Platform} Combo binds to local data, filters its options as the user types, groups them by a data field, and can be disabled. -## Combobox Features Example -The following demo shows some features that are enabled/disabled at runtime: + - +The Combo can also load its data from a remote service in chunks, accept custom values, and show its list with custom overlay settings. + + +## Live Demo + + - + -In our sample we are going to use the component, so we have to import them together with the combo: + + + +## Features + +### Data Binding + +Bind the {Platform} Combo to a local data source through its property. The sets which property of the data items the Combo stores as its selection, and the sets which property the Combo shows as the text of each item. The following snippets bind the Combo to a list of US states, storing the code of each state and showing its name: + + + +```typescript +import { usStates } from './states-data'; + +export class ComboDataBindingComponent { + // Items such as { id: 'CT', name: 'Connecticut', region: 'New England' } + public usStates = usStates; +} +``` + +```html + +``` + + +```html + +``` ```ts -import { defineComponents, IgcComboComponent, IgcSwitchComponent } from 'igniteui-webcomponents'; -import 'igniteui-webcomponents/themes/light/bootstrap.css'; +import { IgcComboComponent } from 'igniteui-webcomponents'; +import { UsState, usStates } from './ComboData'; -defineComponents(IgcComboComponent, IgcSwitchComponent); +// Items such as { id: 'CT', name: 'Connecticut', region: 'New England' } +const combo = document.getElementById('combo') as IgcComboComponent; +combo.data = usStates; ``` + +```razor + - +@code { + // Items such as new UsState { Id = "CT", Name = "Connecticut", Region = "New England" } + private List usStates = UsStatesData.States; + private string[] selectedStates = []; +} +``` -In our sample we are going to use the component. +`IgbCombo` infers its value type from `Data` and `@bind-Value`. The Blazor snippets in the rest of this topic leave them out, so add them back when you copy a snippet. -Register the {ProductName} services: + -```csharp -// in Program.cs file + + +```tsx +import { IgrCombo } from "igniteui-react"; +import { usStates } from "./ComboData"; -builder.Services.AddIgniteUIBlazor(); +// Items such as { id: "CT", name: "Connecticut", region: "New England" } + ``` -Registering , the Combo's client resource module, is **optional**: the component loads its resources when it first renders. Listing it in `builder.Services.AddIgniteUIBlazor(typeof(IgbComboModule))` can be used to preload resources or to support elements created only on the client (see [Component Modules](../../general-getting-started.mdx#component-modules)). + + + +When the property is not set, the Combo shows the property set by . + -You will also need to link an additional CSS file to apply the styling to the component. The following needs to be placed in the app's host page (**wwwroot/index.html** in a standalone Blazor WebAssembly or Blazor Hybrid app, **Pages/_Host.cshtml** in a Blazor Server app, **Components/App.razor** in a Blazor Web App): + -```razor - +### Remote Binding + +The Combo can load its data from a remote service in chunks: it requests the items the user scrolls to through the event, and the service returns only those items. The sample below loads products from a remote service while the user scrolls and searches: + + + +#### Define Remote Service + +A remote service loads the items on demand from a server. The Combo exposes its property, which holds the index of the first item to load and the number of items to load. To size the scrollbar for all the items on the server, set the property to their total count. + +The following service has a `getData()` method that builds the request from the state of the Combo and its search text, and emits the loaded items through an observable: + +```typescript +import { HttpClient } from '@angular/common/http'; +import { Injectable, inject } from '@angular/core'; +import { IForOfState } from 'igniteui-angular/directives'; +// import { IForOfState } from '@infragistics/igniteui-angular/directives'; for licensed package +import { BehaviorSubject } from 'rxjs'; + +@Injectable() +export class RemoteNWindService { + private http = inject(HttpClient); + private url = 'https://services.odata.org/V4/Northwind/Northwind.svc/Products'; + + public remoteData = new BehaviorSubject([]); + + public getData(state: IForOfState, searchText: string, cb?: (data: any) => void) { + return this.http.get(this.buildUrl(state, searchText)).subscribe((data: any) => { + this.remoteData.next(data.value); + cb?.(data); + }); + } + + // Requests the chunk of items the Combo shows, and the total count of the matching items. + private buildUrl(state: IForOfState, searchText: string): string { + let query = `?$skip=${state.startIndex}&$top=${state.chunkSize}&$count=true`; + if (searchText) { + // Double the apostrophes for OData, then encode the text for the URL. + const text = encodeURIComponent(searchText.replace(/'/g, "''")); + query += `&$filter=contains(ProductName, '${text}')`; + } + return `${this.url}${query}`; + } +} ``` +#### Binding ComboBox to Remote Service + +Bind the observable of the service to the Combo with the `async` pipe, and request a new chunk of items whenever the Combo raises or the search text changes: + +```html + + + +``` + +```typescript +// The size of the first chunk, requested before the Combo reports how many items it shows. +const FIRST_CHUNK_SIZE = 10; + +// The component lists RemoteNWindService in its providers, and the application +// providers include provideHttpClient(), which the service needs. +export class ComboRemoteComponent implements OnInit { + @ViewChild('remoteCombo', { static: true }) + public remoteCombo: IgxComboComponent; + + private remoteService = inject(RemoteNWindService); + public rData = this.remoteService.remoteData; + private searchText = ''; + + public ngOnInit() { + this.loadChunk({ startIndex: 0, chunkSize: FIRST_CHUNK_SIZE }); + } + + // The Combo asks for the next chunk while the user scrolls. + public onDataPreLoad() { + this.loadChunk(this.remoteCombo.virtualizationState); + } + + // The server filters the items: request the first chunk of the matching ones. + public onSearchInputUpdate(event: IComboSearchInputEventArgs) { + this.searchText = event.searchText; + this.loadChunk({ startIndex: 0, chunkSize: FIRST_CHUNK_SIZE }); + } + + private loadChunk(state: IForOfState) { + this.remoteService.getData(state, this.searchText, (data) => { + // The total count sizes the scrollbar for all the items, not only the loaded chunk. + this.remoteCombo.totalItemCount = data['@odata.count']; + }); + } +} +``` + +#### Handling Selection + +When the Combo is bound to remote data that loads in chunks, and the data items are objects, set the property. Without it, the Combo compares the selected items with the loaded items by reference, as described in the [Combo topic](../../combo.mdx#data-value-and-display-properties). Every chunk the service loads creates new objects, so the Combo can't match the selected items with them. + + +When binding the Combo to remote data, set the `valueKey` property to a property that is unique to each item. + + +### Custom Overlay Settings + +The Combo shows its list of items in an overlay, which you can configure by passing to the input. The Combo merges these settings over its own defaults, so set only the ones to change. The following settings make the list modal, which dims the page behind it, and close it when the user clicks outside: + +```typescript +import { OverlaySettings } from 'igniteui-angular/core'; +// import { OverlaySettings } from '@infragistics/igniteui-angular/core'; for licensed package + +export class ComboOverlayComponent { + public overlaySettings: OverlaySettings = { + modal: true, + closeOnOutsideClick: true + }; +} +``` + +```html + +``` + + + + +By default, the Combo positions its list with the , which opens the list below the input, or above it when there isn't enough room. + +### Filtering +The {Platform} Combo filters its list of options as the user types in the search input of the dropdown. Filtering is on by default. Set to turn it off, which also hides the search input. - + +To let users switch the search between case-sensitive and case-insensitive, set . The Combo then shows a case-sensitive icon in its search input. The icon has no effect while filtering is disabled, because the search input is hidden. +```html + + -```tsx -import { IgrCombo, IgrSwitch } from 'igniteui-react'; -import 'igniteui-webcomponents/themes/light/bootstrap.css'; + + ``` + + + + +To let users switch the search between case-sensitive and case-insensitive, set . The Combo then shows a case-sensitive icon in its search input. The icon has no effect while filtering is disabled, because the search input is hidden. + + +```html + + + + + +``` + + + + + +```razor +@* Shows the case-sensitive icon in the search input *@ + + +@* Turns filtering off, which also hides the search input *@ + +``` -Then, using React's useState hook, we will declare our variables which will update when the state of the switches change. This will keep track for updates and reflect the changes to the combo inputs accordingly: + ```tsx -const [disableFiltering, setDisableFiltering] = useState(false); -const [caseSensitiveIcon, setCaseSensitiveIcon] = useState(false); -const [groupingEnabled, setGroupingEnabled] = useState(false); -const [comboDisabled, setComboDisabled] = useState(false); - - - - - - setDisableFiltering(e.detail.checked)}> - Disable Filtering - - setCaseSensitiveIcon(e.detail.checked)}> - Show Case-sensitive Icon - - setGroupingEnabled(e.detail.checked)}> - Enable Grouping - - setComboDisabled(e.detail.checked)}> - Disable Combo - +// Shows the case-sensitive icon in the search input + + +// Turns filtering off, which also hides the search input + ``` - +#### Filtering Options -```ts -let combo = document.getElementById('combo') as IgcComboComponent; +The property configures how the {Platform} Combo matches the search text: -let switchIcon = document.getElementById('caseSensitive') as IgcSwitchComponent; -let switchFilter = document.getElementById('filtering') as IgcSwitchComponent; -let switchDisable = document.getElementById('disabled') as IgcSwitchComponent; + -switchIcon.addEventListener("igcChange", () => { - combo.caseSensitiveIcon = switchIcon.checked; -}); +- `filteringKey` - the data field to search in. Defaults to the field set by `displayKey`. +- `caseSensitive` - whether the search is case-sensitive. Defaults to `false`. The case-sensitive icon toggles this value. -switchFilter.addEventListener("igcChange", () => { - combo.disableFiltering = switchIcon.disabled = switchFilter.checked; -}); + -switchDisable.addEventListener("igcChange", () => { - combo.disabled = switchDisable.checked; -}); -``` + + +- `filterKey` - the data field to search in. Defaults to the field set by `displayKey`. +- `caseSensitive` - whether the search is case-sensitive. Defaults to `false`. The case-sensitive icon toggles this value. +- `matchDiacritics` - whether accented letters match only themselves, so that `é` doesn't match `e`. Defaults to `false`. -```razor - - - -Disable Filtering -Show Case-sensitive Icon -Enable Grouping -Disable Combo +In Blazor, set these options through an `IgbFilteringOptions` object, as `FilterKey`, `CaseSensitive` and `MatchDiacritics`. -@code { - private string[] SelectedCities = []; - private bool DisableFiltering = false; - private bool CaseSensitiveIcon = false; - private bool Disabled = false; + - public void OnDisableFilteringClick(IgbCheckboxChangeEventArgs e) { - this.DisableFiltering = e.Detail.Checked; - } +The following snippet searches the region of each state instead of its name, and makes the search case-sensitive: - public void OnCaseSensitiveClick(IgbCheckboxChangeEventArgs e) { - this.CaseSensitiveIcon = e.Detail.Checked; - } + - public void OnDisableClick(IgbCheckboxChangeEventArgs e) { - this.Disabled = e.Detail.Checked; - } +```typescript +import { IComboFilteringOptions } from 'igniteui-angular/combo'; +// import { IComboFilteringOptions } from '@infragistics/igniteui-angular/combo'; for licensed package + +export class ComboDemo { + public filteringOptions: IComboFilteringOptions = { + filteringKey: 'region', + caseSensitive: true + }; } ``` - +```html + +``` -Note that grouping is enabled/disabled by setting the property to a corresponding data source field: + ```ts -let switchGroup = document.getElementById('grouping') as IgcSwitchComponent; - -switchGroup.addEventListener("igcChange", () => { - this.combo.groupKey = switchGroup.checked ? "country" : undefined; -}); +combo.filteringOptions = { + filterKey: 'region', + caseSensitive: true +}; ``` @@ -208,12 +369,14 @@ switchGroup.addEventListener("igcChange", () => { ```razor -@code { - private string Group = ""; + - public void OnGroupClick(IgbCheckboxChangeEventArgs e) { - this.Group = e.Detail.Checked ? "Country" : ""; - } +@code { + private IgbFilteringOptions filteringOptions = new IgbFilteringOptions + { + FilterKey = "Region", + CaseSensitive = true + }; } ``` @@ -222,23 +385,47 @@ switchGroup.addEventListener("igcChange", () => { ```tsx - + ``` -## Features + -### Filtering +### Custom Values + +The property lets users add items that are missing from the data. When the search text matches no item, the dropdown shows an **Add item** button, which adds the search text to the data as a new item. + +```html + +``` + + + +### Search Input Focus + +When the dropdown of the {Platform} Combo opens, its search input receives focus. -By default, filtering in the ComboBox is enabled. It can be disabled by setting the property. + -Filtering options can be further enhanced by enabling the search case sensitivity. The case-sensitive icon can be turned on using the property so that end-users can control the case sensitivity. +Set the property to `false` to focus the list of items instead. On mobile devices, this keeps the software keyboard from opening with the dropdown. + +```html + +``` + + + + + +Set to focus the list of options instead. On mobile devices, this keeps the software keyboard from opening with the dropdown. + + ```html - + ``` @@ -246,7 +433,7 @@ Filtering options can be further enhanced by enabling the search case sensitivit ```razor - + ``` @@ -254,52 +441,58 @@ Filtering options can be further enhanced by enabling the search case sensitivit ```tsx - + ``` -#### Filtering Options - -The {ProductName} exposes one more filtering property that allows passing configuration of both `FilterKey` and `CaseSensitive` options. The `FilterKey` indicates which data source field should be used for filtering the list of options. The `CaseSensitive` option indicates if the filtering should be case-sensitive or not. +### Disable Combo -The following code snippet shows how to filter the cities from our data source by country instead of name. We are also making the filtering case-sensitive by default: +Set to disable the {Platform} Combo: + - +```html + +``` + -```ts -const options = { - filterKey: 'country', - caseSensitive: true -}; + -combo.filteringOptions = options; +```html + ``` + +```razor + +``` - + + ```tsx -const options = { - filterKey: 'country', - caseSensitive: true -}; - - + ``` - ### Grouping -Defining a option will group the items, according to the provided key: +Set to a field of the data items to group the options of the {Platform} Combo under a header for each value of that field: + + + +```html + +``` + + @@ -311,8 +504,10 @@ Defining a option wi +In Blazor, the key is the name of the C# property, such as `Region`: + ```razor - + ``` @@ -326,12 +521,35 @@ Defining a option wi -The property will only have effect if your data source consists of complex objects. +The property takes effect only when the data items are objects. #### Sorting Direction -The ComboBox component also exposes an option for setting whether groups should be sorted in ascending or descending order. By default, the sorting order is ascending: + + +The property sets the order of the groups in the Combo: `SortingDirection.Asc` (the default) sorts them in ascending order, `SortingDirection.Desc` in descending order, and `SortingDirection.None` keeps them in the order their first items appear in the data. The items inside each group keep their order in the data. + +```typescript +import { SortingDirection } from 'igniteui-angular/core'; +// import { SortingDirection } from '@infragistics/igniteui-angular/core'; for licensed package + +export class ComboDemo { + public groupSortingDirection = SortingDirection.Desc; +} +``` + +```html + +``` + + + + + +The property sets the order of the groups in the {Platform} Combo: `asc` (the default) sorts them in ascending order, `desc` in descending order, and `none` keeps them in the order their first items appear in the data. The items inside each group keep their order in the data. + + @@ -343,8 +561,10 @@ The ComboBox component also exposes an option for setting whether groups should +In Blazor, set it to a `GroupingDirection` value: `Asc`, `Desc` or `None`. + ```razor - + ``` @@ -357,14 +577,18 @@ The ComboBox component also exposes an option for setting whether groups should -### Label + -The label can be set easily using the property: +### Outlined + +Set to give the {Platform} Combo an outlined appearance: + + ```html - + ``` @@ -372,7 +596,7 @@ The label can be set easily using the ```razor - + ``` @@ -380,19 +604,23 @@ The label can be set easily using the ```tsx - + ``` -### Placeholder + -A placeholder text can be specified for both the ComboBox component input and the search input placed inside the dropdown menu: +### Clear Button + +The {Platform} Combo shows a clear button in its input while at least one option is selected, and clicking the button clears the selection. Set to hide the button: + + ```html - + ``` @@ -400,7 +628,7 @@ A placeholder text can be specified for both the ComboBox component input and th ```razor - + ``` @@ -408,19 +636,23 @@ A placeholder text can be specified for both the ComboBox component input and th ```tsx - + ``` -### Autofocus + -If you want your ComboBox to be automatically focused on page load you can use the following code: +### Label + +Set to show a label for the {Platform} Combo: + + ```html - + ``` @@ -428,7 +660,7 @@ If you want your ComboBox to be automatically focused on page load you can use t ```razor - + ``` @@ -436,19 +668,23 @@ If you want your ComboBox to be automatically focused on page load you can use t ```tsx - + ``` -### Search Input Focus + + +### Placeholder -The ComboBox search input is focused by default. To disable this feature and move the focus to the list of options use the property as shown below: +The property sets the text the {Platform} Combo input shows while no option is selected, and sets the text of the search input in the dropdown: + + ```html - + ``` @@ -456,7 +692,7 @@ The ComboBox search input is focused by default. To disable this feature and mov ```razor - + ``` @@ -464,19 +700,23 @@ The ComboBox search input is focused by default. To disable this feature and mov ```tsx - + ``` -### Required + + +### Autofocus -The ComboBox can be marked as required by setting the required property. +Set to focus the {Platform} Combo when the page loads: + + ```html - + ``` @@ -484,27 +724,33 @@ The ComboBox can be marked as required by setting the required property. ```razor - + ``` +In React, use the `autoFocus` prop: + ```tsx - + ``` -### Disable ComboBox + -You can disable the ComboBox using the property: +### Required + +Set to make the {Platform} Combo invalid in a form until at least one option is selected: + + ```html - + ``` @@ -512,7 +758,7 @@ You can disable the ComboBox using the ```razor - + ``` @@ -520,18 +766,67 @@ You can disable the ComboBox using the ```tsx - + ``` + + +### Scroll Strategy + +The property sets what the dropdown of the {Platform} Combo does when a container around the Combo scrolls while the dropdown is open: `hide` (the default) hides the dropdown while the input is out of view, `scroll` keeps the dropdown open and attached to the input, and `close` closes it. + + + + + +```html + +``` + + + + + +```tsx + +``` + + ## API References +See the complete {Platform} Combo API reference: + +- -
+ + +- +- + + ## Additional Resources +Use the following {Platform} resources to learn more about the Combo: + + + +- [Combo Overview](../../combo.mdx) +- [Combo Templates](../../combo-templates.mdx) +- [Single Select Combo](../../simple-combo.mdx) + + + + + +- [Combo Overview](./overview.mdx) +- [Combo Templates](./templates.mdx) +- [Single Selection Combo](./single-selection.mdx) + + + - [{ProductName} **Forums**]({ForumsLink}) - [{ProductName} **GitHub**]({GithubLink}) diff --git a/docs/xplat/src/content/en/toc.json b/docs/xplat/src/content/en/toc.json index 67816f5110..29200b0d00 100644 --- a/docs/xplat/src/content/en/toc.json +++ b/docs/xplat/src/content/en/toc.json @@ -3386,6 +3386,7 @@ { "name": "Features", "href": "inputs/combo/features.mdx", + "updated": true, "include": [ "Web" ] @@ -3409,6 +3410,14 @@ "Web" ] }, + { + "name": "Combo Features", + "href": "inputs/combo/features.mdx", + "updated": true, + "include": [ + "Angular" + ] + }, { "exclude": [ "Angular"