import { AfterViewChecked , ChangeDetectorRef , Component , ElementRef , EventEmitter , Input , OnInit , Output , QueryList , SimpleChanges , TemplateRef , ViewChild , ViewChildren } from '@angular/core' ; import { AutocompleteGroup } from './classes/AutocompleteGroup' ; import { SelectedAutocompleteItem } from './classes/typing' ; import { CompleterComponent } from './completer/completer.component' ; import { GroupNoResult , ReturnStringArrayByID } from './utils/utils' ; import { Subject } from 'rxjs' ; @ Component ( { selector : 'ng-auto-complete' , template : `
        <div #init style="display: none;"><span class="after-view-init"></span></div>
        <ng-completer [ngClass]="classes" *ngFor="let item of group" (cleared)="InputCleared($event)"
                      (no-result)="NoResult($event)"
                      (selected)="ListenToSelected($event)"
                      [group]="item"></ng-completer>
    ` , } ) export class NgAutoCompleteComponent implements OnInit , AfterViewChecked { @ ViewChildren ( CompleterComponent ) public completers : QueryList < CompleterComponent > ; @ ViewChild ( 'init' , { static : true } ) public init : ElementRef ; @ Output ( ) public selected : EventEmitter < SelectedAutocompleteItem > = new EventEmitter < SelectedAutocompleteItem > ( ) ; @ Output ( 'no-result' ) public noResult : EventEmitter < GroupNoResult > = new EventEmitter < GroupNoResult > ( ) ; @ Input ( ) public group : AutocompleteGroup [ ] = [ ] ; @ Input ( ) public key = '' ; @ Input ( ) public classes : string [ ] = [ ] ; _viewHasBeenInit = false ; _viewInitSubject : Subject < boolean > = new Subject < boolean > ( ) ; constructor ( private cdr ) { } /**
     *
     */ static FindCompleter ( key , list ) { const completer = list . filter ( ( c ) => { return key === c . key ; } ) ; if ( typeof completer [ 0 ] !== 'undefined' ) { return completer [ 0 ] ; } return null ; } /**
     *
     */ ngOnInit ( ) { } /**
     *
     */ ngAfterViewChecked ( ) { if ( ! this . _viewHasBeenInit ) { const el = this . init . nativeElement . querySelector ( '.after-view-init' ) ; if ( window . getComputedStyle ( el ) . length > 0 ) { this . _viewHasBeenInit = true ; this . _viewInitSubject . next ( true ) ; } } } /**
     *
     */ ListenToSelected ( selected ) { this . selected . emit ( selected ) ; /**
         *
         */ this . SetChildren ( selected ) ; } /**
     *
     */ NoResult ( group ) { this . noResult . emit ( group ) ; } /**
     *
     */ InputCleared ( key ) { this . group . forEach ( ( group ) => { if ( group . key === key || group . parent === key ) { this . ResetInput ( group . key ) ; } } ) ; /**
         * Items may have changed, need to te re-set list in completer components.
         */ this . TriggerChange ( ) ; } /**
     *
     */ SetChildren ( selected ) { this . group . forEach ( ( item ) => { if ( item . parent === selected . group . key ) { this . ResetInput ( item . key ) ; /**
                 *
                 */ if ( selected . item !== null && typeof selected . item . children !== 'undefined' ) { item . SetNewValue ( selected . item . children , selected . group . keys . titleKey ) ; } } } ) ; /**
         * Items may have changed, need to te re-set list in completer components.
         */ this . TriggerChange ( ) ; } /**
     *
     */ TriggerChange ( ) { this . completers . forEach ( ( completer ) => { completer . SetItems ( ) ; } ) ; } /**
     *
     */ GetInput ( key ) { return this . completers . reduce ( ( result , completer ) => { if ( completer . group . key === key ) { result = completer ; } return result ; } , < CompleterComponent > { } ) ; } /**
     *
     */ SubscribeInput ( key , f ) { if ( this . _viewHasBeenInit ) { const completer = this . GetInput ( key ) ; /**
             *
             */ f ( completer ) ; return ; } this . _viewInitSubject . subscribe ( ( _bool ) => { const completer = this . GetInput ( key ) ; setTimeout ( ( ) => { f ( completer ) ; } ) ; this . _viewInitSubject . unsubscribe ( ) ; } ) ; } /**
     *
     */ ResetInput ( key ) { this . SubscribeInput ( key , ( completer ) => { completer . ClearValue ( ) ; } ) ; } /**
     *
     */ SetValues ( key , values ) { this . SubscribeInput ( key , ( completer ) => { completer . group . SetValues ( values ) ; /**
             * Items may have changed, need to te re-set list in completer components.
             */ this . TriggerChange ( ) ; } ) ; } /**
     *
     */ SetTemplate ( key , type , template ) { this . SubscribeInput ( key , ( completer ) => { completer . group [ type ] = template ; /**
             * Items may have changed, need to te re-set list in completer components.
             */ this . TriggerChange ( ) ; } ) ; } /**
     *
     */ SetAsync ( key , promise ) { this . SubscribeInput ( key , ( completer ) => { completer . group . async = promise ; /**
             * Items may have changed, need to te re-set list in completer components.
             */ this . TriggerChange ( ) ; } ) ; } /**
     *
     */ SetEnable ( key ) { this . SubscribeInput ( key , ( completer ) => { completer . _disabled = false ; /**
             * Items may have changed, need to te re-set list in completer components.
             */ this . TriggerChange ( ) ; } ) ; } /**
     *
     */ SetDisable ( key ) { this . SubscribeInput ( key , ( completer ) => { completer . _disabled = true ; /**
             * Items may have changed, need to te re-set list in completer components.
             */ this . TriggerChange ( ) ; } ) ; } /**
     *
     */ SelectItem ( key , id ) { this . SubscribeInput ( key , ( completer ) => { Object . keys ( completer . _items ) . forEach ( ( k ) => { const f = `_id_${ String ( id ) }` ; const c = k . substring ( k . indexOf ( f ) , k . length ) ; if ( f === c ) { completer . SelectItem ( completer . _items [ k ] ) ; } } ) ; } ) ; } /**
     *
     */ RemovableValues ( key , ids ) { this . SubscribeInput ( key , ( completer ) => { completer . group . Removables ( ReturnStringArrayByID ( ids ) ) ; /**
             * Items may have changed, need to te re-set list in completer components.
             */ this . TriggerChange ( ) ; } ) ; } /**
     *
     */ ResetInputs ( ) { this . group . forEach ( ( item ) => { this . ResetInput ( item . key ) ; } ) ; } }