Tengo que crear dinámicamente un formulario con datos recibidos del servidor con la opción de agregar y eliminar campos de entrada para cada campo de entrada existente.
Estos son los datos que recibo del servidor
documents = [{id: 1, service_item_id: 311101, name: 'document 1'}, {id: 2, service_item_id: 311102,, name: 'document 2'}, {id: 3, service_item_id: 311103,, name: 'document 3'}, {id: 4, service_item_id: 311104,, name: 'document 4'}]
He creado una función para crear el formulario
createControls(controls) {
console.log(controls);
for (let control of controls) {
const newFormControl = new FormControl();
this.myForm.addControl(control.service_item_id, newFormControl);
}
}
this.createControls(this.documents);
Y en el Html he creado esto
<form [formGroup]="myForm" (ngSubmit)="submitForm()">
<div *ngFor="let c of documentation; let index = index">
<label>
{{ c.name}}
</label>
<input type="number" [formControlName]="c.service_item_id" [placeholder]="c.name" />
<button class="btn btn-primary btn-sm" (click)="add(c.service_item_id)">Add</button>
<button class="btn btn-primary btn-sm" (click)="remove(c.service_item_id, index)">Remove</button>
</div>
<button type="submit" class="btn btn-primary btn-small">Submit</button>
</form>
Mis funciones de agregar y quitar son
add(item): void {
(this.myForm.get(item) as FormArray).push(
this.fb.control(null)
);
}
remove(item, index) {
(this.myForm.get(item) as FormArray).removeAt(index);
}
Solo se está creando el formulario, pero los botones para agregar y eliminar no funcionan.
Por favor ayúdenme a resolver este problema.
Gracias de antemano
------------------------------------
Creo que lo que funcionará mejor para su situación es utilizar FormArray. ConFormArray puede insertar y eliminar elementos tal como lo haría con una matriz normal
myForm = this.fb.group({
documents: this.fb.array([])
});
get documentsControl(): FormArray {
return this.myForm.get("documents") as FormArray;
}
documents = [
{ id: 1, service_item_id: 311101, name: "document 1" },
{ id: 2, service_item_id: 311102, name: "document 2" },
{ id: 3, service_item_id: 311103, name: "document 3" },
{ id: 4, service_item_id: 311104, name: "document 4" }
];
ngOnInit() {
this.documents.forEach(document =>
this.documentsControl.push(
this.fb.group({
id: [document.id],
name: [document.name],
service_item_id: [document.service_item_id]
})
)
);
}
constructor(private fb: FormBuilder) {}
submitForm() {}
add() {
this.documentsControl.push(
this.fb.group({
id: [null],
name: [null],
service_item_id: [null]
})
);
}
remove(index) {
this.documentsControl.removeAt(index);
}
para agregar elementos usamos push mientras que para eliminar elementos usamos removeAt
A continuación se muestra el html
<form [formGroup]="myForm" (ngSubmit)="submitForm()">
<ng-container formArrayName='documents'>
<div *ngFor="let c of documentsControl.controls; let index = index" [formGroupName]='index'>
<label>
{{ c.value.name}}
</label>
<input type="number" formControlName="service_item_id" placeholder="name" />
<button class="btn btn-primary btn-sm" (click)="add()">Add</button>
<button class="btn btn-primary btn-sm" (click)="remove(index)">Remove</button>
</div>
</ng-container>
<button type="submit" class="btn btn-primary btn-small">Submit</button>
</form>
Editar
Para agregar elementos debajo del botón en el que se hizo clic, podemos implementar insert()
insert(index) {
const serviceItenId = this.documentsControl.controls[index].get('service_item_id').value
this.documentsControl.insert(
index + 1,
this.fb.group({
id: [null],
name: [null],
service_item_id: [serviceItenId]
})
);
}
He actualizado la siguiente demostración para reflejar esto
Ver demostración
3
Gracias Owen, pero los campos de entrada se agregan al final de la página. ¿Hay alguna manera de agregarlo justo debajo del elemento en el que se hizo clic?
- Ex sitio
27 de marzo de 2021 a las 4:05
service_item_id viene como nulo, ¿hay alguna manera de replicarlo en la función de inserción? Gracias de antemano por tu ayuda
Ex-sitio
28/03/2021 a las 15:19
1
@Exsite ve la función de inserción actualizada()
-Owen Kelvin
28/03/2021 a las 15:57
------------------------------------
Creo que quieres hacer algo como
(this.myForm.controls as FormArray).push(this.fb.control(/*your item*/)
Y lo mismo para eliminar