Drew13 Drew13 - 15 days ago 13
TypeScript Question

Angular2 populating Bootstrap 4 modal form inputs with previously clicked data

Using Angular2, on my main page I have a table that sends the data of whichever row was clicked on to a Bootstrap 4 modal that pops up using a button on the main page. The modal contains form inputs that populate with the clicked row's data for editing. My problem is that if I edit one or both of the datefields and submit, those edited values populate the form inputs for the next row I click on to edit, but ONLY if I edited that first clicked row's dates.

For example, if row 1 has original dates

11/23/2016
and
11/26/2016
and row 2 has original dates
12/20/2016
and
12/22/2016
and I choose to edit row 1 first and change them to
10/22/2016
and
10/31/2016
. Once I open the modal to edit row 2, it's dates will be
10/22/2016
and
10/31/2016
. But if I didn't edit row 1's dates, row 2's dates would show up properly as
12/20/2016
and
12/22/2016
. Additionally, the first two form inputs do not have this behavior.

I've tried using change detection in each method but none of that works for this issue. Also tried setting
receivedRow
's dates to null, but that doesn't work either.

Main page (the button on the left in the row of 3 is what opens the modal):
enter image description here

Modal:
enter image description here

Typescript:

@Component({
selector: 'update-validation',
styleUrls: ['../app.component.css'],
templateUrl: 'update.component.html',
providers: [DatePipe]
})

export class UpdateComponent {
@Input() receivedRow:DataTable;
public dt: NgbDateStruct;
public dt2: NgbDateStruct;
public startCheck: boolean = false;
public endCheck: boolean = false;
updateForm : FormGroup;

constructor(fb: FormBuilder, private datePipe: DatePipe, private cdRef:ChangeDetectorRef){
this.updateForm = fb.group({
'dataPoint' : [null, Validators.required],
'ICCP' : [null, Validators.required],
'startDate' : [null, Validators.required],
'endDate' : [null, Validators.required]
}, {validator: this.endDateAfterOrEqualValidator})
}

ngOnChanges(){
if(this.receivedRow){
this.updateForm.controls['dataPoint'].setValue(this.receivedRow.tDataPoint);
this.updateForm.controls['ICCP'].setValue(this.receivedRow.tICCP);
this.updateForm.controls['startDate'].setValue(this.receivedRow.tStartDate);
this.updateForm.controls['endDate'].setValue(this.receivedRow.tEndDate);
}
}

resetForm(){
location.reload();
//this.updateForm.reset();
}

submitForm(value: any, originalRow: any){
var dataPointID = originalRow.receivedRow.tDataPoint;
for (let entry in DPS) {
if (DPS[entry].tDataPoint === dataPointID) {
DPS[entry].tDataPoint = String(this.updateForm.controls['dataPoint'].value);
DPS[entry].tICCP = String(this.updateForm.controls['ICCP'].value);
DPS[entry].tStartDate = String(this.updateForm.controls['startDate'].value);
DPS[entry].tEndDate = String(this.updateForm.controls['endDate'].value);
}
}
}

getStartDate(){
var month = this.receivedRow.tStartDate.substring(0,2);
var day = this.receivedRow.tStartDate.substring(3,5);
var year = this.receivedRow.tStartDate.substring(6,10);
var dateToUse = new Date(Number(year),Number(month)-1,Number(day));
let timestamp = this['startDate'] != null ? new Date(this['startDate'].year, this['startDate'].month-1, this['startDate'].day).getTime() : dateToUse.getTime();
this.updateForm.controls['startDate'].setValue(this.datePipe.transform(timestamp, 'MM/dd/yyyy'));
}

getEndDate(){
var month = this.receivedRow.tEndDate.substring(0,2);
var day = this.receivedRow.tEndDate.substring(3,5);
var year = this.receivedRow.tEndDate.substring(6,10);
var dateToUse = new Date(Number(year),Number(month)-1,Number(day));
let timestamp = this['endDate'] != null ? new Date(this['endDate'].year, this['endDate'].month-1, this['endDate'].day).getTime() : dateToUse.getTime();
this.updateForm.controls['endDate'].setValue(this.datePipe.transform(timestamp, 'MM/dd/yyyy'));
}

public showDatePick(selector):void {
if(selector === 0) {
this.startCheck = !this.startCheck
} else {
this.endCheck = !this.endCheck;
}
this.cdRef.detectChanges();
}

endDateAfterOrEqualValidator(formGroup): any {
var startDateTimestamp, endDateTimestamp;
for(var controlName in formGroup.controls) {
if (controlName.indexOf("startDate") !== -1) {
tartDateTimestamp = Date.parse(formGroup.controls[controlName].value);
}
if (controlName.indexOf("endDate") !== -1) {
endDateTimestamp = Date.parse(formGroup.controls[controlName].value);
}
}
return (endDateTimestamp < startDateTimestamp) ? { endDateLessThanStartDate: true } : null;
}
}

Answer

Modified submitForm function to set ngModel's startDate and endDate to null so that when getStartDate and getEndDate get called, timestamp in the getStartDate and getEndDate functions gets set to the date based on the row that is clicked and not the previously binded startDate and endDate.

submitForm(value: any, originalRow: any){
  var dataPointID = originalRow.receivedRow.tDataPoint;
  for (let entry in DPS) {
    if (DPS[entry].tDataPoint === dataPointID) {
      DPS[entry].tDataPoint = String(this.updateForm.controls['dataPoint'].value);
      DPS[entry].tICCP = String(this.updateForm.controls['ICCP'].value);
      DPS[entry].tStartDate = String(this.updateForm.controls['startDate'].value);
      DPS[entry].tEndDate = String(this.updateForm.controls['endDate'].value);
      this['startDate'] = null;
      this['endDate'] = null;
    }
  }
}