I have a model driven form in which I would like to add a drop down list containing several options. The options are from a pre-fetched list, and the model of the form is injected to the component. The form is loaded correctly: All the fields from the model are filled properly, abd the list of options for the drop-down list is also loaded correctly.
The only problem is that I can't set the selected
value of the list, and it appears with an empty value at first.
Here, I am loading the HMOs list, then loading the patient, and only then creating the form.
All the values of the form (name, id, etc. which are omitted here) are loaded correctly into the form.
The drop-down list in the form is filled correctly: All HMOs are populating the list.
Still, the selected value in the list is missing, and the lost is loaded with no initial value.
For debugging purposes, I have replaced the boolean condition in the option
tag: patient.hmo.uid == hmo.uid
to a function call: isSelected(hmo)
.
This function essentially does the same comparison and returns its value, but first logs it. Indeed I see that the option with the correct hmo gets a true
value and all other options get false
values, meaning all data is loaded correctly.
Also, when I set the [selected]="true"
(always to be true), I do see the change affects: The last option is selected (the default in HTML).
So where am I wrong? How should I set the selected option correctly?
Code for the component (all fields except HMO are omitted):
import {Component, Input, Inject, OnInit} from "@angular/core";
import {
FormGroup,
FormControl,
REACTIVE_FORM_DIRECTIVES,
Validators,
FormBuilder,
FormArray
} from "@angular/forms";
import {Patient} from "./patient";
import {PatientsService} from "./patients.service";
import {Hmo} from "../hmos/hmo";
import {HmosService} from "../hmos/hmos.service";
import {Doctor} from "../doctors/doctor";
import {DoctorsService} from "../doctors/doctors.service";
import {Router, ActivatedRoute} from "@angular/router";
import {Subscription} from "rxjs/Rx";
import {Response} from "@angular/http";
import {JavaDate} from "./java-date";
@Component({
moduleId: module.id,
selector: 'gy-patient-edit',
templateUrl: 'patient-edit.component.html',
directives: [REACTIVE_FORM_DIRECTIVES],
})
export class PatientEditComponent implements OnInit {
patientForm: FormGroup;
@Input() patient: Patient;
private hmos: Hmo[];
private patientUid: number;
private showForm: boolean = false;
constructor(@Inject(PatientsService) private patientsService: PatientsService,
@Inject(HmosService) private hmosService: HmosService,
@Inject(ActivatedRoute) private route: ActivatedRoute,
@Inject(FormBuilder) private formBuilder: FormBuilder) {
}
ngOnInit(): any {
this.subscription = this.route.params.subscribe(
(params: any) => {
this.patientUid = params['id']; //Getting the UID from the URL
}
);
this.hmosService.hmosChanged.subscribe(
(hmos: Hmo[]) => {
this.hmos = hmos; //Fetching available HMOs
}
);
this.hmosService.fetchHmos();
this.patientsService.fetchPatient(this.patientUid) //Fetching the Patient
.map((response: Response) => response.json())
.subscribe((data: Patient) => {
this.patient = data;
this.restartForm(); //Only required so the form will ne initialized only after the patient is received from the server
});
}
restartForm(){
this.patientForm = this.formBuilder.group({
hmo: [this.patient.hmo]]
});
this.showForm = true;
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Code for the HTML form:
<div class="row" *ngIf="showForm">
<div class="col-xs-12" *ngIf="showForm">
<form [formGroup]="patientForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="hmo">HMO</label>
<select formControlName="hmo" id="hmo">
<option *ngFor="let hmo of hmos"
[value]="hmo.uid" [selected]="patient.hmo.uid == hmo.uid">
{{hmo.name}}
</option>
</select>
</form>
</div>
</div>
Code for Patient
:
import {Hmo} from "../hmos/hmo";
export class Patient {
constructor(public hmo: Hmo) {
}
}
Code for Hmo
:
export class Hmo{
constructor(public uid: number, public name: string){}
}
The ngModel directive declared in the FormsModule lets you bind controls in your template-driven form to properties in your data model.
The selected option is calculated by comparing the <option>
's value with <select>
's value. In light of that, to mark an <option>
as selected, we need to make sure the wrapping <select>
is containing the same value, which in turn requires the correct value of the corresponding form control in your model.
Your code can be slightly modified as follow:
restartForm(){
this.patientForm = this.formBuilder.group({
hmo: [this.patient.hmo.uid]
});
this.showForm = true;
}
And Template:
<select formControlName="hmo" id="hmo">
<option *ngFor="let hmo of hmos"
[value]="hmo.uid">
{{hmo.name}}
</option>
</select>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With