Progress bar improvements, validators

This commit is contained in:
annampak 2017-10-04 12:39:45 +03:00
parent 14335cce29
commit 6c0d9946ee
7 changed files with 121 additions and 75 deletions

View File

@ -1,5 +1,6 @@
export enum RuleStyle { export enum RuleStyle {
existence, existence,
regex regex,
customValidation
} }

View File

@ -50,11 +50,10 @@
<div class="panel-footer"> <div class="panel-footer">
{{dirtyValues}}
<div class="progress"> <div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="70" <div class="progress-bar" role="progressbar" aria-valuenow="70"
aria-valuemin="0" aria-valuemax="100" [ngStyle]="{'width': dirtyValues + '%'}"> aria-valuemin="0" aria-valuemax="100" [ngStyle]="{'width': dirtyValues + '%'}">
{{dirtyValues}} {{dirtyValues}}%
</div> </div>
</div> </div>
<!-- <button type="button" class="btn btn-info" onclick="signOut();">Sign out</button> --> <!-- <button type="button" class="btn btn-info" onclick="signOut();">Sign out</button> -->

View File

@ -1,7 +1,7 @@
import { Component, Input, OnInit, AfterViewChecked, ViewChild } from '@angular/core'; import { Component, Input, OnInit, AfterViewChecked, ViewChild } from '@angular/core';
import { FormGroup, Validators } from '@angular/forms'; import { FormGroup, Validators } from '@angular/forms';
import { NgForm } from '@angular/forms'; import { NgForm } from '@angular/forms';
import { Router, ActivatedRoute, ParamMap } from '@angular/router'; import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import 'rxjs/add/operator/switchMap'; import 'rxjs/add/operator/switchMap';
//import { FieldBase } from '../../app/form/fields/field-base'; //import { FieldBase } from '../../app/form/fields/field-base';
@ -20,52 +20,64 @@ import { GroupBase } from './dynamic-form-group/group-base';
export class DynamicFormComponent implements OnInit { export class DynamicFormComponent implements OnInit {
@Input() dataModel: DataModel = new DataModel(); @Input() dataModel: DataModel = new DataModel();
form: FormGroup; form: FormGroup;
payLoad = ''; payLoad = '';
@Input() dirtyValues:number = 0; @Input() dirtyValues: number = 0;
constructor(private qcs: FieldControlService, private serverService: ServerService, private dataModelService: dataModelBuilder, private router: Router, private route: ActivatedRoute) { constructor(private qcs: FieldControlService, private serverService: ServerService, private dataModelService: dataModelBuilder, private router: Router, private route: ActivatedRoute) {
this.form = this.qcs.toFormGroup(new Array(), new Array()); this.form = this.qcs.toFormGroup(new Array(), new Array());
} }
getSubForm(subformName){ getSubForm(subformName) {
return this.form.controls[subformName]; return this.form.controls[subformName];
} }
ngOnInit() { ngOnInit() {
console.log("DynamicFormComponent.ngOnInit() -- RUNNIGN"); console.log("DynamicFormComponent.ngOnInit() -- RUNNIGN");
this.serverService.getData() this.serverService.getData()
.subscribe( .subscribe(
(data: any[]) => { (data: any[]) => {
console.log("this.serverService.getFields"); console.log("this.serverService.getFields");
this.dataModel = new DataModel(); this.dataModel = new DataModel();
this.dataModel = this.dataModelService.getDataModel(data); this.dataModel = this.dataModelService.getDataModel(data);
this.form = this.qcs.toFormGroup(this.dataModel.fields, this.dataModel.groups); this.form = this.qcs.toFormGroup(this.dataModel.fields, this.dataModel.groups);
this.form.valueChanges.subscribe(data => { this.form.valueChanges.subscribe(data => {
console.log('Form changes', data); // console.log('Form changes', data);
let dirtyValuesArray: Array<any> = []; let dirtyValuesArray: Array<any> = [];
let count = 0; let count = 0;
Object.keys(this.form.controls).forEach((c) => { let countDirtyValues = 0;
count++; Object.keys(this.form.controls).forEach((c) => {
let currentControl = this.form.controls[c]; //count++;
if(currentControl.dirty) let currentControl = this.form.controls[c];
dirtyValuesArray.push(currentControl.value); if (currentControl.dirty)
dirtyValuesArray.push(currentControl.value);
});
var percentage = Math.floor(dirtyValuesArray.length * 100 / count); });
this.dirtyValues = percentage; this.dataModel.groups.forEach(grp => {
grp.groupFields.forEach((fld) => {
if (fld.visible == true || fld.visible == "true")
count++;
if(fld.value != undefined)
countDirtyValues++;
});
});
//console.log(count);
// var percentage = Math.floor(dirtyValuesArray.length * 100 / count);
var percentage = Math.floor(countDirtyValues * 100 / count);
this.dirtyValues = percentage;
}) })
//this.form = this.qcs.toFormGroup(this.fields); //this.form = this.qcs.toFormGroup(this.fields);
console.log("SUMMARY: ======>"); console.log("SUMMARY: ======>");
console.log(this.dataModel); console.log(this.dataModel);
console.log(this.form); console.log(this.form);
@ -74,7 +86,7 @@ export class DynamicFormComponent implements OnInit {
}, },
(error) => console.log(error) (error) => console.log(error)
); );
} }
onSubmit() { onSubmit() {
@ -91,7 +103,8 @@ export class DynamicFormComponent implements OnInit {
this.onValueChanged(); // (re)set validation messages now this.onValueChanged(); // (re)set validation messages now
} }
onValueChanged(data?: any) {debugger; onValueChanged(data?: any) {
debugger;
if (!this.form) { return; } if (!this.form) { return; }
const form = this.form; const form = this.form;

View File

@ -1,10 +1,11 @@
import { DataModel } from '../../entities/DataModel'; import { DataModel } from '../../entities/DataModel';
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup, ValidatorFn, AbstractControl } from '@angular/forms';
import { FieldBase } from './field-base'; import { FieldBase } from './field-base';
import { GroupBase } from '../../form/dynamic-form-group/group-base'; import { GroupBase } from '../../form/dynamic-form-group/group-base';
import { DropdownField } from '../../form/fields/dropdown/field-dropdown'; import { DropdownField } from '../../form/fields/dropdown/field-dropdown';
import { RuleStyle } from '../../entities/common/rulestyle';
@Component({ @Component({
@ -16,67 +17,99 @@ export class DynamicFormFieldComponent {
@Input() dataModel: DataModel; @Input() dataModel: DataModel;
@Input() field: FieldBase<any>; @Input() field: FieldBase<any>;
@Input() form: FormGroup; @Input() form: FormGroup;
get isValid() { debugger; get isValid() {
return this.form.controls[this.field.key].valid; return this.form.controls[this.field.key].valid;
}
get isValidRequired() {
return this.form.controls[this.field.key].hasError("required");
}
get isValidPattern() {
return this.form.controls[this.field.key].hasError("pattern");
}
get isValidCustom() {
return this.form.controls[this.field.key].hasError("forbiddenName");
} }
public ngOnInit() { //dropdown lists take only one of the available sources public ngOnInit() { //dropdown lists take only one of the available sources
for (var i=0, len = this.dataModel.groups.length; i<len; i++){ for (var i = 0, len = this.dataModel.groups.length; i < len; i++) {
let dropdownField:any; let dropdownField: any;
dropdownField = this.dataModel.groups[i].groupFields.find(x=>x.controlType == "dropdown"); dropdownField = this.dataModel.groups[i].groupFields.find(x => x.controlType == "dropdown");
if(dropdownField != undefined){ if (dropdownField != undefined) {
if(dropdownField.attributes.sources != undefined) if (dropdownField.attributes.sources != undefined)
dropdownField.options = dropdownField.attributes.sources[0].params; dropdownField.options = dropdownField.attributes.sources[0].params;
} }
} }
} }
ruleVisibleMethod(field, rule, dataModel){ //visibility rule -- checks if target field is visible ruleVisibleMethod(field, rule, dataModel) { //visibility rule -- checks if target field is visible
dataModel.fields.forEach(fld => { dataModel.fields.forEach(fld => {
if (fld.label == rule._target && fld.visible == true) if (fld.label == rule._target && fld.visible == true)
field.visible = true; field.visible = true;
}); });
if(field.visible == true) if (field.visible == true)
return true; return true;
} }
FieldValueRuleMethod(field, rule){ //fieldValue rule -- checks the value of target FieldValueRuleMethod(field, rule) { //fieldValue rule -- checks the value of target
if (rule._ruleStyle == "range"){ if (rule._ruleStyle == "range") {
this.dataModel.fields.forEach(fld => { this.dataModel.fields.forEach(fld => {
if (fld.key == rule._target && rule._from< fld.value <rule._to){ if (fld.key == rule._target && rule._from < fld.value < rule._to) {
console.log("visible"+ fld.value) console.log("visible" + fld.value)
field.visible = true; field.visible = true;
} }
}); });
} }
if (rule._ruleStyle == "boolean"){ //boolean Decision field if (rule._ruleStyle == "boolean") { //boolean Decision field
let ruleValue = rule.value.__text; let ruleValue = rule.value.__text;
if (field.value.value.toString() == ruleValue){ if (field.value.value.toString() == ruleValue) {
this.dataModel.getFieldByKey(rule._target).visible = true; this.dataModel.getFieldByKey(rule._target).visible = true;
}else{ this.AddvalidationRules(rule._target);
} else {
this.dataModel.getFieldByKey(rule._target).visible = false; this.dataModel.getFieldByKey(rule._target).visible = false;
} }
} }
if (rule._ruleStyle == "checked"){ //checkbox field if (rule._ruleStyle == "checked") { //checkbox field
if (field.value == true){ if (field.value == true) {
this.dataModel.getFieldByKey(rule._target).visible = true; this.dataModel.getFieldByKey(rule._target).visible = true;
}else{ this.AddvalidationRules(rule._target);
} else {
this.dataModel.getFieldByKey(rule._target).visible = false; this.dataModel.getFieldByKey(rule._target).visible = false;
} }
} }
} }
toggleVisibility(e, field, ckb){ //ckb the checkbox only send this parameter, it's essential to change the field value toggleVisibility(e, field, ckb) { //ckb the checkbox only send this parameter, it's essential to change the field value
if(ckb) if (ckb)
field.value = ckb.checked; field.value = ckb.checked;
field.rules.forEach(rule => { field.rules.forEach(rule => {
if (rule._type=="fieldValue"){ if (rule._type == "fieldValue") {
this.FieldValueRuleMethod(field, rule); this.FieldValueRuleMethod(field, rule);
} }
}); });
} }
AddvalidationRules(field) {
if (this.dataModel.getFieldByKey(field).attributes.validation != undefined) {
this.dataModel.getFieldByKey(field).attributes.validation.forEach(rule => {
if (rule.ruleStyle.toString() == RuleStyle[RuleStyle.existence])
this.dataModel.getFieldByKey(field).required = true;
if (rule.ruleStyle.toString() == RuleStyle[RuleStyle.regex])
this.dataModel.getFieldByKey(field).regex = rule.regex;
if (rule.ruleStyle.toString() == RuleStyle[RuleStyle.customValidation])
this.form.controls[field].setValidators(this.forbiddenNameValidator(/bob/i));
});
}
}
forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
const forbidden = nameRe.test(control.value);
return forbidden ? { 'forbiddenName': { value: control.value } } : null;
};
}
} }

View File

@ -8,7 +8,7 @@ export class FieldBase<T>{
required:boolean; required:boolean;
order:number; order:number;
rules: Rule[]; rules: Rule[];
visible: boolean; visible: boolean | string;
controlType:string; controlType:string;
group:string; group:string;
description:string; description:string;
@ -22,7 +22,7 @@ export class FieldBase<T>{
required?:boolean, required?:boolean,
order?: number, order?: number,
rules?: Rule[], rules?: Rule[],
visible?: boolean, visible?: boolean | string,
controlType?: string controlType?: string
group?: string group?: string
description?: string, description?: string,

View File

@ -75,7 +75,7 @@ export class dataModelBuilder {
newfield = new CheckBoxField({ newfield = new CheckBoxField({
label: element.title.__cdata, label: element.title.__cdata,
key:element._id, key:element._id,
value: true, value: element.value,
order:element._ordinal, order:element._ordinal,
rules: element.visible.rule != undefined ? element.visible.rule: rule, rules: element.visible.rule != undefined ? element.visible.rule: rule,
visible: element._defaultVisibility, visible: element._defaultVisibility,
@ -91,7 +91,7 @@ export class dataModelBuilder {
newfield = new RadioBoxField({ newfield = new RadioBoxField({
label: element.title.__cdata, label: element.title.__cdata,
key:element._id, key:element._id,
value: true, value: element.value,
order:element._ordinal, order:element._ordinal,
rules: element.visible.rule != undefined ? element.visible.rule: rule, rules: element.visible.rule != undefined ? element.visible.rule: rule,
visible: element._defaultVisibility, visible: element._defaultVisibility,

View File

@ -29,16 +29,16 @@ export class FieldControlService {
}); });
//PLEASE CHANGE THE group.key TO BE SAME AS THE ONE ON THE DYNAMIC-FORM-GROUP-COMPONENT.html //PLEASE CHANGE THE group.key TO BE SAME AS THE ONE ON THE DYNAMIC-FORM-GROUP-COMPONENT.html
form[group.key] = new FormGroup(subgroup); form[group.key] = new FormGroup(subgroup);
console.log("FORM_GROUP_GROUP: "); //console.log("FORM_GROUP_GROUP: ");
console.log(form); //console.log(form);
}); });
//add also the spare fields into the form //add also the spare fields into the form
fields.forEach(field => { fields.forEach(field => {
form[field.key] = field.required ? new FormControl(field.value || '', Validators.required) : new FormControl(field.value || '') form[field.key] = field.required ? new FormControl(field.value || '', Validators.required) : new FormControl(field.value || '')
}); });
console.log("FORM_GROUP: "); //console.log("FORM_GROUP: ");
console.log(form); //console.log(form);
return new FormGroup(form); return new FormGroup(form);
} }