import { Directive , ElementRef , Input , OnInit , Renderer2 , HostBinding , OnDestroy , NgZone , Inject } from '@angular/core' ; import { UpdateHostClassService } from 'ngx-tethys/core' ; import { NgForm } from '@angular/forms' ; import { keycodes } from 'ngx-tethys/util' ; import { ThyFormLayout , ThyFormValidatorConfig , ThyFormConfig , THY_FORM_CONFIG } from './form.class' ; import { ThyFormValidatorService } from './form-validator.service' ; import { coerceBooleanProperty } from 'ngx-tethys/util' ; export enum ThyEnterKeyMode { submit = 'submit' , alwaysSubmit = 'alwaysSubmit' , forbidSubmit = 'forbidSubmit' } @ Directive ( { selector : '[thyForm],[thy-form]' , providers : [ UpdateHostClassService , ThyFormValidatorService ] , exportAs : 'thyForm' , host : { class : 'thy-form' } } ) export class ThyFormDirective implements OnInit , OnDestroy { private layout : ThyFormLayout ; private initialized = false ; @ Input ( ) set thyLayout ( value ) { if ( value ) { this . layout = value ; if ( this . initialized ) { this . updateClasses ( ) ; } } } get thyLayout ( ) : ThyFormLayout { return this . layout ; } get isHorizontal ( ) { return this . layout === 'horizontal' ; } @ Input ( ) thyEnterKeyMode : ThyEnterKeyMode ; @ Input ( ) set thyFormValidatorConfig ( config ) { this . validator . setValidatorConfig ( config ) ; } @ HostBinding ( 'class.was-validated' ) wasValidated = false ; onSubmitSuccess : ( $event : any ) => void ; private _unsubscribe : ( ) => void ; constructor ( private ngForm , private elementRef , private renderer , private ngZone , private updateHostClassService , public validator , @ Inject ( THY_FORM_CONFIG ) private config ) { this . updateHostClassService . initializeElement ( this . elementRef . nativeElement ) ; this . layout = this . config . layout ; } ngOnInit ( ) { this . ngZone . runOutsideAngular ( ( ) => { this . _unsubscribe = this . renderer . listen ( this . elementRef . nativeElement , 'keydown' , this . onKeydown . bind ( this ) ) ; } ) ; this . updateClasses ( ) ; this . initialized = true ; this . validator . initialize ( this . ngForm , this . elementRef . nativeElement ) ; } submit ( $event ) { if ( this . validator . validate ( $event ) ) { this . onSubmitSuccess ( $event ) ; } else { } } updateClasses ( ) { this . updateHostClassService . updateClassByMap ( { [ `thy-form-${ this . thyLayout }` ] : true } ) ; } submitRunInZone ( $event ) { this . ngZone . run ( ( ) => { this . submit ( $event ) ; } ) ; } onKeydown ( $event ) { const currentInput = document . activeElement ; const key = $event . which || $event . keyCode ; if ( key === keycodes . ENTER && currentInput . tagName ) { if ( ! this . thyEnterKeyMode || this . thyEnterKeyMode === ThyEnterKeyMode . submit ) { if ( currentInput . tagName === 'TEXTAREA' || coerceBooleanProperty ( currentInput . getAttribute ( 'contenteditable' ) ) ) { if ( $event . ctrlKey || $event . metaKey ) { $event . preventDefault ( ) ; this . submitRunInZone ( $event ) ; } } else { $event . preventDefault ( ) ; this . submitRunInZone ( $event ) ; } } else if ( this . thyEnterKeyMode === ThyEnterKeyMode . alwaysSubmit ) { $event . preventDefault ( ) ; this . submitRunInZone ( $event ) ; } else { } } } ngOnDestroy ( ) { if ( this . _unsubscribe ) { this . _unsubscribe ( ) ; this . _unsubscribe = null ; } } }