import { Directive , ElementRef , forwardRef , HostListener , Provider , Renderer2 } from '@angular/core' ; import { ControlValueAccessor , NG_VALUE_ACCESSOR } from '@angular/forms' ; import { undefinedToNull } from '../util' ; ignore const NGQP_SELECT_VALUE_ACCESSOR = { provide : NG_VALUE_ACCESSOR , useExisting : forwardRef ( ( ) => SelectControlValueAccessorDirective ) , multi : true } ; ignore @ Directive ( { selector : 'select:not([multiple])[queryParamName],select:not([multiple])[queryParam]' , providers : [ NGQP_SELECT_VALUE_ACCESSOR ] , } ) export class SelectControlValueAccessorDirective < T > implements ControlValueAccessor { public value : T | null = null ; private selectedId : string | null = null ; private optionMap = new Map < string , T > ( ) ; private idCounter = 0 ; private fnChange = ( _ ) => { } ; private fnTouched = ( ) => { } ; @ HostListener ( 'change' , [ '$event' ] ) public onChange ( event ) { this . selectedId = ( event . target as HTMLOptionElement ) . value ; this . value = undefinedToNull ( this . optionMap . get ( this . selectedId ) ) ; this . fnChange ( this . value ) ; } @ HostListener ( 'blur' ) public onTouched ( ) { this . fnTouched ( ) ; } constructor ( private renderer , private elementRef ) { } public writeValue ( value ) { this . value = value ; this . selectedId = value === null ? null : this . getOptionId ( value ) ; if ( this . selectedId === null ) { this . renderer . setProperty ( this . elementRef . nativeElement , 'selectedIndex' , - 1 ) ; } this . renderer . setProperty ( this . elementRef . nativeElement , 'value' , this . selectedId ) ; } public registerOnChange ( fn ) { this . fnChange = fn ; } public registerOnTouched ( fn ) { this . fnTouched = fn ; } public setDisabledState ( isDisabled ) { this . renderer . setProperty ( this . elementRef . nativeElement , 'disabled' , isDisabled ) ; } public registerOption ( ) { return ( this . idCounter ++ ) . toString ( ) ; } public deregisterOption ( id ) { this . optionMap . delete ( id ) ; } public updateOptionValue ( id , value ) { this . optionMap . set ( id , value ) ; if ( this . selectedId === id ) { this . fnChange ( value ) ; } } private getOptionId ( value ) { for ( const id of Array . from ( this . optionMap . keys ( ) ) ) { if ( this . optionMap . get ( id ) === value ) { return id ; } } return null ; } }