All Components

Filtering

To enable the filtering functionality, set the filterable property to true.

Basic Configuration

On every user modification of the input value, the ComboBox triggers a filterChange event. The event argument contains the typed string value that you can use to filter the source.

@Component({
  selector: 'my-app',
  template: `
    <div class="example-wrapper">
        <kendo-combobox
            [data]="data"
            [textField]="'text'"
            [valueField]="'value'"
            [filterable]="true"
            (filterChange)="handleFilter($event)"
            [placeholder]="'T-shirt size'"
        >
        </kendo-combobox>
    </div>
  `
})
export class AppComponent {
    public source: Array<{ text: string, value: number }> = [
        { text: "Small", value: 1 },
        { text: "Medium", value: 2 },
        { text: "Large", value: 3 }
    ];

    public data: Array<{ text: string, value: number }>;

    constructor() {
        this.data = this.source.slice();
    }

    handleFilter(value) {
        this.data = this.source.filter((s) => s.text.toLowerCase().indexOf(value.toLowerCase()) !== -1);
    }
}

To filter the data after a delay, use a similar implementation. You can toggle the loading property and provide the user with a visual indication of the filtering process.

import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { from } from 'rxjs/observable/from';
import { delay } from 'rxjs/operators/delay';
import { switchMap } from 'rxjs/operators/switchMap';
import { map } from 'rxjs/operators/map';
import { tap } from 'rxjs/operators/tap';

@Component({
  selector: 'my-app',
  template: `
    <kendo-combobox
        #list
        [data]="data"
        [filterable]="true"
        textField="text"
        valueField="value"
    >
    </kendo-combobox>
  `
})
export class AppComponent implements AfterViewInit {
    @ViewChild('list') list;

    public source: Array<{ text: string, value: number }> = [
        { text: 'Small', value: 1 },
        { text: 'Medium', value: 2 },
        { text: 'Large', value: 3 }
    ];

    public data: Array<{ text: string, value: number }>;

    constructor() {
        this.data = this.source.slice();
    }

    ngAfterViewInit() {
      const contains = value => s => s.text.toLowerCase().indexOf(value.toLowerCase()) !== -1;

      this.list.filterChange.asObservable().pipe(
            switchMap(value => from([this.source]).pipe(
                tap(() => this.list.loading = true),
                delay(1000),
                map((data) => data.filter(contains(value)))
            ))
        )
        .subscribe(x => {
            this.data = x;
            this.list.loading = false;
        });
    }

}

Server-Side Filtering

The following example demonstrates how to use the filter value to create the appropriate query string, required for filtering the data on the server.

import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { CategoriesService } from './categories.service';

@Component({
    providers: [CategoriesService],
    selector: 'my-app',
    template: `
        <div class="col-lg-4 col-sm-6 form-group">
          <div class="input-group">
        <kendo-combobox
        name="category" [data]="view | async"
          [loading]="service.loading"
          [valueField]="'CategoryID'"
          [textField]="'CategoryName'"
          [filterable]="true"
          (filterChange)="handleFilter($event)">
        </kendo-combobox>
          </div>
        </div>

  `
})
export class AppComponent {
    public  view: Observable<any>;

    constructor(private service: CategoriesService) {
        this.view = service;
    }

    public handleFilter(value) {
        this.service.query(value);
    }
}
import { Injectable } from '@angular/core';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs/BehaviorSubject ';
import { map } from 'rxjs/operators/map';
import { tap } from 'rxjs/operators/tap';

@Injectable()
export class CategoriesService extends BehaviorSubject<any> {
    private BASE_URL = 'https://odatasampleservices.azurewebsites.net/V4/Northwind/Northwind.svc/';
    private tableName = 'Categories';
    public loading = false;

    constructor(private http: HttpClient) {
        super(null);
    }

    public query(filter: string): void {
        this.fetch(this.tableName, filter)
            .subscribe(x => super.next(x));
    }

    private fetch(tableName: string, filter): any {
      this.loading = true;
      let queryStr;
        if (filter) {
          queryStr = `$filter=contains(CategoryName,'${filter}')&$skip=0&$count=true`;
        } else {
          queryStr = `$skip=0&$count=true`;
        }

        return this.http
            .get(`${this.BASE_URL}${tableName}?${queryStr}`)
            .pipe(
                map(response => response['value']),
                tap(() => this.loading = false));
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule, HttpClientJsonpModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
import { DropDownsModule } from '@progress/kendo-angular-dropdowns';

import { AppComponent } from './app.component';

@NgModule({
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    HttpClientModule,
    HttpClientJsonpModule,
    DropDownsModule
  ],
  declarations: [
    AppComponent
  ],
  bootstrap: [
    AppComponent
  ]
})
export class AppModule { }
import { AppModule } from './app.module';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Minimum Filter Length

The following example demonstrates how to update the data and open the drop-down list of the ComboBox only after typing a minimum number of characters.

import { Component, ViewChild } from '@angular/core';
import { ComboBoxComponent } from '@progress/kendo-angular-dropdowns';

@Component({
  selector: 'my-app',
  template: `
    <p>Focus the ComboBox and type minimum 3 characters, e.g. "sma"</p>
    <kendo-combobox
        #combo
        [data]="data"
        [textField]="'text'"
        [valueField]="'value'"
        [filterable]="true"
        (filterChange)="handleFilter($event)"
    >
    </kendo-combobox>
  `
})
class AppComponent {
    @ViewChild('combo') public combo: ComboBoxComponent;

    public source: Array<{ text: string, value: number }> = [
        { text: "Small", value: 1 },
        { text: "Medium", value: 2 },
        { text: "Large", value: 3 }
    ];

    public data: Array<{ text: string, value: number }>;

    constructor() {
        this.data = this.source.slice();
    }

    handleFilter(value) {
        if (value.length >= 3) {
            this.data = this.source.filter((s) => s.text.toLowerCase().indexOf(value.toLowerCase()) !== -1);
        } else {
            this.combo.toggle(false);
        }
    }
}

Built-in Directive

When the entire set of data is available on the client, you can use the built-in kendoDropDownFilter directive to filter the data on user input. To configure the kendoDropDownFilter directive, provide a DropDownFilterSettings object to it. DropDownFilterSettings enables you to set the case sensitivity of the performed search through the caseSensitive property and the search logic operator which provides the startsWith and contains options.

The provision of theDropDownFilterSettings configuration object is optional. By default, the kendoDropDownFilter directive performs a case-insensitive search with the startsWith operator.

import { Component } from '@angular/core';
import { DropDownFilterSettings } from '@progress/kendo-angular-dropdowns';

@Component({
  selector: 'my-app',
  template: `
    <div class="example-config">
        <input id="cs" type="checkbox" [(ngModel)]="filterSettings.caseSensitive">                 
        <label for="cs">Case-sensitive</label>
        <hr />
        <div>
            <input id="stw" type="radio" name="op" (click)="changeFilterOperator('startsWith')" checked>
            <label for="stw">StartsWith Operator</label>
        </div>
        <div>
            <input id="cnt" type="radio" name="op"(click)="changeFilterOperator('contains')">
            <label for="cnt">Contains Operator</label>
        </div>
    </div>

    <kendo-combobox
        [data]="data"
        [kendoDropDownFilter]="filterSettings"
        [textField]="'text'"
        [valueField]="'value'"
        [placeholder]="'T-shirt size'"
    >
    </kendo-combobox>
  `
})
class AppComponent {
    public data: Array<{ text: string, value: number }> = [
        { text: "Small", value: 1 },
        { text: "Medium", value: 2 },
        { text: "Large", value: 3 }
    ];

    public filterSettings: DropDownFilterSettings = {
        caseSensitive: false,
        operator: 'startsWith'
    };

    public changeFilterOperator(operator: string): void {
        this.filterSettings.operator = operator;
    }
}
In this article