I have succeeded in creating multiple forms based on the value from the dropdown list, but I am not able to save the data from the input element into database. If my dropdown list displays the value 5, then 5 forms with the same number of input element will be shown and be ready for data entry. My problem is how to save these data from one or multiple forms textbox into database.
Service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Offspring } from './animal';
@Injectable({
providedIn: 'root'
})
export class AnimalService {
readonly Urloffspring = 'api/AnimalAPI'
constructor(private http:HttpClient) { }
formOffspring:Offspring = new Offspring();
formSubmitted: boolean = false;
postOffspring(formOffspring: any){
console.log(formOffspring);
return this.http.post<any>(this.Urloffspring, formOffspring);
}
}
**Component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { AnimalService } from '../animal.service';
@Component({
selector: 'app-fetch-data',
templateUrl: './fetch-data.component.html',
})
export class FetchDataComponent implements OnInit {
reactForm: FormGroup;
public forms: FormGroup[] = [];
public unitData: Object[] = [
{ Id: 'Form1', Form: '1' },
{ Id: 'Form2', Form: '2' },
{ Id: 'Form3', Form: '3' },
{ Id: 'Form4', Form: '4' },
{ Id: 'Form5', Form: '5' },
];
public val: string = "1";
public unitFields: Object = { text: 'Form', value: 'Form' };
public unitWaterMark: string = '';
ngOnInit(): void {
this.generateForms(1);
}
generateForms(count: number): void {
this.forms = [];
for (let i = 0; i < count; i++) {
this.forms.push(
this.fb.group({
Id: (0),
Animal: (null),
Tagno: (null),
})
)}
}
dropdownChange(args: any): void {
const selectedCount = parseInt(args.value, 10);
if (!isNaN(selectedCount)) {
this.generateForms(selectedCount);
}
}
onSubmit(): void {
if (this.forms.every(form => form.valid)) {
const allFormData = this.forms.map(form => form.value);
}
// ... validation code ...
this.service.postOffspring(this.forms).subscribe({
next: (response) => {
console.log('Forms saved successfully', response);
},
error: (error) => {
console.error('Error saving forms', error);
}
});
}
onSubmitAll() {
let allValid = true;
const allFormData = [];
this.forms.forEach((form, index) => {
if (form.valid) {
allFormData.push(form.value);
} else {
form.markAllAsTouched();
allValid = false;
}
});
if (allValid) {
// here can you get the all forms data and send it to backend using the angular service.
}
}
}
constructor(private fb: FormBuilder, private service: AnimalService ) {}
}
html
<div class="col-lg-12 control-section">
<div class="content-wrapper" style="max-width: 600px; margin: 0 auto;">
<ejs-dropdownlist
id="Unt"
[dataSource]="unitData"
type="text"
name="Unt"
[fields]="unitFields"
placeholder="Mark All"
(change)="dropdownChange($event)"
[query]="unitquery"
floatLabelType="Auto"
[value]="val"
>
</ejs-dropdownlist><br><br>
<div *ngFor="let form of forms; let i = index">
<form [id]="'formId' + i" [formGroup]="form" (ngSubmit)="onSubmit(form, i)" class="form-horizontal" novalidate>
<div class="form-title">
<span>Customer {{ i + 1 }}</span>
</div>
<div class="form-group">
<div class="e-float-input">
<input [id]="'Id' + i" formControlName="Id" />
<span class="e-float-line"></span>
<label [for]="'Id' + i" class="e-float-text"></label>
</div>
</div>
<div class="form-group">
<div class="e-float-input">
<input [id]="'Animal' + i" type="text" formControlName="Animal" />
<span class="e-float-line"></span>
<label [for]="'Animal' + i" class="e-float-text">Animal</label>
</div>
</div>
<div class="form-group">
<div class="e-float-input">
<input [id]="'Tagno' + i" type="text" formControlName="Tagno" />
<span class="e-float-line"></span>
<label [for]="'Tagno' + i" class="e-float-text">Tagno</label>
</div>
</div>
</form>
</div>
Backend
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Project1.Models;
using System.Data.SqlClient;
using System.Data;
using Microsoft.Extensions.Configuration;
namespace Project1.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AnimalAPIController : ControllerBase
{
private dbContext _context;
public AnimalAPIController(dbContext context, IConfiguration configuration)
{
_context = context;
}
[HttpPost]
public void Post([FromBody] Animaldb book)
{
_context.Animaldb.Add(book);
_context.SaveChanges();
}
}
}
We should use the FormArray angular element, to initialize an array which contains a group of form group.
We can just loop through the controls and initialize the individual form groups of the form array.
The below is the main code we need to note:
<form
[formGroup]="reactForm"
(ngSubmit)="onSubmit()"
class="form-horizontal"
novalidate
>
<div formArrayName="data">
<div *ngFor="let form of formArray.controls; let i = index">
<div [formGroupName]="i">
<div class="form-title">
...
In the above code, we initialize a single form, the container with formArrayName will define the form array, that will contain the individual sub form groups.
Then we loop through the controls of the form array and initialize the group using [formGroupName]="i" this will update the individual form groups with the data filled.
When we generate the form using the method, we simply loop through the count and push the generated form controls inside the form array using push.
generateForms(count: string): void {
this.reactForm = this.fb.group({
data: new FormArray([]),
});
for (let i = 0; i < +count; i++) {
this.formArray.push(
this.fb.group({
Id: new FormControl(0),
Animal: new FormControl(null),
Tagno: new FormControl(null),
})
);
}
}
The submit method will simplified to this.reactForm.invalid to check the forms validity and this.reactForm.markAllAsTouched(); to mark the entire form as touched.
onSubmit(): void {
if (this.reactForm.invalid) {
this.reactForm.markAllAsTouched();
}
alert(JSON.stringify(this.reactForm.value, null, 4));
// ... validation code ...
this.service.postOffspring(this.reactForm.value).subscribe({
next: (response) => {
console.log('Forms saved successfully', response);
},
error: (error) => {
console.error('Error saving forms', error);
},
});
}
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import {
ReactiveFormsModule,
FormsModule,
FormGroup,
FormArray,
FormControl,
FormBuilder,
} from '@angular/forms';
import { Injectable } from '@angular/core';
import { HttpClient, provideHttpClient } from '@angular/common/http';
import { CommonModule } from '@angular/common';
export class Offspring {}
@Injectable({
providedIn: 'root',
})
export class AnimalService {
readonly Urloffspring = 'api/AnimalAPI';
constructor(private http: HttpClient) {}
formOffspring: Offspring = new Offspring();
formSubmitted: boolean = false;
postOffspring(formOffspring: any) {
console.log(formOffspring);
return this.http.post<any>(this.Urloffspring, formOffspring);
}
}
@Component({
selector: 'app-root',
imports: [ReactiveFormsModule, FormsModule, CommonModule],
templateUrl: './main.html',
})
export class App {
reactForm!: FormGroup;
public unitData: any[] = [
{ Id: 'Form1', Form: '1' },
{ Id: 'Form2', Form: '2' },
{ Id: 'Form3', Form: '3' },
{ Id: 'Form4', Form: '4' },
{ Id: 'Form5', Form: '5' },
];
public val: string = '1';
public unitFields: Object = { text: 'Form', value: 'Form' };
public unitWaterMark: string = '';
constructor(private fb: FormBuilder, private service: AnimalService) {}
ngOnInit(): void {
this.generateForms('1');
}
generateForms(count: string): void {
this.reactForm = this.fb.group({
data: new FormArray([]),
});
for (let i = 0; i < +count; i++) {
this.formArray.push(
this.fb.group({
Id: new FormControl(0),
Animal: new FormControl(null),
Tagno: new FormControl(null),
})
);
}
}
get formArray() {
return this.reactForm.get('data') as FormArray;
}
onSubmit(): void {
if (this.reactForm.invalid) {
this.reactForm.markAllAsTouched();
}
alert(JSON.stringify(this.reactForm.value, null, 4));
// ... validation code ...
this.service.postOffspring(this.reactForm.value).subscribe({
next: (response) => {
console.log('Forms saved successfully', response);
},
error: (error) => {
console.error('Error saving forms', error);
},
});
}
}
bootstrapApplication(App, {
providers: [provideHttpClient()],
});
<div class="col-lg-12 control-section">
<div class="content-wrapper" style="max-width: 600px; margin: 0 auto">
<select [(ngModel)]="val" (change)="generateForms(val)">
<option *ngFor="let item of unitData" [value]="item.Form">
{{item.Form}}
</option>
</select>
<form
[formGroup]="reactForm"
(ngSubmit)="onSubmit()"
class="form-horizontal"
novalidate
>
<div formArrayName="data">
<div *ngFor="let form of formArray.controls; let i = index">
<div [formGroupName]="i">
<div class="form-title">
<span>Customer {{ i + 1 }}</span>
</div>
<div class="form-group">
<div class="e-float-input">
<input [id]="'Id' + i" formControlName="Id" />
<span class="e-float-line"></span>
<label [for]="'Id' + i" class="e-float-text"></label>
</div>
</div>
<div class="form-group">
<div class="e-float-input">
<input
[id]="'Animal' + i"
type="text"
formControlName="Animal"
/>
<span class="e-float-line"></span>
<label [for]="'Animal' + i" class="e-float-text">Animal</label>
</div>
</div>
<div class="form-group">
<div class="e-float-input">
<input [id]="'Tagno' + i" type="text" formControlName="Tagno" />
<span class="e-float-line"></span>
<label [for]="'Tagno' + i" class="e-float-text">Tagno</label>
</div>
</div>
</div>
</div>
</div>
<button type="submit">submit</button>
</form>
</div>
</div>