我有一个角形式的形式数组。我想对此表单数组应用验证。如果表单数组为空,则应禁用提交按钮。提交表单的条件是数组中至少有一项
<!-- Left Panel -->
<app-empsidebar></app-empsidebar>
<div id="right-panel" class="right-panel">
<app-empheader></app-empheader>
<!-- Header -->
<div class="content">
<div class="animated fadeIn">
<div class="card">
<div class="card-header">
<strong class="card-title"> Add Course</strong>
</div>
{{this.courseForm.value | json}}
<!-- {{this.TrainingModule.value | json}} -->
<form (ngSubmit)="onsubmit()" [formGroup]="courseForm" >
<div class="row col-md-12">
<div class="col-md-6">
<div class="col-md-12 mt-4">
<div class="row form-group">
<div class="col-md-3">
<label for="selectSm" class="form-control-label control-label">Department</label>
</div>
<div class="col-md-9">
<select name="department" id="department" class="form-control-sm form-control" formControlName="department">
<option value="" selected disabled>Select Department</option>
<option value="EM">Employee</option>
<option value="HR">HR</option>
<option value="HA">HR Assistant</option>
<option value="MN">Manager</option>
<option value="LM">Line Manager</option>
</select>
<br>
<span style="color:red;" *ngIf="department && department.invalid && department.touched ">Required</span>
</div>
</div>
</div>
<div class="col-md-12">
<div class="row form-group">
<div class="col col-md-3"><label for="text-input" class="form-control-label control-label">Title</label></div>
<div class="col-12 col-md-9">
<input type="text" id="title" name="title" required class="form-control" formControlName="title">
<span style="color:red;" *ngIf="title && title.invalid && title.touched">Required</span>
</div>
</div>
</div>
<div class="col-md-12">
<div class="form-group row">
<label for="staticEmail" class="col-sm-3 control-label">Description</label>
<div class="col-12 col-md-9">
<textarea name="description" id="description" end_date rows="3" class="form-control" formControlName="description"></textarea>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="col-md-12 mt-4">
<div class="row form-group">
<div class="col col-md-3"><label for="text-input" class="form-control-label control-label">Start Date</label></div>
<div class="col-12 col-md-9"><input type="date" id="start_date" name="start_date" class="form-control" formControlName="start_date"></div>
</div>
</div>
<div class="col-md-12">
<div class="row form-group">
<div class="col col-md-3"><label for="text-input" class="form-control-label control-label">End Date</label></div>
<div class="col-12 col-md-9"><input type="date" id="end_date" name="end_date" class="form-control" formControlName="end_date"></div>
</div>
</div>
<div class="col-md-12">
<div class="form-group row">
<label for="staticEmail" class="col-sm-3 control-label">Assessment</label>
<div class="col-sm-9">
<input type="radio" id="assessment_status" name="assessment_status" value="1" checked formControlName="assessment_status" >
<label class="ml-1 mr-3">No</label>
<input type="radio" id="assessment_status" name="assessment_status" value="2" formControlName="assessment_status">
<label class="ml-1">Yes</label>
</div>
</div>
</div>
</div>
<div class="col-md-12" formArrayName="TrainingModules" >
<div class="">
<div class="text-right mt-2">
<button type="button" (click)="addModule()" class="btn btn-success btn-sm" ><i class="fa fas fa-plus-circle"></i> Add Module</button>
</div>
<div class="table-stats ov-h">
<table class="table data">
<thead>
<tr>
<th scope="col" class="tb_font_sty">Module Name</th>
<th scope="col" class="tb_font_sty">Source</th>
<th scope="col" class="tb_font_sty">Path</th>
<th scope="col" class="tb_font_sty">Duration</th>
<th scope="col" class="tb_font_sty"></th>
</tr>
</thead>
<tbody *ngFor="let TrainingModule of TrainingModules().controls; let i=index" [formGroupName]="i" >
<tr>
<!-- <input type="text" name="index" value="{{i+1}}"> -->
<td scope="row "><input type="text" name="modules[]" class="form-control form-control-sm" formControlName="modules"[ngClass]="{'is-invalid':
trainingModulescon(i).controls['modules'].errors && (trainingModulescon(i).controls['modules'].dirty || trainingModulescon(i).controls['modules'].touched)}">
<div *ngFor="let validation of validation_modulemessage.modules" class="invalid-feedback">
<div *ngIf="trainingModulescon(i).controls['modules'].hasError(validation.type) && (trainingModulescon(i).controls['modules'].dirty || trainingModulescon(i).controls['modules'].touched)">
{{ validation.message }}
</div>
</div>
</td>
<td class="">
<select name="selectSource[]" id="{{i}}" class="form-control form-control-sm" formControlName="selectSource" (change)="selectsource($event)" [ngClass]="{'is-invalid':
trainingModulescon(i).controls['selectSource'].errors && (trainingModulescon(i).controls['selectSource'].dirty || trainingModulescon(i).controls['selectSource'].touched)}">
<option value="" selected disabled>Select Source</option>
<option value="1">Youtube</option>
<option value="2">Video</option>
<option value="3">Audio</option>
<option value="4">Document</option>
</select>
<div *ngFor="let validation of validation_modulemessage.selectSource" class="invalid-feedback">
<div *ngIf="trainingModulescon(i).controls['selectSource'].hasError(validation.type) && (trainingModulescon(i).controls['selectSource'].dirty || trainingModulescon(i).controls['selectSource'].touched)">
{{ validation.message }}
</div>
</div>
</td>
<td class="path_{{i}}">
<input type="text"class="form-control form-control-sm" name="path[]" formControlName="path" [ngClass]="{'is-invalid':
trainingModulescon(i).controls['path'].errors && (trainingModulescon(i).controls['path'].dirty || trainingModulescon(i).controls['path'].touched)}">
<div *ngFor="let validation of validation_modulemessage.path" class="invalid-feedback">
<div *ngIf="trainingModulescon(i).controls['path'].hasError(validation.type) && (trainingModulescon(i).controls['path'].dirty || trainingModulescon(i).controls['path'].touched)">
{{ validation.message }}
</div>
</div>
</td>
<td class="video_{{i}} hide">
<input type="file" formControlName="video" name="video[]">
</td>
<td class="audio_{{i}} hide">
<input type="file" formControlName="audio" name="audio[]"><!-- style="width: 95px;" -->
</td>
<td class="upldoc_{{i}} hide">
<input type="file" formControlName="upl_doc" name="upldoc[]">
</td>
<td class="">
<input type="text" name="duration[]" class="form-control form-control-sm" formControlName="duration" [ngClass]="{'is-invalid':trainingModulescon(i).controls['duration'].errors && (trainingModulescon(i).controls['duration'].dirty || trainingModulescon(i).controls['duration'].touched)}">
<div *ngFor="let validation of validation_modulemessage.duration" class="invalid-feedback">
<div *ngIf="trainingModulescon(i).controls['duration'].hasError(validation.type) && (trainingModulescon(i).controls['duration'].dirty || trainingModulescon(i).controls['duration'].touched)">
{{ validation.message }}
</div>
</div>
</td>
<td>
<button class="btn btn-danger btn-sm" (click)="removeModule(i)"><i class="fa fa-trash" aria-hidden="true"></i></button>
</td>
</tr>
</tbody>
</table>
</div>
<!-- /.table-stats -->
</div>
</div>
</div>
<div class="col-md-12 mt-4">
<div class="mb-2" align="right">
<button type="submit" class="btn btn-outline-success mr-1" [disabled]="(courseForm.controls['department'].invalid || courseForm.controls['title'].invalid) || !trainingmodulevalid() ">Submit</button>
<button type="button" class="btn btn-outline-danger">Reset</button>
</div>
</div>
</form>
</div>
</div>
<div class="clearfix"></div>
<!-- Footer -->
<app-empfooter></app-empfooter>
<!-- Footer -->
</div>
<!-- Right Panel -->
我的代码如下
import { Component, OnInit } from '@angular/core';
// import {} from '@angular/forms';
import { Router } from '@angular/router';
import { ApiCallService } from 'src/app/api-call.service';
import { FormBuilder, FormGroup,Validators,FormArray,FormControl } from '@angular/forms';
@Component({
selector: 'app-addtraining',
templateUrl: './addtraining.component.html',
styleUrls: ['./addtraining.component.scss']
})
export class AddtrainingComponent implements OnInit {
moduleList: any;
constructor(private route:Router,private apicall:ApiCallService,private fb:FormBuilder){
}
courseForm= new FormGroup({
department: new FormControl ('', [Validators.required]),
title:new FormControl ('', [Validators.required]),
start_date: new FormControl (),
end_date: new FormControl (),
description: new FormControl (),
assessment_status: new FormControl ("1"),
TrainingModules:this.fb.array([])
})
TrainingModules():FormArray {
return this.courseForm.get("TrainingModules") as FormArray ;
}
newModule():FormGroup {
return this.fb.group({
modules: new FormControl ('', [Validators.required]),
selectSource: new FormControl ('', [Validators.required]),
path: new FormControl ('', [Validators.required]),
video: '',
audio: '',
upl_doc: '',
duration: new FormControl ('', [Validators.required])
});
}
trainingModulescon(index: string | number) {
this.moduleList = this.courseForm.get('TrainingModules') as FormArray;
const formGroup = this.moduleList.controls[index] as FormGroup;
return formGroup;
}
trainingmodulevalid(){
this.moduleList = this.courseForm.get('TrainingModules') as FormArray;
return (this.moduleList.status=="VALID");
}
addModule(){
this.TrainingModules().push(this.newModule());
}
removeModule(i:number) {
this.TrainingModules().removeAt(i);
}
validation_modulemessage = {
path: [{ type: 'required', message: 'path is required' }],
modules: [{ type: 'required', message: 'Module is required' }],
selectSource: [{ type: 'required', message: 'Source is required' }],
duration: [{ type: 'required', message: 'Duration is required' }]
};
data:any;
onsubmit() {
this.trainingmodulevalid();
this.data=this.courseForm.get("TrainingModules") as FormArray
// alert(JSON.stringify(this.data.value));
this.apicall.addCourse(this.courseForm.value).subscribe((res)=>{
alert(JSON.stringify(res));
console.log(JSON.stringify(res));
})
}
selectsource(event:any){
var ids=event.target.id;
if(event.target.value=='1'){
$('.path_'+ids).removeClass('hide');
$('.video_'+ids).addClass('hide');
$('.audio_'+ids).addClass('hide');
$('.upldoc_'+ids).addClass('hide');
} else if(event.target.value=='2'){
$('.video_'+ids).removeClass('hide');
$('.path_'+ids).addClass('hide');
$('.audio_'+ids).addClass('hide');
$('.upldoc_'+ids).addClass('hide');
} else if(event.target.value=='3'){
$('.audio_'+ids).removeClass('hide');
$('.path_'+ids).addClass('hide');
$('.video_'+ids).addClass('hide');
$('.upldoc_'+ids).addClass('hide');
}else {
$('.upldoc_'+ids).removeClass('hide');
$('.path_'+ids).addClass('hide');
$('.video_'+ids).addClass('hide');
$('.audio_'+ids).addClass('hide');
}
}
get department(){
return this.courseForm.get('department');
}
get title(){
return this.courseForm.get('title');
}
ngOnInit(): void {}
}
不要提交类型,而是使用普通类型,并创建 onSubmit() 方法,您可以在其中将表单值分配给某个对象,用它做任何您需要的事情(比如调用一些数据服务或其他任何东西,然后可能会导航到其他地方)。
您的“提交”按钮:
<button type="button" class="btn btn-primary" (click)="onSubmit()" [disabled]="courseForm.get('department')?.invalid || courseForm.get('title')?.invalid" >Save</button>
根据需要调整它以完全按照您的意愿行事。