Search code examples
javascriptjsonangularangular7dynamicform

How to store selected checkbox's values in FormGroup in a Dynamic Form


I am getting form components from API. My code is able to generate HTML FORM from JSON. After generating the form and filling the data when I click on submit I am getting below JSON

{
  "Enter Your Name": "Abhishek",
  "Enter Your Empid": 55555,
  "Gender": "Male",
  "Skills": true
}

My HTML FORM from where I am getting data from user:

<mat-card>
  <h1 >{{templateName}}</h1>
  <br>
<form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()">
  <div *ngFor="let form_elem of formTemplate">
  <div [ngSwitch]="form_elem.questionType">
    <div *ngSwitchCase="'Text'">
      <label>{{form_elem.questionTitle}}: </label>
      <mat-form-field class="full-width">
      <input matInput type="text" placeholder="{{form_elem.questionTitle}}" formControlName="{{form_elem.questionTitle}}"/>
      </mat-form-field>
    </div>
    <div *ngSwitchCase="'Number'">
      <label>{{form_elem.questionTitle}}: </label>
      <mat-form-field class="full-width">
      <input matInput type="Number" placeholder="{{form_elem.questionTitle}}" formControlName="{{form_elem.questionTitle}}"/>
      </mat-form-field>
    </div>

      <div *ngSwitchCase="'Single choice'">
       <label>{{form_elem.questionTitle}}: </label><br><br>
       <mat-radio-group class = "tp-radio-group" formControlName="{{form_elem.questionTitle}}">
       <mat-radio-button class = "tp-radio-button"
      *ngFor = "let options of form_elem.questionGroup.options" [value] = "options.optionText">
      {{options.optionText}}  &nbsp;
   </mat-radio-button> 
</mat-radio-group>
</div>

<div *ngSwitchCase="'Multi choice'">
       <label>{{form_elem.questionTitle}}: </label><br><br>
<mat-checkbox class = "tp-margin" *ngFor = "let options of form_elem.questionGroup.options"  formControlName = "{{form_elem.questionTitle}}">
  {{options.optionText}} &nbsp; </mat-checkbox>
</div>


<br>
  </div>
  </div> 
  <button mat-fab value="Submit">Submit</button>
</form>
</mat-card> 

As can be seen for Text, Number and Radio it is giving values but for checkbox component that is "Skills" it is showing true. I want selected checkboxes value instead of "true".

HTML FORM is dynamic that is generated from below JSON

"surveyQuestions": [
    {
      "questionTitle": "Enter Your Name",
      "questionType": "Text",
      "questionGroup": {}
    },
    {
      "questionTitle": "Enter Your Empid",
      "questionType": "Number",
      "questionGroup": {}
    },
    {
      "questionTitle": "Gender",
      "questionType": "Single choice",
      "questionGroup": {
        "options": [
          {
            "optionText": "Male"
          },
          {
            "optionText": "Female"
          }
        ],
        "showRemarksBox": false
      }
    },
    {
      "questionTitle": "Skills",
      "questionType": "Multi choice",
      "questionGroup": {
        "options": [
          {
            "optionText": "C"
          },
          {
            "optionText": "Java"
          },
          {
            "optionText": "Mule"
          }
        ],
        "showRemarksBox": false
      }
    }
  ]

In My Component.ts

ngOnInit() {
 let group={}    
    this.form_template.forEach(input_template=>{
      group[input_template.questionTitle]=new FormControl('');  
    })
    this.myFormGroup = new FormGroup(group);
}
 onSubmit() {
    console.log(JSON.stringify(this.myFormGroup.value));
  }

Please suggest me how to get that checkbox's values in json.


Solution

  • You are using the same form control for all you checkboxes named 'Skills' in this example that's why you are getting only one submitted value. I suggest to use a form control for each checkbox and map your data after form submission.

    ts

    ...
    
    ngOnInit() {
     let group={}    
        this.form_template.forEach(input_template=>{
           if (input_template.questionType === "Multi choice"){
            let form_group = {} ;
             input_template.questionGroup.options.forEach(option => {
                   form_group[option.optionText]=new FormControl('');
                  })
          group[input_template.questionTitle]=new FormGroup(form_group);
          } else {
          group[input_template.questionTitle]=new FormControl('');  
         }
        })
        this.myFormGroup = new FormGroup(group);
    }
    

    html

     ...
        <div *ngSwitchCase="'Multi choice'">
               <label>{{form_elem.questionTitle}}: </label><br><br>
    <div [formGroupName]="form_elem.questionTitle">
        <mat-checkbox class = "tp-margin" *ngFor = "let options of form_elem.questionGroup.options"  formControlName = "{{options.optionText}}">
          {{options.optionText}} &nbsp; </mat-checkbox>
        </div>
    </div>
        ...