custom validator, progress bar

This commit is contained in:
annampak 2017-10-03 18:36:09 +03:00
parent 0a982bd290
commit 7206849671
9 changed files with 154 additions and 79 deletions

View File

@ -27,13 +27,13 @@ export class DataModel {
this.fIndex = new Map<string, FieldBase<any>>(); this.fIndex = new Map<string, FieldBase<any>>();
this.fields.forEach((field) => { this.fields.forEach((field) => {
console.log("fieldid:" +field.key); //console.log("fieldid:" +field.key);
this.fIndex.set(field.key, field); this.fIndex.set(field.key, field);
}); });
this.groups.forEach((group) => { this.groups.forEach((group) => {
group.groupFields.forEach((field) => { group.groupFields.forEach((field) => {
console.log("groupid: "+group.key + "fieldid:" +field.key); //console.log("groupid: "+group.key + "fieldid:" +field.key);
this.fIndex.set(field.key, field); this.fIndex.set(field.key, field);
}); });
}); });

View File

@ -9,5 +9,6 @@ export class Rule {
target: string; target: string;
range: any[2]; range: any[2];
ruleText: string; ruleText: string;
regex: string;
methodJs:string;
} }

View File

@ -1,4 +1,5 @@
<div class="col-md-6"> <div class="panel-body">
<div class="col-md-8">
<form [formGroup]="form" (ngSubmit)="onSubmit()" novalidate> <form [formGroup]="form" (ngSubmit)="onSubmit()" novalidate>
<div *ngFor = "let section of dataModel.sections"> <div *ngFor = "let section of dataModel.sections">
@ -33,14 +34,30 @@
</form> </form>
<p>Form value: {{ form.value | json }}</p> <p>Form value: {{ form.value | json }}</p>
</div> </div>
<div class="col-md-6"> <div class="col-md-4">
<h4>On this page:</h4> <h4>On this page:</h4>
<div *ngIf="dataModel.groups.length"> <div *ngIf="dataModel.groups.length">
<toc [dataModel]="dataModel"></toc> <toc [dataModel]="dataModel"></toc>
</div> </div>
</div> </div>
<a href="#" onclick="signOut();">Sign out</a> </div>
<div class="panel-footer">
{{dirtyValues}}
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="70"
aria-valuemin="0" aria-valuemax="100" [ngStyle]="{'width': dirtyValues + '%'}">
{{dirtyValues}}
</div>
</div>
<!-- <button type="button" class="btn btn-info" onclick="signOut();">Sign out</button> -->
<a href="#" onclick="signOut();">Sign out</a>
</div>

View File

@ -22,6 +22,7 @@ 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;
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());
@ -48,6 +49,21 @@ export class DynamicFormComponent implements OnInit {
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 => {
console.log('Form changes', data);
let dirtyValuesArray: Array<any> = [];
let count = 0;
Object.keys(this.form.controls).forEach((c) => {
count++;
let currentControl = this.form.controls[c];
if(currentControl.dirty)
dirtyValuesArray.push(currentControl.value);
});
var percentage = Math.floor(dirtyValuesArray.length * 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: ======>");
@ -75,7 +91,7 @@ export class DynamicFormComponent implements OnInit {
this.onValueChanged(); // (re)set validation messages now this.onValueChanged(); // (re)set validation messages now
} }
onValueChanged(data?: any) { onValueChanged(data?: any) {debugger;
if (!this.form) { return; } if (!this.form) { return; }
const form = this.form; const form = this.form;

View File

@ -33,14 +33,14 @@
<div>{{field.description}}</div> <div>{{field.description}}</div>
<input *ngSwitchCase="'textbox'" class="form-control" [formControlName]="field.key" [id]="field.key" [type]="field.type" <input *ngSwitchCase="'textbox'" class="form-control" [formControlName]="field.key" [id]="field.key" [type]="field.type"
required="field.required" [(ngModel)]="field.value"> [(ngModel)]="field.value" [required]="field.required" [pattern] = "field.regex">
<select [id]="field.key" *ngSwitchCase="'dropdown'" class="form-control"[formControlName]="field.key" [(ngModel)]="field.value"> <select [id]="field.key" *ngSwitchCase="'dropdown'" class="form-control"[formControlName]="field.key" [(ngModel)]="field.value" [required]="field.required">
<option *ngFor="let opt of field.options" [value]="opt.key">{{opt.value}}</option> <option *ngFor="let opt of field.options" [value]="opt.key">{{opt.value}}</option>
</select> </select>
<input *ngSwitchCase="'checkbox'" class="form-check" [formControlName]="field.key" [(ngModel)]="field.value" [id]="field.key" [type]="field.type" <input *ngSwitchCase="'checkbox'" class="form-check" [formControlName]="field.key" [(ngModel)]="field.value" [id]="field.key" [type]="field.type"
(change)="toggleVisibility($event, field, ckb)" #ckb> <!--(change)="field.value = ckb.checked"--> (change)="toggleVisibility($event, field, ckb)" #ckb [required]="field.required"> <!--(change)="field.value = ckb.checked"-->
@ -48,14 +48,17 @@
<ng-container *ngFor="let answrBase of field.answers"> <ng-container *ngFor="let answrBase of field.answers">
<div style="display: inline-block;margin-right:10px;"> <div style="display: inline-block;margin-right:10px;">
<label for="{{answrBase.id}}" style="padding: 8px 10px; padding-right:5px;">{{answrBase.answer}}</label> <label for="{{answrBase.id}}" style="padding: 8px 10px; padding-right:5px;">{{answrBase.answer}}</label>
<input type="radio" [formControlName]="field.key" [id]= "answrBase.id" [value]= "answrBase" [(ngModel)]="field.value" (change) = "toggleVisibility($event, field)"/> <input type="radio" [formControlName]="field.key" [id]= "answrBase.id" [value]= "answrBase" [(ngModel)]="field.value" (change) = "toggleVisibility($event, field)" [required]="field.required"/>
</div> </div>
</ng-container> </ng-container>
</div> </div>
</div> </div>
<div class= "errorMessage" *ngIf="!isValid">{{field.label}} is required</div> <div [hidden]="isValid">
<div *ngIf="isValidRequired">{{field.label}} is required</div>
<div *ngIf="isValidPattern">{{field.label}} must follow a regular expression</div>
<div *ngIf="isValidCustom">{{field.label}} custom Valid</div>
</div>
</div> </div>

View File

@ -13,6 +13,7 @@ export class FieldBase<T>{
group:string; group:string;
description:string; description:string;
attributes: Attribute; attributes: Attribute;
regex:string;
constructor(options: { constructor(options: {
value?: T, value?: T,
@ -25,7 +26,8 @@ export class FieldBase<T>{
controlType?: string controlType?: string
group?: string group?: string
description?: string, description?: string,
attributes?: Attribute attributes?: Attribute,
regex?:string
} = {}) { } = {}) {
this.value = options.value; this.value = options.value;
this.key = options.key || ''; this.key = options.key || '';
@ -38,5 +40,6 @@ export class FieldBase<T>{
this.group = options.group || ''; this.group = options.group || '';
this.description = options.description || ''; this.description = options.description || '';
this.attributes = options.attributes || new Attribute(); this.attributes = options.attributes || new Attribute();
this.regex = options.regex || '';
} }
} }

View File

@ -6,9 +6,17 @@
<body> <body>
<!-- <div class="g-signin2" data-onsuccess="onSignIn"></div> --> <!-- <div class="g-signin2" data-onsuccess="onSignIn"></div> -->
<div class="container">
<div class="col-md-3 text-center">
<h4>Please Sign in</h4>
</div>
<div class="col-md-3 text-center">
<div>
<google-signin [clientId]="myClientId" (googleSignInSuccess)="onGoogleSignInSuccess($event)"></google-signin>
</div>
</div>
</div>
<div> <google-signin [clientId]="myClientId" (googleSignInSuccess)="onGoogleSignInSuccess($event)"></google-signin></div>
<!-- <button routerLink="/dynamic-form">Go to form</button> <!-- <button routerLink="/dynamic-form">Go to form</button>
<button routerLink="/projects">Go to projects</button> trial for routing --> <button routerLink="/projects">Go to projects</button> trial for routing -->
<!-- <a href="#" onclick="signOut();">Sign out</a> --> <!-- <a href="#" onclick="signOut();">Sign out</a> -->

View File

@ -27,7 +27,7 @@ export class dataModelBuilder {
this.dataModel.groups = this.getGroups(data.dataset.profile.viewstyle.definition.root.fieldGroups.fieldGroup, this.fields); this.dataModel.groups = this.getGroups(data.dataset.profile.viewstyle.definition.root.fieldGroups.fieldGroup, this.fields);
this.dataModel.semanticAttr = new Array(new Attribute); this.dataModel.semanticAttr = new Array(new Attribute);
//this.dataModel.semanticAttr = data.dataset.profile.definition.root.fields.field; //this.dataModel.semanticAttr = data.dataset.profile.definition.root.fields.field;
this.dataModel.semanticAttr = this.getFieldsAttributes(data.dataset.profile.definition.root.fields.field, this.fields) ; this.dataModel.semanticAttr = this.getFieldsAttributes(data.dataset.profile.definition.root.fields.field, data.dataset.profile.ruleset.definition.root.functions.function, this.fields) ;
this.dataModel.sections = this.getSections(data.dataset.profile.viewstyle.definition.root.sections.section, this.dataModel.groups) ; this.dataModel.sections = this.getSections(data.dataset.profile.viewstyle.definition.root.sections.section, this.dataModel.groups) ;
this.dataModel.buildIndex(); this.dataModel.buildIndex();
@ -203,7 +203,7 @@ export class dataModelBuilder {
} }
private getFieldsAttributes(attributes:any, fields:any[]){ private getFieldsAttributes(attributes:any, functions:any, fields:any[]){
let attribute:Attribute[]=[]; let attribute:Attribute[]=[];
attributes.forEach(attr => { attributes.forEach(attr => {
let newAttribute = new Attribute(); let newAttribute = new Attribute();
@ -214,10 +214,11 @@ export class dataModelBuilder {
newAttribute.multiplicityMin = attr.multiplicity._min; newAttribute.multiplicityMin = attr.multiplicity._min;
newAttribute.ordinal = attr._ordinal; newAttribute.ordinal = attr._ordinal;
newAttribute.sources = new Array(); newAttribute.sources = new Array();
newAttribute.sources.push(attr.sources.source);
newAttribute.validation = new Array(); newAttribute.validation = new Array();
//newAttribute.validation.push(attr.validation.rule); //newAttribute.validation.push(attr.validation.rule);
if(attr.sources){
newAttribute.sources.push(attr.sources.source);
newAttribute.sources.forEach(src => { newAttribute.sources.forEach(src => {
src.params=new Array(); src.params=new Array();
for (var i=0, len=attr.sources.source.value.length; i<len; i++){ for (var i=0, len=attr.sources.source.value.length; i<len; i++){
@ -228,12 +229,24 @@ export class dataModelBuilder {
} }
}); });
}
if (attr.validation.rule.length) if (attr.validation.rule.length)
for (var i=0, len=attr.validation.rule.length; i<len; i++){ for (var i=0, len=attr.validation.rule.length; i<len; i++){
let rule = new Rule(); let rule = new Rule();
rule.ruleStyle= attr.validation.rule[i]._ruleStyle; rule.ruleStyle= attr.validation.rule[i]._ruleStyle;
rule.ruleType= attr.validation.rule[i]._type; rule.ruleType= attr.validation.rule[i]._type;
if (attr.validation.rule[i]._ruleStyle == "regex")
rule.regex= attr.validation.rule[i].__cdata;
if (attr.validation.rule[i]._ruleStyle == "customValidation"){
rule.method= attr.validation.rule[i]._method;
functions.forEach(fnc => {
if(fnc._id == rule.method)
rule.methodJs = fnc.script.__cdata;
});
}
newAttribute.validation.push(rule); newAttribute.validation.push(rule);
} }
@ -242,6 +255,17 @@ export class dataModelBuilder {
let rule = new Rule(); let rule = new Rule();
rule.ruleStyle= attr.validation.rule._ruleStyle; rule.ruleStyle= attr.validation.rule._ruleStyle;
rule.ruleType= attr.validation.rule._type; rule.ruleType= attr.validation.rule._type;
if (attr.validation.rule._ruleStyle == "regex")
rule.regex= attr.validation.rule.__cdata;
if (attr.validation.rule._ruleStyle == "customValidation"){
rule.method= attr.validation.rule._method;
functions.forEach(fnc => {
if(fnc._id == rule.method) debugger;
rule.methodJs = fnc.__cdata;
});
}
newAttribute.validation.push(rule); newAttribute.validation.push(rule);
} }
} }

View File

@ -16,12 +16,15 @@ export class FieldControlService {
groups.forEach(group => { groups.forEach(group => {
let subgroup: any = {}; let subgroup: any = {};
group.groupFields.forEach(field => { group.groupFields.forEach(field => {
if(field.attributes.validation != undefined) //if(field.attributes.validation != undefined)
field.attributes.validation.forEach(val => { // field.attributes.validation.forEach(val => {
if (val.ruleStyle.toString()=="existence"){ // if (val.ruleStyle.toString()=="existence"){
field.required = true; // field.required = true;
} // }
}); // if (val.ruleStyle.toString()=="regex"){
// field.regex = val.regex;
// }
// });
subgroup[field.key] = field.required ? new FormControl(field.value || '', Validators.required) : new FormControl(field.value || '') subgroup[field.key] = field.required ? new FormControl(field.value || '', Validators.required) : new FormControl(field.value || '')
}); });
//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