import { Directive , ElementRef , HostListener , Inject , Input , Optional , Renderer2 } from "@angular/core" ; import { COMPOSITION_BUFFER_MODE , ControlValueAccessor , NG_VALUE_ACCESSOR } from "@angular/forms" ; @ Directive ( { selector : "input[trim], textarea[trim]" , providers : [ { provide : NG_VALUE_ACCESSOR , useExisting : InputTrimDirective , multi : true } ] } ) export class InputTrimDirective implements ControlValueAccessor { private get _type ( ) : string { return this . _sourceElementRef . nativeElement . type || "text" ; } @ Input ( ) trim : string ; type { string } private private _value : string ; private _sourceRenderer : Renderer2 ; private _sourceElementRef : ElementRef ; /**
     * Updates the value on the blur event.
     */ @ HostListener ( "blur" , [ "$event.type" , "$event.target.value" ] ) onBlur ( event , value ) { this . updateValue ( event , value . trim ( ) ) ; this . onTouched ( ) ; } /**
     * Updates the value on the input event.
     */ @ HostListener ( "input" , [ "$event.type" , "$event.target.value" ] ) onInput ( event , value ) { this . updateValue ( event , value ) ; } onChange = ( _ ) => { } ; onTouched = ( ) => { } ; constructor ( @ Inject ( Renderer2 ) renderer , @ Inject ( ElementRef ) elementRef , @ Optional ( ) @ Inject ( COMPOSITION_BUFFER_MODE ) compositionMode ) { this . _sourceRenderer = renderer ; this . _sourceElementRef = elementRef ; } registerOnChange ( fn ) { this . onChange = fn ; } registerOnTouched ( fn ) { this . onTouched = fn ; } param { any } value public writeValue ( value ) { this . _value = value === "" ? "" : value || null ; this . _sourceRenderer . setProperty ( this . _sourceElementRef . nativeElement , "value" , this . _value ) ; if ( this . _type !== "text" ) { this . _sourceRenderer . setAttribute ( this . _sourceElementRef . nativeElement , "value" , this . _value ) ; } } setDisabledState ( isDisabled ) { this . _sourceRenderer . setProperty ( this . _sourceElementRef . nativeElement , 'disabled' , isDisabled ) ; } param cursorPosition param hasTypedSymbol private setCursorPointer ( cursorPosition , hasTypedSymbol ) { if ( hasTypedSymbol && [ "text" , "search" , "url" , "tel" , "password" ] . indexOf ( this . _type ) >= 0 ) { this . _sourceElementRef . nativeElement . setSelectionRange ( cursorPosition , cursorPosition ) ; } } param { string } value param { string } event private updateValue ( event , value ) { value = this . trim !== "" && event !== this . trim ? value : value . trim ( ) ; const previous = this . _value ; const cursorPosition = this . _sourceElementRef . nativeElement . selectionStart ; this . writeValue ( value ) ; if ( ( this . _value || previous ) && this . _value . trim ( ) !== previous ) { this . onChange ( this . _value ) ; } const hasTypedSymbol = value && previous && value !== previous ; this . setCursorPointer ( cursorPosition , hasTypedSymbol ) ; } }