How to combine two parts of single form in angular

2020-04-17 06:32发布

问题:

I am making angular application with angular dynamic form where i am loading data for dynamic form through JSON..

JSON has two parts such as part 1 and part 2,

  jsonDataPart1: any = [
    {
      "elementType": "textbox",
      "class": "col-12 col-md-4 col-sm-12",
      "key": "project_name",
      "label": "Project Name",
      "type": "text",
      "value": "",
      "required": false,
      "minlength": 3,
      "maxlength": 20,
      "order": 1
    },
    {
      "elementType": "textbox",
      "class": "col-12 col-md-4 col-sm-12",
      "key": "project_desc",
      "label": "Project Description",
      "type": "text",
      "value": "",
      "required": true,
      "order": 2
    }
  ]

  jsonDataPart2: any = [
            {
          "elementType": "textbox",
          "class": "col-12 col-md-4 col-sm-12",
          "key": "property_one",
          "label": "Property One",
          "type": "text",
          "value": "",
          "required": true,
          "order": 3
        },
        {
          "elementType": "textbox",
          "class": "col-12 col-md-4 col-sm-12",
          "key": "property_two",
          "label": "Property Two",
          "type": "text",
          "value": "",
          "required": true,
          "order": 4
        },
        {
          "elementType": "radio",
          "class": "col-12 col-md-3 col-sm-12",
          "key": "property_required",
          "label": "Property Required",
          "options": [
            {
              "key": "required",
              "value": "Required"
            },
            {
              "key": "not_required",
              "value": "Not Required"
            }
          ],
          "order": 5
        },
        {
          "elementType": "checkbox",
          "class": "col-12 col-md-3 col-sm-12",
          "key": "property_check",
          "label": "Property Required",
          "order": 6
        }
  ]

And i am loading the JSON as separate part like,

  ngOnInit() {
    //Building form first part
    this.questions = this.service.getQuestions(this.jsonDataPart1)
    this.form = this.qcs.toFormGroup(this.questions);

        //Building form second part
    this.questionsPartTwo = this.service.getQuestions(this.jsonDataPart2)
    this.formPartTwo = this.qcs.toFormGroupPartTwo(this.questionsPartTwo);
  }

And HTML looks like,

<div>
    <form (ngSubmit)="onSubmit()" [formGroup]="form">

 <h4> <b> Form Part One begins from here </b> </h4>
        <div *ngFor="let question of questions" class="form-row">
            <ng-container>
                <app-question [question]="question" [form]="form"></app-question>
            </ng-container>
        </div>

 <h4> <b> Form Part Two begins from here </b> </h4>

    <div *ngFor="let partTwo of questionsPartTwo">
                <ng-container>
                <app-question [question]="partTwo" [form]="formPartTwo"></app-question>

            </ng-container>
        </div>

        <div class="form-row">
            <button type="submit" [disabled]="!form.valid">Save</button>
    </div>
  </form> <br>

  <pre>
{{form?.value|json}}
</pre>
</div>

I need to combine these two and need to get single output for the whole single form..

In my real application i am having two json data and loading each separately and assigning form so please dont break out the part one and part two json..

Let me stop the code here as its getting long you might get confused..

Here is a working stackblitz: https://stackblitz.com/edit/angular-x4a5b6-2rykpo

Just take a workaround dynamic-form.component.ts and dynamic-form.component.html You will get clear what i have done..

Kindly help me to load the splitted JSON to this.service.getQuestions and get two parts and join both in final output to submit..

If i am wrong in approach kindly help me to correct it as i am new in angular and dynamic form.. It needs to be in angular dynamic form and json loading only no change in it..

Help i am expecting is from combining both parts 1 and 2 while submitting form..

Please help me i am stucking for a long to come out of it..

回答1:

You can take several aproach

1.-Create a formJoin that was {form1:questions of form1,form2:questions of form2}

In your ngOnInit

formJoin:FormGroup;
ngOnInit()
{
    this.questions = this.service.getQuestions(this.jsonDataPart1)
    this.form = this.qcs.toFormGroup(this.questions);

    this.questionsPartTwo = this.service.getQuestions(this.jsonDataPart2)
    this.formPartTwo = this.qcs.toFormGroup(this.questionsPartTwo);

    this.formJoin=new FormGroup({form1:this.form,form2:this.formPartTwo})
}

//In your .html 
<form (ngSubmit)="onSubmit()" [formGroup]="formJoin">

2.-Join the question in an unique json

this.allquestions=this.service.getQuestions(
        this.jsonDataPart1.concat(this.jsonDataPart2));
this.formJoin2=this.qcs.toFormGroup(this.allquestions);
//get the first question.key in the second form
this.questionBreak=this.jsonDataPart2[0].key;

//In your .html
<form  (ngSubmit)="onSubmit()" [formGroup]="formJoin2">

 <h4> <b> An uniq Form </b> </h4>
    <div *ngFor="let question of allquestions" class="form-row">
       <!--make a break fro the secondForm-->
       <ng-container *ngIf="question.key==questionBreak">
           <h4> <b> Form Part Two begins from here </b> </h4>
       </ng-container>
        <ng-container>
            <app-question [question]="question" [form]="formJoin2"></app-question>
        </ng-container>
    </div>
 </form>

IMPORTANT NOTE: You needn't have two functions in service toFormGroup and toFormGroupPartTwo. If you see is the same function, you "feed" the function with different arguments, but is the same function.

In the stackblitz has the two options together

Update update code to make a break,



回答2:

Use Top level form and wrap your child form inside the parent form and use provider to use existing Form

Parent.component.html

<form [formGroup]="form" (ngSubmit)="onClick();">
    <h1>Part1</h1>
    <div class="row" formArrayName="part1" *ngFor="let c of form['controls']['part1']['controls'];let i =index">
        <div class="col">
            <input [attr.type]="jsonDataPart1[i].type"
        class="form-control" [attr.placeholder]="jsonDataPart1[i].label"
         [formControlName]="i" >
    </div>
  </div>

  <app-part2 [part2]="jsonDataPart2">
     <h1>Part2</h1>
  </app-part2>
<br>
<button class="btn btn-primary">Save</button>
</form>

child.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { FormGroup, FormControl, ControlContainer, FormGroupDirective, FormArray } from '@angular/forms';
@Component({
  selector: 'app-part2',
  templateUrl: './part2.component.html',
  styleUrls: ['./part2.component.css'],
  viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class Part2Component implements OnInit {
  @Input('part2') part2;
  part2Form;
  constructor(private parentForm: FormGroupDirective) { }

  ngOnInit() {
    this.part2Form = this.parentForm.form;
    const control = this.part2.map(d => new FormControl());
    this.part2Form.addControl('part2F', new FormGroup({
      part2: new FormArray(control)
    }))
  }
}

Example:https://stackblitz.com/edit/angular-xrrabj