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,