import { getLocaleNumberSymbol , NumberSymbol } from '@angular/common' ; import { Directive , ElementRef , Inject , Input , LOCALE_ID , OnInit } from '@angular/core' ; import { ControlValueAccessor , NG_VALUE_ACCESSOR } from '@angular/forms' ; import 'inputmask/lib/extensions/inputmask.numeric.extensions' ; import Inputmask from 'inputmask/lib/inputmask' ; interface InputMask { unmaskedvalue : ( ) => string ; setValue : ( val : string ) => void ; } @ Directive ( { selector : '[kirby-decimal-mask]' , providers : [ { provide : NG_VALUE_ACCESSOR , multi : true , useExisting : DecimalMaskDirective , } , ] , } ) export class DecimalMaskDirective implements ControlValueAccessor , OnInit { @ Input ( ) min : number ; @ Input ( ) max : number ; @ Input ( ) precision = 2 ; @ Input ( ) setMaxOnOverflow = false ; @ Input ( ) set allowMinus ( allowMinus ) { this . _allowMinus = allowMinus || ( this . min || 0 ) < 0 ; } @ Input ( ) set disableGroupSeperator ( disabled ) { this . _groupSeperatorDisabled = String ( disabled ) === '' || String ( disabled ) === 'true' ; } @ Input ( ) set maxlength ( maxlength ) { this . _maxlength = maxlength ; const maxlengthValue = parseInt ( '9' . repeat ( maxlength ) ) ; this . max = this . getMax ( maxlengthValue ) ; this . min = this . getMin ( maxlengthValue ) ; } groupSeparator = getLocaleNumberSymbol ( this . locale , NumberSymbol . Group ) ; radixPoint = getLocaleNumberSymbol ( this . locale , NumberSymbol . Decimal ) ; inputmask : InputMask ; _allowMinus = false ; _maxlength : number ; _groupSeperatorDisabled : boolean ; onChange = ( _ ) => { } ; constructor ( private elementRef , @ Inject ( LOCALE_ID ) private locale ) { } ngOnInit ( ) { this . elementRef . nativeElement . setAttribute ( 'type' , 'text' ) ; this . elementRef . nativeElement . removeAttribute ( 'maxlength' ) ; this . initMask ( ) ; } writeValue ( val ) { if ( ! this . inputmask ) return ; const formattedValue = String ( val ) . replace ( '.' , this . radixPoint ) ; this . inputmask . setValue ( formattedValue ) ; } registerOnChange ( onChange ) { this . onChange = onChange ; } registerOnTouched ( _ ) { } private initMask ( ) { new Inputmask ( 'decimal' , { groupSeparator : this . _groupSeperatorDisabled ? '' : this . groupSeparator , radixPoint : this . radixPoint , digits : this . _maxlength ? 0 : this . precision , min : this . min , max : this . max , allowMinus : this . _allowMinus , negationSymbol : { front : getLocaleNumberSymbol ( this . locale , NumberSymbol . MinusSign ) , back : '' , } , SetMaxOnOverflow : this . setMaxOnOverflow , showMaskOnFocus : false , showMaskOnHover : false , placeholder : '' , onBeforeWrite : ( ) => { if ( ! this . inputmask ) return ; const unmaskedValue = this . inputmask . unmaskedvalue ( ) ; this . onChange ( unmaskedValue . replace ( this . radixPoint , '.' ) ) ; } , } ) . mask ( this . elementRef . nativeElement ) ; this . inputmask = this . elementRef . nativeElement . inputmask ; } private getMax ( maxlengthValue ) { return this . max === undefined ? maxlengthValue : Math . min ( this . max , maxlengthValue ) ; } private getMin ( maxlengthValue ) { if ( ! this . allowMinus ) return ; maxlengthValue = - Math . abs ( maxlengthValue ) ; return this . min === undefined ? maxlengthValue : - Math . abs ( Math . max ( this . min , maxlengthValue ) ) ; } }