import { Component , OnDestroy , OnInit } from '@angular/core' ; import { BehaviorSubject , Subject } from 'rxjs' ; import { distinctUntilChanged , takeUntil } from 'rxjs/operators' ; @ Component ( { selector : 'app' , templateUrl : './app.component.html' , styleUrls : [ './app.component.css' ] } ) export class AppComponent implements OnInit , OnDestroy { options : string [ ] | Function ; display : string = null ; key : string = null ; selected : string | string [ ] ; multiple = new BehaviorSubject < boolean > ( false ) ; allowNull = false ; disabled = false ; dropDirection = 'down' ; dropdownOpen : boolean ; maxHeight : string = '250px' ; placeholder = 'Select a country' ; readonlyInput : boolean = false ; clearButton : boolean = false ; recentOptions : ReadonlyArray < string > ; recentOptionsMaxCount : number = 5 ; private _pageSize = 20 ; private _onDestroy = new Subject < void > ( ) ; get pageSize ( ) { return this . _pageSize ; } set pageSize ( value ) { const numValue = Number ( value ) ; this . _pageSize = ( numValue >= 1 ) ? numValue : 1 ; } pagingEnabled = new BehaviorSubject < boolean > ( false ) ; dataSet = new BehaviorSubject < string > ( 'strings' ) ; loadOptionsCallback = this . loadOptions . bind ( this ) ; dataSets : { strings ? : any [ ] ; objects ? : any [ ] ; } = { } ; constructor ( ) { this . multiple . pipe ( distinctUntilChanged ( ) , takeUntil ( this . _onDestroy ) ) . subscribe ( ( value ) => { this . selected = null ; this . dropdownOpen = false ; } ) ; this . pagingEnabled . pipe ( distinctUntilChanged ( ) , takeUntil ( this . _onDestroy ) ) . subscribe ( ( value ) => { this . selected = null ; this . dropdownOpen = false ; this . options = this . pagingEnabled . getValue ( ) ? this . loadOptionsCallback : this . selectedDataSet ( ) ; } ) ; this . dataSet . pipe ( distinctUntilChanged ( ) , takeUntil ( this . _onDestroy ) ) . subscribe ( ( value ) => { if ( this . multiple . getValue ( ) === true ) { this . pagingEnabled . next ( false ) ; } this . selected = null ; this . dropdownOpen = false ; this . options = this . pagingEnabled . getValue ( ) ? this . loadOptionsCallback : this . selectedDataSet ( ) ; this . display = ( value === 'objects' ) ? 'name' : null ; this . key = ( value === 'objects' ) ? 'id' : null ; } ) ; this . dataSets . strings = [ 'United States' , 'United Kingdom' , ... ] ; this . dataSets . objects = this . dataSets . strings . map ( ( option , i ) => { return { id : i , name : option } ; } ) ; } ngOnInit ( ) { this . options = this . selectedDataSet ( ) ; } ngOnDestroy ( ) { this . _onDestroy . next ( ) ; this . _onDestroy . complete ( ) ; } selectedDataSet ( ) { return this . dataSets [ this . dataSet . getValue ( ) ] ; } loadOptions ( pageNum , pageSize , filter ) { let promise = new Promise < any [ ] > ( ( resolve , reject ) => { setTimeout ( ( ) => { const pageStart = pageNum * pageSize ; const newItems = this . selectedDataSet ( ) . filter ( ( option ) => this . isFilterMatch ( option , filter ) ) . slice ( pageStart , pageStart + pageSize ) ; resolve ( newItems ) ; } , 2000 ) ; } ) ; return promise ; } isFilterMatch ( option , filter ) { if ( ! filter ) { return true ; } if ( typeof option === 'string' ) { return option . toLowerCase ( ) . indexOf ( filter . toLowerCase ( ) ) >= 0 ; } else { return option . name . toLowerCase ( ) . indexOf ( filter . toLowerCase ( ) ) >= 0 ; } } } export interface FilterOption { id : string ; name : string ; }