11import { Component , Input , OnChanges , SimpleChanges , EventEmitter , Output , AfterViewInit , ChangeDetectorRef } from '@angular/core' ;
2+ import { SdcPopulationService } from '../../services/sdc-population.service' ;
3+ import { FhirService } from '../../services/fhir.service' ;
24
35declare var LForms : any ;
46
@@ -11,14 +13,20 @@ declare var LForms: any;
1113export class QuestionnaireFormComponent implements OnChanges , AfterViewInit {
1214 @Input ( ) questionnaire : any = null ;
1315 @Input ( ) questionnaireId : string = '' ;
16+ @Input ( ) patientId : string | null = null ;
1417 @Output ( ) formSubmitted = new EventEmitter < any > ( ) ;
1518 @Output ( ) formCancelled = new EventEmitter < void > ( ) ;
1619
1720 formRendered = false ;
21+ isPrePopulated = false ;
1822 formContainerId = '' ;
1923 private lformsLoaded = false ;
2024
21- constructor ( private cdr : ChangeDetectorRef ) {
25+ constructor (
26+ private cdr : ChangeDetectorRef ,
27+ private sdcPopulationService : SdcPopulationService ,
28+ private fhirService : FhirService
29+ ) {
2230 // Generate unique container ID for this component instance
2331 this . formContainerId = `questionnaire-form-${ Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) } ` ;
2432 // Load LForms library if not already loaded
@@ -63,7 +71,7 @@ export class QuestionnaireFormComponent implements OnChanges, AfterViewInit {
6371 document . head . appendChild ( script ) ;
6472 }
6573
66- renderForm ( ) : void {
74+ async renderForm ( ) : Promise < void > {
6775 if ( ! this . questionnaire ) {
6876 this . formRendered = false ;
6977 return ;
@@ -75,26 +83,50 @@ export class QuestionnaireFormComponent implements OnChanges, AfterViewInit {
7583 }
7684
7785 try {
78- // Check if container exists
7986 const container = document . getElementById ( this . formContainerId ) ;
8087 if ( ! container ) {
8188 this . formRendered = false ;
8289 return ;
8390 }
84-
85- // Clear any existing form first
91+
8692 container . innerHTML = '' ;
87-
88- // Render the questionnaire using LForms
89- // Use setTimeout to ensure the container is fully cleared
93+
94+ let populatedQR : any = null ;
95+ if ( this . patientId ) {
96+ try {
97+ populatedQR = this . sdcPopulationService . populate ( this . questionnaire , this . patientId ) ;
98+ } catch {
99+ // Pre-population failure must never block form rendering
100+ }
101+ }
102+
90103 setTimeout ( ( ) => {
91104 try {
92- LForms . Util . addFormToPage ( this . questionnaire , this . formContainerId ) ;
105+ if ( populatedQR ) {
106+ // Merge approach: convert questionnaire to LForms internal format first,
107+ // then merge the QR into it before rendering. This is the correct LForms
108+ // API for pre-population — addFormToPage options do not apply QR answers.
109+ if ( typeof LForms . Util . setFHIRContext === 'function' ) {
110+ LForms . Util . setFHIRContext ( { baseUrl : this . fhirService . getBaseUrl ( ) } ) ;
111+ }
112+ const lfData = LForms . Util . convertFHIRQuestionnaireToLForms ( this . questionnaire , 'R4' ) ;
113+ const merged = LForms . Util . mergeFHIRDataIntoLForms ( 'QuestionnaireResponse' , populatedQR , lfData , 'R4' ) ;
114+ LForms . Util . addFormToPage ( merged , this . formContainerId ) ;
115+ } else {
116+ LForms . Util . addFormToPage ( this . questionnaire , this . formContainerId ) ;
117+ }
93118 this . formRendered = true ;
94- // Trigger change detection to update the view
119+ this . isPrePopulated = ! ! populatedQR ;
95120 this . cdr . detectChanges ( ) ;
96121 } catch ( innerError ) {
97- this . formRendered = false ;
122+ // If merge/render fails, fall back to plain render without pre-population
123+ try {
124+ LForms . Util . addFormToPage ( this . questionnaire , this . formContainerId ) ;
125+ this . formRendered = true ;
126+ } catch {
127+ this . formRendered = false ;
128+ }
129+ this . isPrePopulated = false ;
98130 this . cdr . detectChanges ( ) ;
99131 }
100132 } , 100 ) ;
0 commit comments