I want to create a nested form
from Data:
My Actual Data is:
mainObject = {
adminname: 'Saqib',
adminemail: '[email protected]',
users: [
{ user_type: 'Adult', count: 3 },
{ user_type: 'Child', count: 1 },
{ user_type: 'infant', count: 0 },
],
};
I want to show nested forms for these Counts in Users Array. like there should be 3 adult forms, 1 child form and no Infant form as infant count is 0. And these counts can be changed like there could be 0 child and 1 infant.
.html
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<input formControlName="name" placeholder="Enter Admin Name" />
<br />
<input formControlName="admin_email" placeholder="Enter Admin Email" />
<div formArrayName="users">
<div *ngFor="let pro of myForm.get('users').controls; let i = index">
<br />
<div [formGroupName]="i" style="border: 1px solid; padding: 10px">
<div>User Type: {{ pro.value.user_type }}</div>
User Name:<br />
<input type="text" formControlName="user_name" /> <br />
Email:<br />
<input type="text" formControlName="user_email" />
</div>
</div>
</div>
<p>
<button type="submit">Submit</button>
</p>
</form>
.ts
myForm: FormGroup;
mainObject = {
adminname: 'Saqib',
adminemail: '[email protected]',
users: [
{ user_type: 'Adult', count: 3 },
{ user_type: 'Child', count: 1 },
{ user_type: 'infant', count: 0 },
],
};
// I want to Show forms according to this users count with their Type:
// according to this data there should be 3 adult forms, 1 hchild form and no infant Form.
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.formInit();
}
formInit() {
this.myForm = this.fb.group({
name: '',
admin_email: '',
users: this.fb.array(
this.mainObject.users.map((e) => this.newUsers(e.user_type, e.count))
),
});
}
get users(): FormArray {
return this.myForm.get('users') as FormArray;
}
newUsers(t, c): FormGroup {
console.log(t, c);
return this.fb.group({
user_type: t,
user_name: '',
user_email: '',
});
}
onSubmit() {
console.log(this.myForm.value);
}
I have create example Stackblitz for better understanding:
CodePudding user response:
Perhaps you can achieve the concept as below:
Concept:
Create a dictionary with group by key:
user_type
and value: an Array with (number of) object(s) created based oncount
.Get the value from result 1, perform flatten nested array and add those objects into an array.
toFormUsers(users: any[]): any[] {
// Generate array by user_type
let userTypeGroup = users.reduce((accumulator, current) => {
accumulator[current.user_type] = accumulator[current.user_type] || [];
for (let i = 0; i < current.count; i )
accumulator[current.user_type].push({ user_type: current.user_type });
return accumulator;
}, {});
// Flatten array of array for userTypeGroup
return [].concat(
...Object.keys(userTypeGroup).map((x) => userTypeGroup[x])
);
}
And modify your FormGroup
to apply the method above by passing mainObject.users
.
this.myForm = this.fb.group({
name: '',
admin_email: '',
users: this.fb.array(
this.toFormUsers(this.mainObject.users).map((e) => this.newUsers(e.user_type, e.count))
),
});
CodePudding user response:
To create Nested array of Count in users array from mainObject
:
.ts
ngOnInit() {
this.formInit();
}
formInit() {
this.myForm = this.fb.group({
name: '',
admin_email: '',
users: this.fb.array([]),
});
this.mainObject.users.map((e) => {
if (e.count > 0) {
for (let i = 0; i < e.count; i ) {
this.addUser(e.user_type);
}
}
});
}
addUser(t) {
const userArray = <FormArray>this.myForm.controls['users'];
const newUser = this.initUser(t);
userArray.push(newUser);
}
initUser(t) {
return this.fb.group({
user_type: t,
user_name: '',
user_email: '',
});
}
get users(): FormArray {
return this.myForm.get('users') as FormArray;
}
newUsers(t, c): FormGroup {
console.log(t, c);
return this.fb.group({
user_type: t,
user_name: '',
user_email: '',
});
}