Я использую реактивные формы formArray, чтобы добавить раздел данных по щелчку добавления, и по щелчку редактирования, после редактирования я использовал кнопку удаления и сохранения, чтобы сохранить в таблицу. Таким образом, в основном необходимо выполнять одну операцию за раз. Поэтому, когда я нажимаю на кнопку «Изменить», кнопка «Добавить новый» будет отключена, и после сохранения данных я включаю кнопку «Добавить». Итак, теперь, если я внес изменения в элемент с помощью редактирования, и нажмите, чтобы удалить или открыть новый элемент для редактирования, то должно появиться предупреждающее сообщение о том, что вы хотите удалить сделанные изменения. Я пытаюсь реализовать, но он работает только в первый раз, и со следующего раза он начинает показывать предупреждающее сообщение при каждом нажатии на иконку редактирования. Может кто-нибудь помочь мне заставить его работать.
DEMO: DEMO
HTML таблицы, куда я отправляю данные и показываю, что я добавил и что элементы, которые я получаю из бэкэнда.
<table class="table table-hover accordion-table"
*ngIf="agentDetailsList?.w9Info || temporaryControls.length != 0">
<thead>
<tr>
<th scope="col" *ngFor="let field of w9ListDetails"> {{field.displayName}}
</th>
<th scope="col" class="width75">Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let w9 of agentDetailsList?.w9Info ? agentDetailsList.w9Info : temporaryControls ">
<td *ngFor="let field of w9ListDetails">
{{w9[field.param]}}
</td>
<td class="width75">
<button type="button" class="btn btn-outline-primary btn-table {{isReadOnly ? 'link-disabled' : ''}}"
title="View" (click)="downLoadFiles(w9)"><i class="fas fa-eye"></i></button>
<button type="button" class="btn btn-outline-primary btn-table ml-1 {{isReadOnly ? 'link-disabled' : ''}}"
title="Edit" (click)="editw9(w9, 'editMode')"><i class="fas fa-edit"></i></button>
</td>
</tr>
</tbody>
</table>
HTML formArray:
<div class="card-body" *ngIf="agentW9InfoForm" [formGroup]='agentW9InfoForm'>
<form formArrayName="w9Info" *ngFor="let item of agentW9InfoForm.controls.w9Info?.controls; let i = index;">
<div class="border rounded p-3 position-relative" [formGroupName]="i">
<button class="btn btn-link btn-close position-absolute" (click)="deleteW9Details(i,item)"
[class.disabled]="isReadOnly"><i class="fas fa-times fa-lg"></i></button>
<div class="row">
<div class="col-6">
<div class="form-group">
<label for="">Tax ID Number <span class="text-danger">*</span></label>
<input type="text" class="form-control {{w9ReadOnly ? 'link-disabled' : ''}}"
placeholder="Tax ID Number" name="taxId" formControlName="taxId" maxlength="50"
autocomplete="new-tx" [ngClass]="{ 'is-invalid': submitted && item.controls.taxId.errors }"
allowNumberOnly>
<div *ngIf="submitted && item.controls.taxId.errors" class="invalid-feedback">
<div *ngIf="item.hasError('required', 'taxId')">Tax Id is required</div>
</div>
</div>
</div>
<div class="col-6">
<div class="form-group">
<label for="">Signature Date <span class="text-danger">*</span></label>
<input type="text" class="form-control {{w9ReadOnly ? 'link-disabled' : ''}}" placeholder="MM/DD/YYYY"
name="signatureDate" formControlName="signatureDate"
[ngClass]="{ 'is-invalid': submitted && item.controls.signatureDate.errors }">
<div *ngIf="submitted && item.controls.signatureDate.errors" class="invalid-feedback">
<div *ngIf="item.controls.signatureDate.errors.required">Signature Date is required</div>
</div>
</div>
</div>
<div class="col-6">
<div class="form-group ">
<label for="">Business Type <span class="text-danger">*</span></label>
<select class="custom-select {{w9ReadOnly ? 'link-disabled' : ''}}" name="businessType"
formControlName="businessType"
[ngClass]="{ 'is-invalid': submitted && item.controls.businessType.errors }">
<option value=''>Select Business Type </option>
<option *ngFor="let businessType of detailsSelectDropDown?.W9BusinessType"
[value]='businessType.id'>
{{businessType.value}}</option>
</select>
<div *ngIf="submitted && item.controls.businessType.errors" class="invalid-feedback">
<div *ngIf="item.controls.businessType.errors.required">Business Type is required</div>
</div>
</div>
</div>
</div>
<div class="row" *ngIf="!hideUpload">
<div class="col">
<div class="form-group" >
<label for="">Upload File</label>
<div class="form-control" (click)="fileInput.click()" appDragDrop
(onFileDropped)="uploadFile($event,item.controls)">
<input hidden type="file" #fileInput (change)="uploadFile($event,item.controls)"
class="custom-file-input" id="uploadFile" formControlName="fileName">
<span>{{ item.controls.fileName.value?.slice(12) }}</span>
</div>
</div>
</div>
<div class="col-6">
<button type="button" class="btn btn-outline-primary mt-4" id="" (click)="upload()">Upload</button>
</div>
</div>
<div class="row">
<div class="col d-flex justify-content-end align-items-end">
<button class="btn btn-primary delbtn" (click)="saveW9Details(item.controls,i)"
[class.disabled]="isReadOnly">
Save
</button>
</div>
</div>
</div>
</form>
<div class="row mt-3">
<div class="col d-flex justify-content-end align-items-end">
<div class="form-group {{addButtonDisable ? 'link-disabled' : ''}}">
<button type="button" class="btn btn-outline-primary {{isReadOnly ? 'link-disabled' : ''}}"
(click)="addW9Details()"><i class="fas fa-plus"></i> Add New</button>
</div>
</div>
</div>
</div>
TS:
deleteW9Details(i) {
let error = !this.getFormData.invalid && this.getFormData.dirty
if(!error == true) {
this.getFormData.removeAt(i);
} else {
alert('are you sure to delete')
}
}
HTML:
<button class="col-2 pull-left m-b10 m-t10 delbtn" (click)="deleteW9Details(i)"
[class.disabled]="isReadOnly">
Delete
</button>
<button class="col-2 pull-left m-b10 m-t10 delbtn" (click)="saveW9Details(item.controls)"
[class.disabled]="isReadOnly">
Save
</button>
TS FormArray:
private w9InfoFormInit() {
if (!this.groupCode && !this.agentCode) {
// Add
this.agentW9InfoForm = this.FB.group({
w9Info: this.FB.array([this.createW9Information()])
})
} else {
//edit
this.agentW9InfoForm = this.FB.group({
w9Info:this.FB.array([])
})
}
if (this.mode == 1) {
this.agentW9InfoForm.disable()
this.isReadOnly = true;
}
}
editw9InfoDetails(w9,mode) {
let modes = mode
if("editMode" ) {
this.hideUpload = true;
this.saveUpload = false
} else {
this.hideUpload = false;
this.saveUpload =true
}
this.addButtonDisable = true;
const control = <FormArray>this.agentW9InfoForm.get('w9Info');
control.controls = [];
let info = [];
info.push(w9)
for (const emp of info) {
const grp = this.FB.group({
taxId: [emp.taxId, Validators.required],
signatureDate: [emp.signatureDate, [Validators.required]],
businessType: [emp.businessType, [Validators.required]],
fileName:[emp.fileName],
agentW9id:[emp.agentW9id],
originalFileName: [emp.originalFileName],
agentCode:[emp.agentCode],
id:[emp.id]
});
control.push(grp);
}
}
editw9(w9,mode) {
let error = !this.w9InfoDetails.invalid && this.w9InfoDetails.dirty
if(error != true) {
this.editw9InfoDetails(w9,mode)
} else {
this.notificationService.activate("Validation Message", "Are you sure to delete changes? ", "Yes").then(responseOK => {
if (responseOK) {
this.editw9InfoDetails(w9,mode)
}
});
}
}
Создание массива формы вместе с удалением и редактированием элементов строки,
public addW9Details() {
this.hideUpload = false;
this.w9ReadOnly = false;
if(this.agentDetailsList && this.agentDetailsList.w9Info) {
this.saveUpload = false;
} else {
this.saveUpload = true;
}
const control = <FormArray>this.agentW9InfoForm.get('w9Info');
if(this.agentDetailsList && this.agentDetailsList.w9Info) {
control.controls = [];
}
control.push(this.createW9Information());
this.addButtonDisable = true;
}
public deleteW9Details(i,item) {
let error = !this.w9InfoDetails.invalid && this.w9InfoDetails.dirty
if(!error == true) {
this.w9InfoDetails.removeAt(i);
this.addButtonDisable = false
} else {
this.notificationService.activate("Validation Message", "Are you sure to delete changes? ", "Yes").then(responseOK => {
if (responseOK) {
this.w9InfoDetails.removeAt(i);
this.addButtonDisable = false
}
});
}
}
public preventW9DetailsEmpty() {
if (!this.w9InfoDetails.length) {
let group = this.createW9Information();
group.reset();
this.agentW9InfoForm.setControl('w9Info', this.FB.array([group]));
}
}
public get w9InfoDetails(): FormArray {
return <FormArray>this.agentW9InfoForm.controls['w9Info'];
}
private createW9Information() {
return this.FB.group({
taxId: [null, Validators.required],
signatureDate: [null, Validators.required],
businessType: [null, Validators.required],
originalFileName: [''],
agentW9id:0,
fileName: [''],
agentCode:parseInt(this.agentbasicInfoForm.controls['agentCode'].value),
id:''
});
}
Сохранение вновь добавленного элемента строки / сохранение Редактировать элемент в сетке, здесь указан код детали:
saveW9Details(item, num) {
if(this.w9InfoDetails.invalid) {
this.notificationService.activate("Validation Message", "Please fill Tax Id Number,Signature Date, Business Type", "OK", false).then(responseOK => {
if (responseOK) {
}
});
} else {
this.addButtonDisable = false;
if(this.agentDetailsList && this.agentDetailsList.w9Info) {
if(item.agentW9id.value) {
for(var i=0;i<this.agentDetailsList.w9Info.length;i++){
let itembusinessName = this.detailsSelectDropDown.W9BusinessType.filter(x => x.id === parseInt(item.businessType.value));
if(this.agentDetailsList.w9Info[i].agentW9id===item.agentW9id.value){
this.agentDetailsList.w9Info[i].taxId=item.taxId.value;
this.agentDetailsList.w9Info[i].businessType=item.businessType.value;
this.agentDetailsList.w9Info[i].signatureDate=item.signatureDate.value;
this.agentDetailsList.w9Info[i].agentW9id = item.agentW9id.value;
this.agentDetailsList.w9Info[i].businessName = itembusinessName[0].value;
this.agentDetailsList.w9Info[i].id = itembusinessName[0].id;
// updated=true;
this.temporaryControls.push(this.agentDetailsList.w9Info[i])
}
}
}
else {
let itembusinessName = this.detailsSelectDropDown.W9BusinessType.filter(x => x.id === parseInt(item.businessType.value));
console.log(itembusinessName,"business")
let temp={
taxId:item.taxId.value,
signatureDate:item.signatureDate.value,
businessType: item.businessType.value,
agentW9id:item.agentW9id.value,
businessName: itembusinessName[0].value,
originalFileName:item.fileName.value?item.fileName.value.slice(12):'',
id: this.temporaryControls.length
}
if(this.agentDetailsList&& this.agentDetailsList.w9Info) {
this.agentDetailsList.w9Info.push(temp);
this.temporaryControls.push(temp)
}
console.log(this.temporaryControls,"dssdf")
}
}
else {
let itembusinessName = this.detailsSelectDropDown.W9BusinessType.filter(x => x.id === parseInt(item.businessType.value));
console.log(itembusinessName,"business")
let temp={
taxId:item.taxId.value,
signatureDate:item.signatureDate.value,
businessType: item.businessType.value,
agentW9id:item.agentW9id.value,
businessName: itembusinessName[0].value,
originalFileName:item.fileName.value?item.fileName.value.slice(12):'',
id: this.temporaryControls.length
};
console.log(temp,"dsfdsg")
this.temporaryControls.push(temp)
}
console.log(this.temporaryControls,"dssdf")
this.w9InfoDetails.removeAt(item);
console.log(this.temporaryControls,"temp")
}
}