I am trying to use the library @ngui-autocomplete in Angular 4 project. I use a form for both creating new entries in database and also for updating/editing existing ones. The Code for my autocomplete input is the following:
<div [ngClass]="{
'form-group': true, 'row' : true,
'has-danger': incidentForm.get('doctor').invalid && ( incidentForm.get('doctor').touched || incidentForm.get('doctor').dirty ),
'has-success': incidentForm.get('doctor').valid && ( incidentForm.get('doctor').dirty || incidentForm.get('doctor').touched )
}">
<label for="doctor" class="col-sm-2 col-form-label">Ιατρός:</label>
<div class="col-6">
<input ngui-auto-complete [ngClass]="{
'form-control': true,
'form-control-danger': incidentForm.get('doctor').invalid && ( incidentForm.get('doctor').touched || incidentForm.get('doctor').dirty ),
'form-control-success': incidentForm.get('doctor').valid && ( incidentForm.get('doctor').dirty || incidentForm.get('doctor').touched )
}"
name="doctor" formControlName="doctor"
id="doctor" [source]="doctors"
autocomplete="off"
[list-formatter]="'lastName firstName'"
value-formatter="lastName firstName"
select-value-of="id"
required >
<!-- VALIDATION -->
<div class="form-control-feedback"
*ngIf="incidentForm.get('doctor').hasError('required') && incidentForm.get('doctor').touched">
{{ validationMessages.doctor.required }}
</div>
<!-- END OF VALIDATION -->
</div>
</div>
My form.ts code is:
import {Component, OnInit} from '@angular/core';
import {IncidentsService} from '../incidents.service';
import {Patient} from '../../patients/patient';
import {Doctor} from '../../doctors/doctor';
import {Clinic} from '../../clinics/clinic';
import {Incident} from '../incident';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {SigningDoctor} from '../../signing-doctors/signing-doctor';
import {HttpErrorResponse} from '@angular/common/http';
import {ActivatedRoute} from '@angular/router';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs/Observable';
import {DomSanitizer, SafeHtml} from '@angular/platform-browser';
@Component({
selector: 'app-incident-form',
templateUrl: './incident-form.component.html',
styleUrls: ['./incident-form.component.css']
})
export class IncidentFormComponent implements OnInit {
private incident: Incident;
private id;
private incidentForm: FormGroup;
private patients: Patient[] = [];
private doctors: Doctor[] = [];
private clinics: Clinic[] = [];
private signingDoctors: SigningDoctor[] = [];
private doctor: Doctor;
private errorMsg;
constructor(private incidentsService: IncidentsService, private formBuilder: FormBuilder, private route: ActivatedRoute, private sanitizer: DomSanitizer) {
this.createForm();
}
createForm() {
this.incidentForm = this.formBuilder.group({
protocolNo: ['', [Validators.required, Validators.pattern('^[0-9]{1,}')]],
date: ['', Validators.required],
mikro: ['', Validators.required],
makro: ['', Validators.required],
yliko: ['', Validators.required],
anoso: [''],
histo: [''],
klinikesPlirofories: [''],
simpliromatikiEkthesi: [''],
symperasma: ['', Validators.required],
patient: ['', Validators.required],
doctor: ['', Validators.required],
clinic: [''],
isPayed: ['', Validators.required],
signingDoctor: ['', Validators.required]
});
}
ngOnInit() {
this.parseID();
this.getIncidentByID();
this.getRelatedData();
}
private parseID() {
this.route.params
.catch(error => {
console.log('error catched', error);
return Observable.of({description: error});
})
.subscribe(
params => {
this.id = +params['id'];
}
);
}
private setFormValues(response){
this.incidentForm.get('protocolNo').setValue(response.protocolNo);
this.incidentForm.get('date').setValue(response.date);
this.incidentForm.get('mikro').setValue(response.mikro);
this.incidentForm.get('makro').setValue(response.makro);
this.incidentForm.get('yliko').setValue(response.yliko);
this.incidentForm.get('anoso').setValue(response.anoso);
this.incidentForm.get('histo').setValue(response.histo);
this.incidentForm.get('klinikesPlirofories').setValue(response.klinikesPlirofories);
this.incidentForm.get('simpliromatikiEkthesi').setValue(response.simpliromatikiEkthesi);
this.incidentForm.get('symperasma').setValue(response.symperasma);
this.incidentForm.get('isPayed').setValue(response.isPayed);
this.incidentForm.get('doctor').setValue(response.doctor);
}
autocompleListFormatter = (data: any) => {
let html = `${data.lastName} ${data.firstName}`;
return this.sanitizer.bypassSecurityTrustHtml(html);
}
private getIncidentByID() {
this.incidentsService.getIncidentByID(this.id)
.subscribe(
response => {
this.incident = response;
this.setFormValues(response);
},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.log('An error occurred:', err.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
}
});
}
getRelatedData() {
this.incidentsService.getRelatedData().subscribe(
results => {
this.patients = results[0];
this.doctors = results[1];
this.clinics = results[2];
this.signingDoctors = results[3];
},
(err: HttpErrorResponse) => IncidentFormComponent.handleError
);
}
submitForm() {
this.incidentsService.submitForm(this.incidentForm.value).subscribe(
res => {
// this.incident = res;
console.log('Submit Form Response: ' + JSON.stringify(res));
this.incidentForm.reset();
// this.createForm();
},
(err: HttpErrorResponse) => IncidentFormComponent.handleError
);
}
static handleError(err) {
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.log('An error occurred:', err.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
}
}
validationMessages = {
protocolNo: {
required: 'Ο Αριθμός Πρωτοκόλλου είναι υποχρεωτικός.',
pattern: 'Ο Αριθμός Πρωτοκόλλου Έχει Λάθος Μορφή.'
},
date: {
required: 'Η Ημερομηνία Είναι Υποχρεωτική. ',
pattern: 'Λάθος Μορφή Ημερομηνίας.'
},
symperasma: {
required: 'Το Συμπερασμα είναι Υποχρεωτικό.',
},
patient: {
required: 'Η Επιλογή Ασθενή Είναι Υποχρεωτική.'
},
doctor: {
required: 'Η Επιλογή Ιατρού Είναι Υποχρεωτική.'
},
signingDoctor: {
required: 'Η Επιλογή Υπογράφων Ιατρού Είναι Υποχρεωτική.'
},
yliko: {
required: 'Το πεδίο υλικό είναι υποχρεωτικό.'
},
mikro: {
required: 'Το πεδίο μίκροσκοπικά είναι υποχρεωτικό.'
},
makro: {
required: 'Το πεδίο μακροσκοπικά είναι υποχρεωτικό.'
},
isPayed: {
required: 'Το πεδίο πληρωμή είναι υποχρεωτικό.'
},
success: 'Yeah'
};
}
For creating entries everything works as expected. However when i am updating existing entries, thying to set the value to autocomplete input component by using the command
this.incidentForm.get('doctor').setValue(response.doctor);
while form.value is correct inside the input field i get: [object Object] instead of "lastName firstName" as declared in command
value-formatter="lastName firstName"
I suppose i am missing something very simple but i can't get it.
The Solution was simple. Just added
display-property-name="lastName firstName"
i.e.
<input ngui-auto-complete name="doctor"
formControlName="doctor"
id="doctor"
[source]="doctors"
autocomplete="off"
[list-formatter]="'lastName firstName'"
value-formatter="lastName firstName"
display-property-name="lastName firstName"
[(ngModel)] = "Doctor"
required>