我是angular的新手,最近正在创建一个动态表单,通过api给出的响应进行验证。api将提供表单字段,如日期类型输入类型或多选择。此外,api响应将提供验证,如字段是否需要和输入字段的正则表达式(如果存在)。
使用上述所有数据,我需要在angular中创建一个表单,它应该像普通表单一样工作,验证如触摸,未触碰,必需字段错误,验证器错误等
使用html和javascript创建的页面的公共URL。该api将从网络选项卡
中获得。https://devemr.growthemr.com/assets/static/form.html?bid=1413& fid = 9242
下面是我尝试的代码库。
form.component.ts
ngOnInit(): void {
this.loadQuestions(); // it is the API call and I have attached the sample API response
this.form = this.fb.group({
items: this.fb.array([])
})
}
addItems() {
this.contactFormQuestions.forEach((x: any) => {
this.itemsFormArray.push(this.fb.group({
[x.id]: ['', x.required ?[ Validators.required] : null, x.regex? [Validators.pattern(x.regex)]: ''],
}));
});
console.log(this.form.get('items'));
}
get itemsFormArray() {
return this.form.get('items') as FormArray;
}
form.component.html
<form [formGroup]="form">
<div formArrayName="items">
<div *ngFor="let pqa of itemsFormArray.controls; let i = index">
<div [formGroupName]="i">
<div [ngSwitch]="pqa.value.questionType" class="switchCase">
<div *ngSwitchCase="'Input'" class="input-feild">
<input type="text" class="form-control" [formControlName]="pqa.value.id">
</div>
<div *ngSwitchCase="'Date'" class="input-feild">
<input type="date" class="form-control" [formControlName]="pqa.value.id">
</div>
</div>
</div>
</div>
</div>
</form>
<<p>API响应/strong>[
{
"id": 59233,
"questionId": 74719,
"questionName": "fname",
"questionType": "Input",
"hidden": null,
"required": true,
"validate": null,
"regex": "[A-Za-z]",
"validationMessage": null,
"answer": false,
"questionChoices": null,
"patientQuestionChoices": [],
"allowMultipleSelection": false,
"showDropDown": null,
"preSelectCheckbox": false
},
{
"id": 59234,
"questionId": 74720,
"questionName": "Date",
"questionType": "Date",
"hidden": null,
"required": true,
"validate": null,
"regex": null,
"validationMessage": null,
"answer": false,
"questionChoices": null,
"patientQuestionChoices": [],
"allowMultipleSelection": false,
"showDropDown": null,
"preSelectCheckbox": false
},
{
"id": 59235,
"questionId": 74721,
"questionName": "Multi Select",
"questionType": "Multiple_Selection_Text",
"hidden": null,
"required": true,
"validate": null,
"regex": null,
"validationMessage": null,
"answer": false,
"questionChoices": null,
"patientQuestionChoices": [
{
"deleted": false,
"tenantId": 1413,
"id": 3993,
"choiceName": "Option1",
"choiceId": 8546,
"selected": false
},
{
"deleted": false,
"tenantId": 1413,
"id": 3994,
"choiceName": "Option2",
"choiceId": 8547,
"selected": false
}
],
"allowMultipleSelection": true,
"showDropDown": true,
"preSelectCheckbox": false
}
]
这里有一些创建ReactiveForm的代码。也许这能帮助你解决你的问题。
可能的方式
一旦你有多个组件的输入表单(文本,日期,多选择,…),这应该是可能的循环你的API响应和测试questionType
动态构建一个表单(ReactiveForm在ts和输入组件在html)。
表单组件
// Reactive Forms
form: FormGroup;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
// Form structure and validators
this.form = this.formBuilder.group({
'user' : this.formBuilder.group({
'username' : ['', Validators.required],
'email' : ['', [Validators.required, Validators.email]]
}),
'identity' : this.formBuilder.group({
'firstname' : ['', Validators.required],
'lastname' : ['', Validators.required],
'address' : this.formBuilder.group({
'street' : ['', Validators.required],
'city' : ['', Validators.required],
})
})
});
}
onSubmit() {
// Get object with same structure as form but only with values
console.log(this.form.value);
alert('Form is ' + (this.form.invalid ? 'invalid' : 'valid'));
}
表单组件html
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<form-text [formGroupParent]="form.get(['user'])"
[formGroupControlName]="'username'">
</form-text>
<form-text [formGroupParent]="form.get(['user'])"
[formGroupControlName]="'email'">
</form-text>
<hr>
<form-text [formGroupParent]="form.get(['identity'])"
[formGroupControlName]="'firstname'">
</form-text>
<form-text [formGroupParent]="form.get(['identity'])"
[formGroupControlName]="'lastname'">
</form-text>
<hr>
<form-text [formGroupParent]="form.get(['identity','address'])"
[formGroupControlName]="'street'">
</form-text>
<form-text [formGroupParent]="form.get(['identity','address'])"
[formGroupControlName]="'city'">
</form-text>
<button type="submit">Submit</button>
</form>
自定义输入组件ts (form-text)
// Needed to bind formControlName
@Input() formGroupParent: FormGroup;
@Input() formGroupControlName: string;
// FormControl store validators
control: FormControl;
ngOnInit() {
// Fetch Form control (validator) from FormGroup parent
this.control = <FormControl>this.formGroupParent.get(this.formGroupControlName);
}
自定义输入组件html (form-text)
<ng-container [formGroup]="formGroupParent">
<label>{{formGroupControlName}}</label>
<input type="text" formControlName="{{formGroupControlName}}">
</ng-container
外部自由对于信息(并不总是容易集成),有一个很棒的库来设计和管理调查:SurveyJS。
看一下文档
这个想法基本上是
1。-创建formGroup
getForm(json:any){
const group=new FormGroup({})
json.forEach(x=>{
const validators=[];
if (x.required)
validators.push(Validator.required)
if (x.regex)
validators.push(Validator.patern(x.regex)
....
group.addControl(x.questionName,new FormControl("",validators)
}
return group
}
2。-迭代form.controls。使用json
中的数据创建元素<form [formGroup]="form">
<div *ngFor="let keyvalue of form.controls|keyvalue;let i=index">
<app-control [data]="json[i]" ></app-control>
</div>
</form>
你的app-control计算json数据并使用viewProviders。这使得您可以使用formControlName或formGroupName或…
@Component({
selector: '..',
templateUrl: '...'
viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
@Input()data;
你的。html像
<input *ngIf="data.questionType=='Input'"
[formControlName]="data.questionName">
<ng-container *ngIf="data.questionType=='Multiple_Selection_Text'">
...
</ng-container>
...