2017-11-23 11:40:02 +01:00
import { VisibilityRulesService } from '../../visibility-rules/visibility-rules.service' ;
import { VisibilityRuleSource } from '../../visibility-rules/models/VisibilityRuleSource' ;
import { Field } from '../../models/Field' ;
2017-09-14 12:37:36 +02:00
import { DataModel } from '../../entities/DataModel' ;
2017-09-22 13:38:53 +02:00
import { Component , Input , OnInit } from '@angular/core' ;
2017-10-05 14:42:44 +02:00
import { FormGroup , ValidatorFn , AbstractControl , Validators } from '@angular/forms' ;
2017-10-17 09:38:04 +02:00
import { ActivatedRoute } from '@angular/router' ;
2017-09-14 12:37:36 +02:00
2017-10-04 11:39:45 +02:00
import { FieldBase } from './field-base' ;
2017-09-18 18:08:15 +02:00
import { GroupBase } from '../../form/dynamic-form-group/group-base' ;
2017-09-22 13:38:53 +02:00
import { DropdownField } from '../../form/fields/dropdown/field-dropdown' ;
2017-10-04 11:39:45 +02:00
import { RuleStyle } from '../../entities/common/rulestyle' ;
2017-09-18 18:08:15 +02:00
2017-09-14 12:37:36 +02:00
@Component ( {
selector : 'df-field' ,
2017-11-07 09:04:59 +01:00
templateUrl : './dynamic-form-field.component.html' ,
2017-11-20 09:46:09 +01:00
styles : [ '.checkBoxLabelCustom {font-weight: 700;}' ]
2017-09-14 12:37:36 +02:00
} )
export class DynamicFormFieldComponent {
@Input ( ) dataModel : DataModel ;
2017-11-23 11:40:02 +01:00
@Input ( ) field : Field ;
2017-09-14 12:37:36 +02:00
@Input ( ) form : FormGroup ;
2017-11-23 11:40:02 +01:00
@Input ( ) pathName :string ;
2017-10-10 16:10:00 +02:00
private fragment : string ;
2017-11-23 11:40:02 +01:00
constructor ( private route : ActivatedRoute , private visibilityRulesService :VisibilityRulesService ) { }
2017-10-17 09:38:04 +02:00
2017-11-03 18:14:32 +01:00
ngOnChanges ( changeRecord ) {
}
2017-10-10 16:10:00 +02:00
2017-10-04 11:39:45 +02:00
get isValid() {
2017-11-23 11:40:02 +01:00
return this . form . get ( "value" ) . valid ;
2017-10-04 11:39:45 +02:00
}
get isValidRequired() {
2017-11-23 11:40:02 +01:00
return this . form . get ( "value" ) . hasError ( "required" ) ;
2017-10-04 11:39:45 +02:00
}
get isValidPattern() {
2017-11-23 11:40:02 +01:00
return this . form . get ( "value" ) . hasError ( "pattern" ) ;
2017-10-04 11:39:45 +02:00
}
get isValidCustom() {
2017-11-23 11:40:02 +01:00
return this . form . get ( "value" ) . hasError ( "forbiddenName" ) ;
2017-09-14 12:37:36 +02:00
}
2017-11-23 11:40:02 +01:00
public ngOnInit() {
2017-10-10 16:10:00 +02:00
this . route . fragment . subscribe ( fragment = > { this . fragment = fragment ; } ) ; //navigate to certain section of the page
2017-09-22 13:38:53 +02:00
}
2017-09-14 12:37:36 +02:00
2017-10-10 16:10:00 +02:00
ngAfterViewChecked ( ) : void { //navigate to certain section of the page
try {
2017-10-17 09:38:04 +02:00
document . querySelector ( '#' + this . fragment ) . scrollIntoView ( ) ;
2017-10-10 16:10:00 +02:00
} catch ( e ) { }
2017-10-17 09:38:04 +02:00
}
2017-10-04 11:39:45 +02:00
ruleVisibleMethod ( field , rule , dataModel ) { //visibility rule -- checks if target field is visible
2017-09-14 12:37:36 +02:00
dataModel . fields . forEach ( fld = > {
if ( fld . label == rule . _target && fld . visible == true )
field . visible = true ;
} ) ;
2017-10-04 11:39:45 +02:00
if ( field . visible == true )
2017-09-14 12:37:36 +02:00
return true ;
2017-10-04 11:39:45 +02:00
}
2017-11-20 09:46:09 +01:00
FieldValueRuleMethod ( field , rule , targetField ) { //fieldValue rule -- checks the value of target and apply rules, at the same time when the field becomes visible /calling the AddvalidationRules we apply the validation rules for the new field
2017-11-03 18:14:32 +01:00
var fieldValue = this . form . get ( field . key ) . value ; //to do: change field.value
2017-10-17 09:38:04 +02:00
if ( rule . _ruleStyle == "range" ) {
if ( parseInt ( rule . _from ) < parseInt ( field . value ) && parseInt ( field . value ) < parseInt ( rule . _to ) ) {
2017-10-13 10:13:52 +02:00
console . log ( "visible" + field . value )
targetField . visible = true ;
2017-11-20 09:46:09 +01:00
this . AddvalidationRules ( targetField ) ;
2017-10-17 09:38:04 +02:00
} else {
this . hideField ( targetField , rule ) ;
2017-10-13 10:13:52 +02:00
}
2017-10-04 11:39:45 +02:00
2017-09-18 12:18:17 +02:00
}
2017-11-03 18:14:32 +01:00
if ( rule . _ruleStyle == "boolean" && field . value !== undefined ) { //boolean Decision field
2017-10-04 11:39:45 +02:00
let ruleValue = rule . value . __text ;
2017-11-03 18:14:32 +01:00
if ( field . value . toString ( ) == ruleValue ) { //field.value.value.toString() == ruleValue
2017-10-17 09:38:04 +02:00
targetField . visible = true ;
2017-11-20 09:46:09 +01:00
this . AddvalidationRules ( targetField ) ;
2017-10-04 11:39:45 +02:00
} else {
2017-10-17 09:38:04 +02:00
this . hideField ( targetField , rule ) ;
2017-09-19 12:48:00 +02:00
}
}
2017-11-07 09:04:59 +01:00
if ( rule . _ruleStyle == "checked" ) { //checkbox field
2017-10-04 11:39:45 +02:00
if ( field . value == true ) {
2017-10-17 09:38:04 +02:00
targetField . visible = true ;
2017-11-20 09:46:09 +01:00
this . AddvalidationRules ( targetField ) ;
2017-10-04 11:39:45 +02:00
} else {
2017-10-17 09:38:04 +02:00
this . hideField ( targetField , rule ) ;
2017-09-19 12:48:00 +02:00
}
}
2017-11-07 09:04:59 +01:00
if ( rule . _ruleStyle == "unchecked" ) { //checkbox field
2017-11-20 09:46:09 +01:00
if ( field . value !== "" ) {
2017-11-07 09:04:59 +01:00
if ( field . value == false ) {
targetField . visible = true ;
2017-11-20 09:46:09 +01:00
this . AddvalidationRules ( targetField ) ;
2017-11-07 09:04:59 +01:00
} else {
this . hideField ( targetField , rule ) ;
}
}
2017-11-20 09:46:09 +01:00
2017-11-07 09:04:59 +01:00
}
2017-10-17 09:38:04 +02:00
if ( rule . _ruleStyle == "existence" ) {
2017-10-04 15:30:38 +02:00
if ( field . visible == "true" || field . visible == true ) {
2017-10-17 09:38:04 +02:00
targetField . visible = true ;
2017-11-20 09:46:09 +01:00
this . AddvalidationRules ( targetField ) ;
2017-10-04 15:30:38 +02:00
} else {
2017-10-17 09:38:04 +02:00
this . hideField ( targetField , rule ) ;
2017-10-04 15:30:38 +02:00
}
}
2017-10-17 09:38:04 +02:00
if ( rule . _ruleStyle == "regex" ) {
2017-10-04 15:30:38 +02:00
if ( new RegExp ( rule . __cdata ) . test ( field . value ) ) {
2017-10-17 09:38:04 +02:00
targetField . visible = true ;
2017-11-20 09:46:09 +01:00
this . AddvalidationRules ( targetField ) ;
2017-10-04 15:30:38 +02:00
} else {
2017-10-17 09:38:04 +02:00
this . hideField ( targetField , rule ) ;
2017-10-04 15:30:38 +02:00
}
}
2017-11-20 09:46:09 +01:00
if ( rule . _ruleStyle == "dropdownValue" ) { //dropdown field
2017-11-08 14:54:22 +01:00
let fieldValue = this . form . get ( field . key ) . value ;
let ruleValue ;
2017-11-20 09:46:09 +01:00
let ruleValueBoolean = false ;
2017-11-08 14:54:22 +01:00
if ( rule . value . length )
rule . value . forEach ( value = > {
2017-11-20 09:46:09 +01:00
if ( fieldValue . toString ( ) == value . __text )
ruleValueBoolean = true ;
2017-11-08 14:54:22 +01:00
return ;
} ) ;
else
ruleValue = rule . value . __text ;
if ( fieldValue . toString ( ) == ruleValue || ruleValueBoolean . valueOf ( ) == true ) { //field.value.value.toString() == ruleValue
targetField . visible = true ;
2017-11-20 09:46:09 +01:00
this . AddvalidationRules ( targetField ) ;
2017-11-08 14:54:22 +01:00
} else {
this . hideField ( targetField , rule ) ;
}
}
2017-10-04 11:39:45 +02:00
}
2017-09-18 12:18:17 +02:00
2017-10-17 09:38:04 +02:00
hideField ( targetField , rule ) {
targetField . visible = false ;
targetField . value = ' ' ;
2017-11-20 09:46:09 +01:00
if ( this . form . controls [ targetField . key ] . hasError ( "pattern" ) )
this . form . controls [ targetField . key ] . reset ( ) ; //the regex error message didn't remove without field reset
this . form . controls [ targetField . key ] . clearValidators ( ) ; // when a field is hidden must clear the validators and the errors
this . form . controls [ targetField . key ] . updateValueAndValidity ( ) ;
}
findTargetField ( field , rule ) {
// var targetField = this.dataModel.getFieldByKey(rule._target);
let targetFields = new Array ( ) ;
if ( this . dataModel . getFieldByKey ( rule . _target ) == undefined ) {
this . dataModel . groups . forEach ( gr = > {
if ( gr . key == rule . _target ) {
gr . groupFields . forEach ( field = > {
targetFields . push ( field ) ;
} ) ;
if ( gr . compositeFields )
gr . compositeFields . groupFields . forEach ( field = > {
targetFields . push ( field ) ;
} ) ;
}
} )
} else {
targetFields . push ( this . dataModel . getFieldByKey ( rule . _target ) ) ;
}
return targetFields ;
2017-10-17 09:38:04 +02:00
}
2017-10-04 11:39:45 +02:00
toggleVisibility ( e , field , ckb ) { //ckb the checkbox only send this parameter, it's essential to change the field value
2017-11-20 09:46:09 +01:00
if ( ckb ) {
if ( e ) this . form . get ( field . key ) . patchValue ( e . target . checked )
2017-11-03 18:14:32 +01:00
field . value = this . form . get ( field . key ) . value ;
2017-11-20 09:46:09 +01:00
}
2017-10-17 09:38:04 +02:00
if ( field . rules . length != undefined && field . rules . length > 1 )
2017-10-04 15:30:38 +02:00
field . rules . forEach ( rule = > {
if ( rule . _type == "fieldValue" ) {
2017-11-20 09:46:09 +01:00
let targetFieldsArray = this . findTargetField ( field , rule ) ;
targetFieldsArray . forEach ( targetField = > {
this . FieldValueRuleMethod ( field , rule , targetField ) ;
} )
2017-10-04 15:30:38 +02:00
}
} ) ;
2017-10-17 09:38:04 +02:00
else if ( field . rules . _type == "fieldValue" ) {
2017-11-20 09:46:09 +01:00
let targetFieldsArray = this . findTargetField ( field , field . rules ) ;
targetFieldsArray . forEach ( targetField = > {
this . FieldValueRuleMethod ( field , field . rules , targetField ) ;
} )
2017-10-04 15:30:38 +02:00
}
2017-10-04 11:39:45 +02:00
}
2017-09-18 12:18:17 +02:00
2017-10-04 11:39:45 +02:00
AddvalidationRules ( field ) {
2017-11-20 09:46:09 +01:00
if ( this . dataModel . getFieldByKey ( field . key ) . attributes . validation != undefined ) {
2017-10-05 14:42:44 +02:00
let arrayVal = new Array ( ) ;
2017-11-20 09:46:09 +01:00
this . dataModel . getFieldByKey ( field . key ) . attributes . validation . forEach ( rule = > {
2017-10-17 09:38:04 +02:00
if ( rule . ruleStyle . toString ( ) == RuleStyle [ RuleStyle . existence ] ) {
2017-11-20 09:46:09 +01:00
this . dataModel . getFieldByKey ( field . key ) . required = true ;
2017-10-17 09:38:04 +02:00
arrayVal . push ( Validators . required ) ;
}
if ( rule . ruleStyle . toString ( ) == RuleStyle [ RuleStyle . regex ] ) {
2017-11-20 09:46:09 +01:00
this . dataModel . getFieldByKey ( field . key ) . regex = rule . regex ;
2017-10-17 09:38:04 +02:00
arrayVal . push ( Validators . pattern ( rule . regex ) ) ;
}
if ( rule . ruleStyle . toString ( ) == RuleStyle [ RuleStyle . customValidation ] ) {
arrayVal . push ( this . forbiddenNameValidator ( /nothing/i ) ) ;
2017-10-05 14:42:44 +02:00
}
2017-10-17 09:38:04 +02:00
2017-10-04 11:39:45 +02:00
} ) ;
2017-11-20 09:46:09 +01:00
this . form . controls [ field . key ] . setValidators ( arrayVal ) ; //Multiple Validators, Usage of array because setValidator override any validators that are provided during initialistaion
this . form . controls [ field . key ] . updateValueAndValidity ( ) ; //hide--> visible must update the validators
2017-10-17 09:38:04 +02:00
2017-10-04 11:39:45 +02:00
}
}
forbiddenNameValidator ( nameRe : RegExp ) : ValidatorFn {
return ( control : AbstractControl ) : { [ key : string ] : any } = > {
const forbidden = nameRe . test ( control . value ) ;
return forbidden ? { 'forbiddenName' : { value : control.value } } : null ;
} ;
}
2017-10-17 09:38:04 +02:00
2017-11-03 18:14:32 +01:00
2017-09-14 12:37:36 +02:00
}