import { VisibilityRulesService } from '../../visibility-rules/visibility-rules.service'; import { VisibilityRuleSource } from '../../visibility-rules/models/VisibilityRuleSource'; import { Field } from '../../models/Field'; import { DataModel } from '../../entities/DataModel'; import { Component, Input, OnInit } from '@angular/core'; import { FormGroup, ValidatorFn, AbstractControl, Validators } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { FieldBase } from './field-base'; import { GroupBase } from '../../form/dynamic-form-group/group-base'; import { DropdownField } from '../../form/fields/dropdown/field-dropdown'; import { RuleStyle } from '../../entities/common/rulestyle'; @Component({ selector: 'df-field', templateUrl: './dynamic-form-field.component.html', styles: ['.checkBoxLabelCustom {font-weight: 700;}'] }) export class DynamicFormFieldComponent { @Input() dataModel: DataModel; @Input() field: Field; @Input() form: FormGroup; @Input() pathName:string; private fragment: string; constructor(private route: ActivatedRoute,private visibilityRulesService:VisibilityRulesService) { } ngOnChanges(changeRecord) { } get isValid() { return this.form.get("value").valid; } get isValidRequired() { return this.form.get("value").hasError("required"); } get isValidPattern() { return this.form.get("value").hasError("pattern"); } get isValidCustom() { return this.form.get("value").hasError("forbiddenName"); } public ngOnInit() { this.route.fragment.subscribe(fragment => { this.fragment = fragment; }); //navigate to certain section of the page } ngAfterViewChecked(): void { //navigate to certain section of the page try { document.querySelector('#' + this.fragment).scrollIntoView(); } catch (e) { } } ruleVisibleMethod(field, rule, dataModel) { //visibility rule -- checks if target field is visible dataModel.fields.forEach(fld => { if (fld.label == rule._target && fld.visible == true) field.visible = true; }); if (field.visible == true) return true; } 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 var fieldValue = this.form.get(field.key).value;//to do: change field.value if (rule._ruleStyle == "range") { if (parseInt(rule._from) < parseInt(field.value) && parseInt(field.value) < parseInt(rule._to)) { console.log("visible" + field.value) targetField.visible = true; this.AddvalidationRules(targetField); } else { this.hideField(targetField, rule); } } if (rule._ruleStyle == "boolean" && field.value !== undefined) { //boolean Decision field let ruleValue = rule.value.__text; if (field.value.toString() == ruleValue) { //field.value.value.toString() == ruleValue targetField.visible = true; this.AddvalidationRules(targetField); } else { this.hideField(targetField, rule); } } if (rule._ruleStyle == "checked") { //checkbox field if (field.value == true) { targetField.visible = true; this.AddvalidationRules(targetField); } else { this.hideField(targetField, rule); } } if (rule._ruleStyle == "unchecked") { //checkbox field if (field.value !== "") { if (field.value == false) { targetField.visible = true; this.AddvalidationRules(targetField); } else { this.hideField(targetField, rule); } } } if (rule._ruleStyle == "existence") { if (field.visible == "true" || field.visible == true) { targetField.visible = true; this.AddvalidationRules(targetField); } else { this.hideField(targetField, rule); } } if (rule._ruleStyle == "regex") { if (new RegExp(rule.__cdata).test(field.value)) { targetField.visible = true; this.AddvalidationRules(targetField); } else { this.hideField(targetField, rule); } } if (rule._ruleStyle == "dropdownValue") { //dropdown field let fieldValue = this.form.get(field.key).value; let ruleValue; let ruleValueBoolean = false; if (rule.value.length) rule.value.forEach(value => { if (fieldValue.toString() == value.__text) ruleValueBoolean = true; return; }); else ruleValue = rule.value.__text; if (fieldValue.toString() == ruleValue || ruleValueBoolean.valueOf() == true) { //field.value.value.toString() == ruleValue targetField.visible = true; this.AddvalidationRules(targetField); } else { this.hideField(targetField, rule); } } } hideField(targetField, rule) { targetField.visible = false; targetField.value = ' '; 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; } toggleVisibility(e, field, ckb) { //ckb the checkbox only send this parameter, it's essential to change the field value if (ckb) { if (e) this.form.get(field.key).patchValue(e.target.checked) field.value = this.form.get(field.key).value; } if (field.rules.length != undefined && field.rules.length > 1) field.rules.forEach(rule => { if (rule._type == "fieldValue") { let targetFieldsArray = this.findTargetField(field,rule); targetFieldsArray.forEach(targetField =>{ this.FieldValueRuleMethod(field, rule, targetField); }) } }); else if (field.rules._type == "fieldValue") { let targetFieldsArray = this.findTargetField(field,field.rules); targetFieldsArray.forEach(targetField =>{ this.FieldValueRuleMethod(field, field.rules, targetField); }) } } AddvalidationRules(field) { if (this.dataModel.getFieldByKey(field.key).attributes.validation != undefined) { let arrayVal = new Array(); this.dataModel.getFieldByKey(field.key).attributes.validation.forEach(rule => { if (rule.ruleStyle.toString() == RuleStyle[RuleStyle.existence]) { this.dataModel.getFieldByKey(field.key).required = true; arrayVal.push(Validators.required); } if (rule.ruleStyle.toString() == RuleStyle[RuleStyle.regex]) { this.dataModel.getFieldByKey(field.key).regex = rule.regex; arrayVal.push(Validators.pattern(rule.regex)); } if (rule.ruleStyle.toString() == RuleStyle[RuleStyle.customValidation]) { arrayVal.push(this.forbiddenNameValidator(/nothing/i)); } }); 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 } } forbiddenNameValidator(nameRe: RegExp): ValidatorFn { return (control: AbstractControl): { [key: string]: any } => { const forbidden = nameRe.test(control.value); return forbidden ? { 'forbiddenName': { value: control.value } } : null; }; } }