Data binding in dynamically created ng-select2 contorls in reactive form formarrays - angular 8

Viewed 240

I need to bind data, fetching from the server, to ng-select2 controls(ng-select2-component). ng-Select2 controls are dynamically created inside form-array controls of a from-group.

The issue I am getting is, I can submit the select2 values to server, but when I try to show that data in the selec2 controllers, is not working.

Angular 8

Here is my code; .html

  <form novalidate [formGroup]="overTimeRuleForm" (ngSubmit)="save()">

        <div formArrayName="overTimeRules">
            <div *ngFor="let criteria of overTimeRuleForm.get('overTimeRules')['controls']; let i= index;">
                <div class="row " [formGroupName]="i">
                   
                    <div class="col-6 col-sm-4 col-md-2 col-lg-3">
                      <div class="form-group row">
                        <div class="col-2 text-right"><label for="workingDays" i18n="@@config_timperiods_start_Time">Day</label>
                        </div>
                        <div class="col-10">
                            <div class="form-group">                                 
                              <select2 [data]="workingDays" formControlName="workingDay"  (update)="onTagChanged(criteria, $event,i)"
                               multiple="true"  [value]="workingDay" name="workingDay">
                              </select2>
                            </div>
                        </div>
                      </div>                       
                    </div>

                    <div class=" col-6 col-sm-6 col-md-3 col-lg-2">
                        <div class="form-group row">
                            <div class="col-5 text-right"><label for="startTime" i18n="@@config_timperiods_start_Time">Start Time</label>
                            </div>
                            <div class="col-7">
                                <div class="form-group">                                 
                                    <select class="form-control form-control-sm" formControlName="startTime" (change)="onStartTimeChange(criteria, $event.target.value,i)">
                                      <option style="display:none"></option>
                                      <option *ngFor="let ut of timeSlots" [ngValue]="ut.name" name="ut.name">
                                        {{ut.name}}
                                      </option>
                                    </select>
                                  </div>
                            </div>
                        </div>
                    </div>
                    <div class=" col-6 col-sm-6 col-md-3 col-lg-2">
                        <div class="form-group row">
                            <div class="col-5 text-right">
                                <label for="endTime" i18n="@@config_timperiods_end_Time">End Time</label>
                            </div>
                            <div class="col-7">
                                <div class="form-group">                                 
                                    <select class="form-control form-control-sm" formControlName="endTime" (change)="onEndTimeChange(criteria, $event.target.value,i)">
                                      <option style="display:none"></option>
                                      <option *ngFor="let ut of timeSlots" [ngValue]="ut.name" name="ut.name">
                                        {{ut.name}}
                                      </option>
                                    </select>
                                  </div>
                            </div>
                        </div>
                    </div>
                    <div class=" col-3 col-sm-3 col-md-1 col-lg-2">
                      <div class="form-group row">
                          <div class="col-5 text-right">
                              <label for="endTime" i18n="@@config_timperiods_end_Time">Percentage</label>
                          </div>
                          <div class="col-7">
                              <div class="form-group">                                 
                                  <input class="form-control form-control-sm" type="text" formControlName="percentage" name="percentage" autocomplete="off"/>
                                </div>
                          </div>
                      </div>                       
                  </div>
                </div>
              <hr>
            </div>
        </div>

        <div class="col-12 col-sm-12 col-md-8 col-lg-8  mb-5 mb-sm-5 mb-md-2 mb-lg-5">
          <button class="btn btn-primary btn-sm" type="button" (click)="addTimePeriod(undefined)"  i18n="@@config_timperiods_add_timperiods">Add Time Period</button>         
          <div *ngIf="isSubmitInvalid && !overTimeRuleForm.valid" class="m-3" style="color: rgb(235, 36, 36);" i18n="@@emp_uf_invalid_submit_lable">
            Please fill the required fields marked with red!

          </div>
          <div>
            <button class="btn btn-primary px-4 mt-3" type="submit" i18n="@@emp_uf_save_btn" > Save</button> 
          </div>
       </div> 
</form>

Here is the script for binding, .ts file

import { Component, OnInit, ElementRef, ViewChildren, AfterViewInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControlName, FormControl, AbstractControl, FormArray } from '@angular/forms';
import { ConfigService } from '../config.service';
import { UserService } from '../../user/user.service';

@Component({
 selector: 'wfm-time-periods',
 templateUrl: './time-periods.component.html',
 styleUrls: ['./time-periods.component.css']
})
export class TimePeriodsComponent implements OnInit {
 @ViewChildren(FormControlName, { read: ElementRef }) formInputElements: ElementRef[];
 public overTimeRuleForm : FormGroup;
 isSubmitInvalid : boolean = false;
 notificationModal: any;
 timeSlots = [];
 workingDays : any[] = [];
 overTimePeriods : any[] = []
 useRegularOverTimeRulesForHolidays = false;
 enableBeforeHolidayoverTimeRules = false;
 disableAddBeforeHolidayButton = false;
 
 constructor(private fbp : FormBuilder, private configService : ConfigService, private userService: UserService) {  


   this.workingDays = [
     { id: '1', value: '1', label : 'Sunday'},
     { id: '2', value: '2', label: 'Monday'},
     { id: '3', value: '3', label: 'Tuesday'},
     { id: '4', value: '4', label: 'Wednesday'},
     { id: '5', value: '5', label: 'Thursday'},
     { id: '6', value: '6', label: 'Friday'},
     { id: '7', value: '7', label: 'Saturday'},
     { id: '8', value: '8', label: 'Public Holiday'},
     { id: '9', value: '9', label: 'Day Before Holiday'},
     { id: '10', value: '10', label: 'Day After Holiday'}
   ];
 }

 ngOnInit() {
   this.overTimeRuleForm = this.fbp.group({
     overTimeRules: this.fbp.array([this.createTimePeriod()]),

   })

   this.notificationModal = {
     header: '',
     description: '',
     type: ''
   };

   this.getOverTimeRules();

 }

 createTimePeriod(id=0, timePeriodId = null, startTime = null, endTime= null, percentage = null, workingDay = null)
 {
   return this.fbp.group({
     id:[id==null ? 0 : id],
     timePeriodId : [timePeriodId == null ? 0 : timePeriodId],
     startTime: [startTime ? startTime : '', Validators.required],
     endTime: [endTime ? endTime : '', Validators.required],
     percentage :[percentage, [Validators.required, Validators.maxLength(3)]],
     workingDay : [workingDay , Validators.required]
   })
 }

 get overTimeRules() : FormArray {
   return this.overTimeRuleForm.get('overTimeRules') as FormArray;
 }

 addTimePeriod(timeperiod) {
   this.overTimeRules.push(this.createTimePeriod(timeperiod));
 }

 removeTimePeriod(index) {
   this.overTimeRules.removeAt(index);
 }

 validateFormFields() {
   const overTimeRulesArray = this.overTimeRuleForm.get('overTimeRules') as FormArray;
   console.log(overTimeRulesArray);
  
   Object.keys(overTimeRulesArray['controls']).forEach(element => {
     const control = overTimeRulesArray.get(element);
     Object.keys(control['controls']).forEach(field => {
       const controlItem = control.get(field);
       if (controlItem instanceof FormControl) {
         controlItem.markAsTouched({ onlySelf: true });
       }
     });
   });
 }



 getOverTimeRules() {
 //Fetching data from server and trying to bind formarrays with  ng-select2 controls.
   this.configService.getOverTimeRules().subscribe((res) => {

      const overTimeRulesArray = this.fbp.array([]);
      
      res.overTimeRules.forEach((item, index) => {

        let tempArr = [];
        for(var i = 0; i < item.workingDay.length; i++)
        {
           tempArr.push(item.workingDay[i]);
        }

        //tempArr = [1,2,3,4]
        
        var objt = this.createTimePeriod(item.id, item.timePeriodId, item.startTime, item.endTime, item.percentage, tempArr) ;// add more properties

        overTimeRulesArray.push(objt);

      });

      // this not working when try to set the formarray controls to form 
      this.overTimeRuleForm.setControl('overTimeRules', overTimeRulesArray);
      
      
     //Trying to patching seperately - also not working 
     const rulesArray = this.overTimeRuleForm.get('overTimeRules') as FormArray;

     res.overTimeRules.forEach((item, index) => {

           Object.keys(rulesArray['controls']).forEach(element => {
               const control = rulesArray.get(element);
               
     
             // //const controlArray = control['controls'] as FormArray;
             // 
             // let select2Control =   Object.keys(control['controls']).filter( p => !p.indexOf('workingDays'));
             // const controlItem = control.get(select2Control);
             // // if (controlItem instanceof FormControl) {
             // //   console.log("patched value");
             // //     // controlItem.setValue(item.workingDay);
             // //      console.log(controlItem.value);
             // //  }
             //controlItem.patchValue({ field: item.workingDays });
             //console.log(controlItem.value);

             Object.keys(control['controls']).forEach(field => {   
               
               if(field === 'workingDay')
               {
                 const controlItem = control.get(field);
                //controlItem.patchValue({ workingDay: item.workingDay });
                 control.get('workingDay').setValue(item.workingDay );

                 if (controlItem instanceof FormControl) {
                   controlItem.patchValue({ workingDay: item.workingDay });
                 }
               } 
             });
           }); 
     });
    
   });
 }

I tried with patching values separately by looping through the form controls in form-array, but it also didn't work.

Can someone help me out, to figure this ?

Thanks,

0 Answers
Related