Reputation: 102
I have the following html in my component, Im trying to generate a form dynamically based on the number of selected elements that can be from 0 to N
<form #form="ngForm" id="formGroupExampleInput">
<div class="col-xs-5 col-md-offset-1">
<a class="list-group-item clearfix" *ngFor="let selectedApi of selectedApps;let i=index">
<div class="pull-right">
<button type="button" class="close" (click)="removeFromSelectedApi(i)">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="pull-left">
<h4 class="list-group-item-heading">{{selectedApi.url}}</h4>
<p class="list-group-item-text">{{selectedApi.method}}</p>
<div class="form-group">
<input type="text" class="form-control" id="formGroupExampleInput" name="{{i}}-users"
placeholder="number of users" ngModel>
<input type="text" class="form-control" id="formGroupExampleInput" name="{{i}}-rpm"
placeholder="request per minute between all users" ngModel>
</div>
<hr>
<div class="form-group" *ngFor="let requiredHeader of selectedApi.requiredHeaders; let in=index">
<input type="text" class="form-control" id="formGroupExampleInput" name="{{i}}-{{requiredHeader}}"
placeholder={{requiredHeader}} ngModel>
</div>
<div class="form-group" *ngFor="let requiredParameter of selectedApi.requiredParametersInURL; let in=index">
<input type="text" class="form-control" id="formGroupExampleInput" name="{{i}}-{{requiredParameter}}"
placeholder={{requiredParameter}} ngModel>
</div>
<div class="form-group" *ngIf="selectedApi.method=='POST' || selectedApi.method=='PUT' || selectedApi.method=='DELETE'">
<!-- <textarea class="form-control" id="formGroupExampleInput" name="{{i}}-{{requiredHeader}}" rows=20></textarea> -->
<textarea class="form-control"
rows="5"
name="{{i}}-body"
id="{{i}}-body"
placeholder="body" ngModel></textarea>
</div>
</div>
</a>
</div>
<div class="pull-right">
<button class="btn btn-success btn-lg" (click)="onSubmitTest(form)">Submit</button>
</div>
</form>
when I create new elements and submit the form I get as a result on form.value something like this:
0-auth-system: "c"
0-auth-user: "d"
0-auth-user-id: "e"
0-email: "h"
0-module: "g"
0-rpm: "b"
0-task-client-key: "f"
0-users: "a"
1-auth-system: "k"
1-auth-user: "l"
1-auth-user-id: "m"
1-rpm: "j"
1-task-client-key: "n"
1-users: "i"
and what I want in fact is an output like the following since it is easier for processing and I dont want to develop code to parse to the previous structure if I can have it as an array:
[
{
auth-system: "c"
,auth-user: "d"
,auth-user-id: "e"
,email: "h"
,module: "g"
,rpm: "b"
,task-client-key: "f"
,users: "a"
},
{
auth-system: "k"
,auth-user: "l"
,auth-user-id: "m"
,rpm: "j"
,task-client-key: "n"
,users: "i"
}
]
Anyone knows how I can achieve this?
Upvotes: 0
Views: 2795
Reputation: 728
you can declare the input names as array like this:
<!-- ... -->
<div *ngFor="let selectedApi of selectedApps;let i=index">
<input type="text" [attr.name]="'obj['+i+'][users]'">
<input type="text" [attr.name]="'obj['+i+'][module]'">
<input type="text" [attr.name]="'obj['+i+'][email]'">
</div>
<!-- ... -->
So you get an array of objects.
Upvotes: 0
Reputation: 57909
@mosi98, you needn't create a formGroup with property items, and "items" was a formArray
@Component({
selector: 'my-app',
template:`
<!--see that, form is a FormArray, but we use [formGroup] too-->
<form [formGroup]="form">
<div *ngFor="let group of form.controls;let i=index">
<div [formGroup]="group">
<input formControlName="name"/>
<input formControlName="grade_list"/>
</div>
</div>
</form>
<hr/>
<pre>
{{form?.value|json}}
</pre>
`,
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
items=[
{name: "c",grade_list: "d",min_grade: "e",max_grade: "h"},
{name: "c",grade_list: "d",min_grade: "e",max_grade: "h"},
{name: "c",grade_list: "d",min_grade: "e",max_grade: "h"}]
form:FormArray=new FormArray(this.buildForm(this.items))
//return an array of FormGroup
buildForm(items:any[]):FormGroup[]
{
return items.map(x=>this.buildItem(x))
}
//return a formGroup
buildItem(item: any):FormGroup {
return new FormGroup({
name: new FormControl(item.name),
grade_list: new FormControl(item.grade_list),
min_grade: new FormControl(item.min_grade),
max_grade: new FormControl(item.max_grade)
});
}
}
Upvotes: 0
Reputation: 653
<form [formGroup]="myFormUnit" (ngSubmit)="submit()">
<table class="table table-lessons table-striped table-hover">
<thead>
<tr>
<th></th>
<th>Field A</th>
<th>Field B</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of myFormUnit.get('items').controls; let i=index" [formGroup]="item">
<td>
<input type="text" class="form-control lablel border-less" [attr.id]="'name'+i" formControlName="name"
disabled="disabled">
<input type="number" class="form-control hidden" readonly="readonly" hidden="hidden"
[attr.id]="'grade_list'+i" formControlName="grade_list"
style="visibility: hidden;">
</td>
<td>
<input type="number" class="form-control" [attr.id]="'min_grade'+i" formControlName="min_grade">
</td>
<td>
<input type="number" class="form-control" [attr.id]="'max_grade'+i" formControlName="max_grade">
</td>
</tr>
</tbody>
</table>
</form>
and ts file is :
myFormUnit: FormGroup;
protected onInitializeComponent() {
this.myFormUnit = this.fb.group({
items: this.fb.array([])
});
}
private fillUnitform(input?: any) {
this.myFormUnit = this.fb.group({
items: this.fb.array(
[]
// [this.buildItem(null, 'lesson'), this.buildItem(null, 'lesson')]
)
});
this.gradeListItems.forEach(item => {
if (item.value !== "12") {
const tmp: Array<any> = this.gridData.data;
tmp.forEach(element => {
if (element.lesson_type === item.value) {
item.value = element.num_unit;
}
});
const fbb = this.myFormUnit.get("items") as FormArray;
if (item.value !== "12") {
const newItem = {
name: item.text,
grade_list: item.value,
min_grade: item.min_grade,
max_grade: item.max_grade
};
if (input) {
// if (input.length > 0)
input.forEach((element: any) => {
if (element.grade_list === item.value) {
newItem.min_grade = element.min_grade;
newItem.max_grade = element.max_grade;
}
});
}
fbb.push(this.fb.group(this.buildItem(newItem)));
}
}
});
}
buildItem(item: any) {
return {
name: new FormControl(item.name),
grade_list: new FormControl(item.grade_list),
min_grade: new FormControl(item.min_grade),
max_grade: new FormControl(item.max_grade)
};
}
submit(){
this.myFormUnit.value.items.forEach(
(item): any => {
if (item.min_grade || item.max_grade) {
grade_list.push({
grade_list: item.grade_list,
min_grade: item.min_grade,
max_grade: item.max_grade
});
}
}
);
}
Upvotes: 2
Reputation: 221
I had a similar problem.
I'm sure it'll give you an idea if you read it carefully
Upvotes: 1