custom validator, progress bar
This commit is contained in:
parent
0a982bd290
commit
7206849671
|
@ -27,13 +27,13 @@ export class DataModel {
|
|||
this.fIndex = new Map<string, FieldBase<any>>();
|
||||
|
||||
this.fields.forEach((field) => {
|
||||
console.log("fieldid:" +field.key);
|
||||
//console.log("fieldid:" +field.key);
|
||||
this.fIndex.set(field.key, field);
|
||||
});
|
||||
|
||||
this.groups.forEach((group) => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,5 +9,6 @@ export class Rule {
|
|||
target: string;
|
||||
range: any[2];
|
||||
ruleText: string;
|
||||
|
||||
regex: string;
|
||||
methodJs:string;
|
||||
}
|
|
@ -1,46 +1,63 @@
|
|||
<div class="col-md-6">
|
||||
<form [formGroup]="form" (ngSubmit)="onSubmit()" novalidate>
|
||||
|
||||
<div *ngFor = "let section of dataModel.sections">
|
||||
<div *ngIf="section.groupFields.length>0 else sectionHeader">
|
||||
<h3>{{section.title}}</h3>
|
||||
<div *ngFor="let group of section.groupFields">
|
||||
<div class="panel-body">
|
||||
<div class="col-md-8">
|
||||
<form [formGroup]="form" (ngSubmit)="onSubmit()" novalidate>
|
||||
|
||||
<div *ngFor = "let section of dataModel.sections">
|
||||
<div *ngIf="section.groupFields.length>0 else sectionHeader">
|
||||
<h3>{{section.title}}</h3>
|
||||
<div *ngFor="let group of section.groupFields">
|
||||
<df-group [group]="group" [dataModel]="dataModel" [form]="getSubForm(group.key)"></df-group>
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #sectionHeader>
|
||||
<h2>{{section.title}}</h2>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
<div *ngFor="let field of dataModel.fields">
|
||||
<div [formGroup]="form" class="form-group">
|
||||
<df-field [field]="field" [form]="form" [dataModel]="dataModel" ></df-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div *ngFor="let group of dataModel.groups">
|
||||
<df-group [group]="group" [dataModel]="dataModel" [form]="getSubForm(group.key)"></df-group>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div>
|
||||
<button type="submit" class="btn btn-default" [disabled]="!form.valid">Save</button>
|
||||
</div>
|
||||
|
||||
<div *ngIf="payLoad" class="form-row">
|
||||
<strong>Saved the following values</strong><br>{{payLoad}}
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<p>Form value: {{ form.value | json }}</p>
|
||||
</div>
|
||||
<ng-template #sectionHeader>
|
||||
<h2>{{section.title}}</h2>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-md-4">
|
||||
<h4>On this page:</h4>
|
||||
<div *ngIf="dataModel.groups.length">
|
||||
<toc [dataModel]="dataModel"></toc>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngFor="let field of dataModel.fields">
|
||||
<div [formGroup]="form" class="form-group">
|
||||
<df-field [field]="field" [form]="form" [dataModel]="dataModel" ></df-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div *ngFor="let group of dataModel.groups">
|
||||
<df-group [group]="group" [dataModel]="dataModel" [form]="getSubForm(group.key)"></df-group>
|
||||
</div> -->
|
||||
|
||||
<div>
|
||||
<button type="submit" class="btn btn-default" [disabled]="!form.valid">Save</button>
|
||||
</div>
|
||||
|
||||
<div *ngIf="payLoad" class="form-row">
|
||||
<strong>Saved the following values</strong><br>{{payLoad}}
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<p>Form value: {{ form.value | json }}</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-md-6">
|
||||
<h4>On this page:</h4>
|
||||
<div *ngIf="dataModel.groups.length">
|
||||
<toc [dataModel]="dataModel"></toc>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="#" onclick="signOut();">Sign out</a>
|
||||
|
||||
<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>
|
||||
|
||||
|
|
|
@ -21,8 +21,9 @@ export class DynamicFormComponent implements OnInit {
|
|||
|
||||
@Input() dataModel: DataModel = new DataModel();
|
||||
form: FormGroup;
|
||||
payLoad = '';
|
||||
|
||||
payLoad = '';
|
||||
@Input() dirtyValues:number = 0;
|
||||
|
||||
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());
|
||||
}
|
||||
|
@ -48,6 +49,21 @@ export class DynamicFormComponent implements OnInit {
|
|||
this.dataModel = this.dataModelService.getDataModel(data);
|
||||
|
||||
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);
|
||||
|
||||
console.log("SUMMARY: ======>");
|
||||
|
@ -58,7 +74,7 @@ export class DynamicFormComponent implements OnInit {
|
|||
},
|
||||
(error) => console.log(error)
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
|
@ -75,7 +91,7 @@ export class DynamicFormComponent implements OnInit {
|
|||
this.onValueChanged(); // (re)set validation messages now
|
||||
}
|
||||
|
||||
onValueChanged(data?: any) {
|
||||
onValueChanged(data?: any) {debugger;
|
||||
if (!this.form) { return; }
|
||||
const form = this.form;
|
||||
|
||||
|
|
|
@ -33,14 +33,14 @@
|
|||
<div>{{field.description}}</div>
|
||||
|
||||
<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>
|
||||
</select>
|
||||
|
||||
<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">
|
||||
<div style="display: inline-block;margin-right:10px;">
|
||||
<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>
|
||||
</ng-container>
|
||||
</div>
|
||||
</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 class= "errorMessage" *ngIf="!isValid">{{field.label}} is required</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
|
@ -13,6 +13,7 @@ export class FieldBase<T>{
|
|||
group:string;
|
||||
description:string;
|
||||
attributes: Attribute;
|
||||
regex:string;
|
||||
|
||||
constructor(options: {
|
||||
value?: T,
|
||||
|
@ -25,7 +26,8 @@ export class FieldBase<T>{
|
|||
controlType?: string
|
||||
group?: string
|
||||
description?: string,
|
||||
attributes?: Attribute
|
||||
attributes?: Attribute,
|
||||
regex?:string
|
||||
} = {}) {
|
||||
this.value = options.value;
|
||||
this.key = options.key || '';
|
||||
|
@ -38,5 +40,6 @@ export class FieldBase<T>{
|
|||
this.group = options.group || '';
|
||||
this.description = options.description || '';
|
||||
this.attributes = options.attributes || new Attribute();
|
||||
this.regex = options.regex || '';
|
||||
}
|
||||
}
|
|
@ -1,14 +1,22 @@
|
|||
<html lang="en">
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- <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 class="g-signin2" data-onsuccess="onSignIn"></div> -->
|
||||
|
||||
|
||||
<div> <google-signin [clientId]="myClientId" (googleSignInSuccess)="onGoogleSignInSuccess($event)"></google-signin></div>
|
||||
<!-- <button routerLink="/dynamic-form">Go to form</button>
|
||||
<button routerLink="/projects">Go to projects</button> trial for routing -->
|
||||
<!-- <a href="#" onclick="signOut();">Sign out</a> -->
|
||||
|
|
|
@ -27,7 +27,7 @@ export class dataModelBuilder {
|
|||
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 = 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.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[]=[];
|
||||
attributes.forEach(attr => {
|
||||
let newAttribute = new Attribute();
|
||||
|
@ -213,27 +213,40 @@ export class dataModelBuilder {
|
|||
newAttribute.multiplicityMax = attr.multiplicity._max;
|
||||
newAttribute.multiplicityMin = attr.multiplicity._min;
|
||||
newAttribute.ordinal = attr._ordinal;
|
||||
newAttribute.sources = new Array();
|
||||
newAttribute.sources.push(attr.sources.source);
|
||||
newAttribute.sources = new Array();
|
||||
newAttribute.validation = new Array();
|
||||
//newAttribute.validation.push(attr.validation.rule);
|
||||
|
||||
newAttribute.sources.forEach(src => {
|
||||
src.params=new Array();
|
||||
for (var i=0, len=attr.sources.source.value.length; i<len; i++){
|
||||
let prm = new Param();
|
||||
prm.key= attr.sources.source.value[i]._value;
|
||||
prm.value= attr.sources.source.value[i]._label;
|
||||
src.params.push(prm);
|
||||
}
|
||||
|
||||
});
|
||||
if(attr.sources){
|
||||
newAttribute.sources.push(attr.sources.source);
|
||||
newAttribute.sources.forEach(src => {
|
||||
src.params=new Array();
|
||||
for (var i=0, len=attr.sources.source.value.length; i<len; i++){
|
||||
let prm = new Param();
|
||||
prm.key= attr.sources.source.value[i]._value;
|
||||
prm.value= attr.sources.source.value[i]._label;
|
||||
src.params.push(prm);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (attr.validation.rule.length)
|
||||
for (var i=0, len=attr.validation.rule.length; i<len; i++){
|
||||
let rule = new Rule();
|
||||
rule.ruleStyle= attr.validation.rule[i]._ruleStyle;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -242,6 +255,17 @@ export class dataModelBuilder {
|
|||
let rule = new Rule();
|
||||
rule.ruleStyle= attr.validation.rule._ruleStyle;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,15 @@ export class FieldControlService {
|
|||
groups.forEach(group => {
|
||||
let subgroup: any = {};
|
||||
group.groupFields.forEach(field => {
|
||||
if(field.attributes.validation != undefined)
|
||||
field.attributes.validation.forEach(val => {
|
||||
if (val.ruleStyle.toString()=="existence"){
|
||||
field.required = true;
|
||||
}
|
||||
});
|
||||
//if(field.attributes.validation != undefined)
|
||||
// field.attributes.validation.forEach(val => {
|
||||
// if (val.ruleStyle.toString()=="existence"){
|
||||
// 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 || '')
|
||||
});
|
||||
//PLEASE CHANGE THE group.key TO BE SAME AS THE ONE ON THE DYNAMIC-FORM-GROUP-COMPONENT.html
|
||||
|
|
Loading…
Reference in New Issue