lforms 29.3.1 → 33.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +256 -0
- package/README.md +97 -14
- package/changed-features.md +99 -0
- package/dist/lforms/LICENSE.md +70 -0
- package/dist/lforms/README.md +100 -0
- package/dist/lforms/fhir/R4/lformsFHIR.min.js +2 -0
- package/dist/lforms/fhir/R4/lformsFHIR.min.js.map +1 -0
- package/dist/lforms/fhir/STU3/lformsFHIR.min.js +2 -0
- package/dist/lforms/fhir/STU3/lformsFHIR.min.js.map +1 -0
- package/dist/lforms/fhir/lformsFHIRAll.min.js +2 -0
- package/dist/lforms/fhir/lformsFHIRAll.min.js.map +1 -0
- package/dist/lforms/webcomponent/assets/lib/zone.min.js +134 -0
- package/dist/lforms/webcomponent/down_arrow_gray_10_10.png +0 -0
- package/dist/lforms/webcomponent/favicon.ico +0 -0
- package/dist/lforms/webcomponent/index.html +9 -0
- package/dist/lforms/webcomponent/lhc-forms.js +2471 -0
- package/dist/lforms/webcomponent/magnifying_glass.png +0 -0
- package/dist/lforms/webcomponent/main.js +2464 -0
- package/dist/lforms/webcomponent/main.js.map +1 -0
- package/dist/lforms/webcomponent/polyfills.js +2 -0
- package/dist/lforms/webcomponent/polyfills.js.map +1 -0
- package/dist/lforms/webcomponent/runtime.js +2 -0
- package/dist/lforms/webcomponent/runtime.js.map +1 -0
- package/dist/lforms/webcomponent/scripts.js +3 -0
- package/dist/lforms/webcomponent/scripts.js.map +1 -0
- package/dist/lforms/webcomponent/styles.css +3 -0
- package/dist/lforms/webcomponent/styles.css.map +1 -0
- package/form_definition.md +382 -0
- package/lforms-33.2.0.tgz +0 -0
- package/package.json +94 -88
- package/r4-support.md +147 -0
- package/sdc-support.md +127 -0
- package/app/.npmignore +0 -3
- package/app/images/blank.gif +0 -0
- package/app/images/signal-stop.png +0 -0
- package/app/index.html +0 -10
- package/app/lforms.js +0 -56
- package/app/lforms.tpl.js +0 -964
- package/app/scripts/angular-packages.js +0 -11
- package/app/scripts/bootstrap-decorators.js +0 -31
- package/app/scripts/bower-index.js +0 -14
- package/app/scripts/fhir/R4/export.js +0 -33
- package/app/scripts/fhir/R4/fhirRequire.js +0 -36
- package/app/scripts/fhir/R4/lformsFHIR.js +0 -27260
- package/app/scripts/fhir/R4/sdc-export.js +0 -455
- package/app/scripts/fhir/R4/sdc-import.js +0 -483
- package/app/scripts/fhir/STU3/export.js +0 -27
- package/app/scripts/fhir/STU3/fhirRequire.js +0 -36
- package/app/scripts/fhir/STU3/lformsFHIR.js +0 -27291
- package/app/scripts/fhir/STU3/sdc-export.js +0 -493
- package/app/scripts/fhir/STU3/sdc-import.js +0 -494
- package/app/scripts/fhir/diagnostic-report.js +0 -707
- package/app/scripts/fhir/export-common.js +0 -209
- package/app/scripts/fhir/expression-processor.js +0 -670
- package/app/scripts/fhir/extensions/rendering-style.js +0 -23
- package/app/scripts/fhir/fhir-common.js +0 -3
- package/app/scripts/fhir/obs-prepop.mjs +0 -97
- package/app/scripts/fhir/runtime-common.js +0 -33
- package/app/scripts/fhir/sdc-common.js +0 -334
- package/app/scripts/fhir/sdc-export-common.js +0 -1046
- package/app/scripts/fhir/sdc-import-common.js +0 -1343
- package/app/scripts/fhir/versions.js +0 -8
- package/app/scripts/index.js +0 -20
- package/app/scripts/lforms-config.js +0 -12
- package/app/scripts/lforms-constants.js +0 -10
- package/app/scripts/lforms-controllers.js +0 -1196
- package/app/scripts/lforms-directives.js +0 -424
- package/app/scripts/lforms-index.js +0 -20
- package/app/scripts/lib/cross_browser.js +0 -21
- package/app/scripts/lib/lforms-data.js +0 -3591
- package/app/scripts/lib/lforms-hl7.js +0 -525
- package/app/scripts/lib/lforms-util.js +0 -1122
- package/app/scripts/lib/lforms-validate.js +0 -277
- package/app/scripts/lib/polyfill.js +0 -81
- package/app/scripts/themeList.js +0 -17
- package/app/styles/lforms.css +0 -1219
- package/app/styles/redmond-theme/README.txt +0 -2
- package/app/styles/redmond-theme/images/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
- package/app/styles/redmond-theme/images/ui-bg_glass_85_dfeffc_1x400.png +0 -0
- package/app/styles/redmond-theme/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- package/app/styles/redmond-theme/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
- package/app/styles/redmond-theme/images/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
- package/app/styles/redmond-theme/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
- package/app/styles/redmond-theme/images/ui-icons_217bc0_256x240.png +0 -0
- package/app/styles/redmond-theme/images/ui-icons_2e83ff_256x240.png +0 -0
- package/app/styles/redmond-theme/images/ui-icons_469bdd_256x240.png +0 -0
- package/app/styles/redmond-theme/images/ui-icons_6da8d5_256x240.png +0 -0
- package/app/styles/redmond-theme/images/ui-icons_cd0a0a_256x240.png +0 -0
- package/app/styles/redmond-theme/images/ui-icons_d8e7f3_256x240.png +0 -0
- package/app/styles/redmond-theme/images/ui-icons_f9bd01_256x240.png +0 -0
- package/app/styles/redmond-theme/jquery-ui.css +0 -1311
- package/app/styles/redmond-theme/jquery-ui.min.css +0 -7
- package/app/styles/redmond-theme/theme.css +0 -443
- package/app/styles/themes.css +0 -1541
- package/app/styles/themes.css.map +0 -9
- package/app/styles/themes.scss +0 -411
- package/app/version.json +0 -1
- package/app/views/partials/attachment.html +0 -38
- package/app/views/partials/field-answers.html +0 -67
- package/app/views/partials/field-units.html +0 -24
- package/app/views/partials/form-controls.html +0 -19
- package/app/views/partials/form-header.html +0 -35
- package/app/views/partials/form-options.html +0 -50
- package/app/views/partials/form-title.html +0 -20
- package/app/views/partials/form-view.html +0 -13
- package/app/views/partials/item-options.html +0 -48
- package/app/views/partials/item.html +0 -126
- package/app/views/partials/itemPrefixAndText.html +0 -4
- package/app/views/partials/layout-horizontal.html +0 -156
- package/app/views/partials/layout-matrix.html +0 -145
- package/app/views/partials/popover-content.html +0 -1
- package/app/views/partials/repeating-button.html +0 -16
- package/app/views/partials/table-item.html +0 -30
- package/app/views/partials/template-table.html +0 -69
- package/app/views/partials/uib-popover-templates/uib-popover-template.html +0 -13
- package/app/views/partials/uib-popover-templates/uib-popover.html +0 -11
|
@@ -1,493 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A package to handle FHIR Questionnaire and SDC (STU2) Questionnaire and QuestionnaireResponse for LForms
|
|
3
|
-
*
|
|
4
|
-
* FHIR Questionnaire:
|
|
5
|
-
* https://www.hl7.org/fhir/questionnaire.html
|
|
6
|
-
*
|
|
7
|
-
* STU2 SDC Ballot:
|
|
8
|
-
* http://hl7.org/fhir/us/sdc/sdc-questionnaire.html
|
|
9
|
-
* http://hl7.org/fhir/us/sdc/sdc-questionnaireresponse.html
|
|
10
|
-
*
|
|
11
|
-
* It provides the following functions:
|
|
12
|
-
* convertLFormsToQuestionnaire()
|
|
13
|
-
* -- Convert existing LOINC panels/forms data in LForms format into FHIR (standard or SDC) Questionnaire data
|
|
14
|
-
* convertLFormsToQuestionnaireResponse()
|
|
15
|
-
* -- Generate FHIR (standard or SDC) QuestionnaireResponse data from captured data in LForms
|
|
16
|
-
*/
|
|
17
|
-
var sdcVersion = '2.0';
|
|
18
|
-
var fhirVersionNum = '3.0';
|
|
19
|
-
|
|
20
|
-
var self = {
|
|
21
|
-
|
|
22
|
-
SDCVersion: sdcVersion,
|
|
23
|
-
QProfile: 'http://hl7.org/fhir/us/sdc/StructureDefinition/sdc-questionnaire|'+sdcVersion,
|
|
24
|
-
QRProfile: 'http://hl7.org/fhir/us/sdc/StructureDefinition/sdc-questionnaireresponse|'+sdcVersion,
|
|
25
|
-
stdQProfile: 'http://hl7.org/fhir/'+fhirVersionNum+'/StructureDefinition/Questionnaire',
|
|
26
|
-
stdQRProfile: 'http://hl7.org/fhir/'+fhirVersionNum+'/StructureDefinition/QuestionnaireResponse',
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Convert LForms captured data to a bundle consisting of a FHIR SDC
|
|
31
|
-
* QuestionnaireResponse and any extractable resources. (Currently this means
|
|
32
|
-
* any Observations that can be extracted via the observationLinkPeriod
|
|
33
|
-
* extension).
|
|
34
|
-
*
|
|
35
|
-
* @param lfData a LForms form object
|
|
36
|
-
* @param noExtensions a flag that a standard FHIR Questionnaire is to be created without any extensions.
|
|
37
|
-
* The default is false.
|
|
38
|
-
* @param subject A local FHIR resource that is the subject of the output resource.
|
|
39
|
-
* If provided, a reference to this resource will be added to the output FHIR
|
|
40
|
-
* resource when applicable.
|
|
41
|
-
* @returns an array of QuestionnaireResponse and Observations. The caller may
|
|
42
|
-
* wish to put all of the returned resources into a transaction Bundle for
|
|
43
|
-
* creating them on a FHIR server.
|
|
44
|
-
*/
|
|
45
|
-
convertLFormsToFHIRData: function(lfData, noExtensions, subject) {
|
|
46
|
-
var qr = this.convertLFormsToQuestionnaireResponse(lfData, noExtensions, subject);
|
|
47
|
-
if (!qr.id) {
|
|
48
|
-
qr.id = this._commonExport._getUniqueId(qr.code && qr.code[0] && qr.code[0].code ||
|
|
49
|
-
qr.identifier || 'QR')
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
var qrRef = 'QuestionnaireResponse/'+qr.id;
|
|
53
|
-
var rtn = [qr];
|
|
54
|
-
var objPerformers = ['Practitioner', 'Patient', 'RelatedPerson']; // intersected with qr.author
|
|
55
|
-
for (var i=0, len=lfData.itemList.length; i<len; ++i) {
|
|
56
|
-
var item = lfData.itemList[i];
|
|
57
|
-
if (self._getExtractValue(item) && item.value) {
|
|
58
|
-
var obs = this._commonExport._createObservation(item);
|
|
59
|
-
for (var j=0, jLen=obs.length; j<jLen; j++) {
|
|
60
|
-
// Following
|
|
61
|
-
// http://hl7.org/fhir/uv/sdc/2019May/extraction.html#observation-based-extraction
|
|
62
|
-
if (qr.basedOn)
|
|
63
|
-
obs[j].basedOn = qr.basedOn;
|
|
64
|
-
if (qr.subject)
|
|
65
|
-
obs[j].subject = qr.subject;
|
|
66
|
-
if (qr.context)
|
|
67
|
-
obs[j].context = qr.context;
|
|
68
|
-
if (qr.authored) {
|
|
69
|
-
obs[j].effectiveDateTime = qr.authored;
|
|
70
|
-
obs[j].issued = qr.authored;
|
|
71
|
-
}
|
|
72
|
-
if (qr.author && objPerformers.indexOf(qr.author.type)>=0)
|
|
73
|
-
obs[j].performer = qr.author;
|
|
74
|
-
|
|
75
|
-
rtn.push(obs[j]);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return rtn;
|
|
80
|
-
},
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Proceses the LForms questionCardinality into FHIR.
|
|
85
|
-
* @param targetItem an item in Questionnaire
|
|
86
|
-
* @param item a LForms item
|
|
87
|
-
*/
|
|
88
|
-
_processQuestionCardinality: function(targetItem, item) {
|
|
89
|
-
if (item.questionCardinality) {
|
|
90
|
-
if (item.questionCardinality.max === "*") {
|
|
91
|
-
targetItem.repeats = true;
|
|
92
|
-
}
|
|
93
|
-
else if (parseInt(item.questionCardinality.max) > 1) {
|
|
94
|
-
targetItem.repeats = true;
|
|
95
|
-
targetItem.extension.push({
|
|
96
|
-
"url": "http://hl7.org/fhir/StructureDefinition/questionnaire-maxOccurs",
|
|
97
|
-
"valueInteger": parseInt(item.questionCardinality.max)
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
targetItem.repeats = false;
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Handle special requirements for 'display' items
|
|
109
|
-
* @param targetItem an item in Questionnaire
|
|
110
|
-
* @param item a LForms item
|
|
111
|
-
* @private
|
|
112
|
-
*/
|
|
113
|
-
_handleSpecialConstraints: function(targetItem, item) {
|
|
114
|
-
//Display items cannot have a "code" asserted
|
|
115
|
-
//Required and repeat aren't permitted for display items
|
|
116
|
-
//Read-only can't be specified for "display" items
|
|
117
|
-
if (targetItem && item.dataType === "TITLE") {
|
|
118
|
-
delete targetItem.code;
|
|
119
|
-
delete targetItem.required;
|
|
120
|
-
delete targetItem.repeats;
|
|
121
|
-
delete targetItem.readOnly;
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Process various restriction settings
|
|
128
|
-
* @param targetItem an item in FHIR SDC Questionnaire object
|
|
129
|
-
* @param item an item in LForms form object
|
|
130
|
-
* @private
|
|
131
|
-
*/
|
|
132
|
-
_handleRestrictions: function(targetItem, item) {
|
|
133
|
-
// http://hl7.org/fhir/StructureDefinition/minLength
|
|
134
|
-
// http://hl7.org/fhir/StructureDefinition/regex
|
|
135
|
-
// http://hl7.org/fhir/StructureDefinition/minValue
|
|
136
|
-
// http://hl7.org/fhir/StructureDefinition/maxValue
|
|
137
|
-
// http://hl7.org/fhir/StructureDefinition/maxDecimalPlaces, not supported yet
|
|
138
|
-
// http://hl7.org/fhir/StructureDefinition/maxSize, for attachment, not supported yet
|
|
139
|
-
// maxLength
|
|
140
|
-
if (item.restrictions) {
|
|
141
|
-
for (var key in item.restrictions) {
|
|
142
|
-
var value = item.restrictions[key];
|
|
143
|
-
var extValue = null;
|
|
144
|
-
var dataType = this._getAssumedDataTypeForExport(item);
|
|
145
|
-
var valueKey = this._getValueKeyByDataType("value", item);
|
|
146
|
-
|
|
147
|
-
switch (key) {
|
|
148
|
-
// http://hl7.org/fhir/StructureDefinition/minValue
|
|
149
|
-
// { // Must be >= this value
|
|
150
|
-
// // from Element: extension
|
|
151
|
-
// "url" : "http://hl7.org/fhir/StructureDefinition/minValue", // R!
|
|
152
|
-
// // value[x]: Value of extension. One of these 6:
|
|
153
|
-
// "valueDate" : "<date>" // R! Value of extension
|
|
154
|
-
// "valueDateTime" : "<dateTime>", // R! Value of extension
|
|
155
|
-
// "valueTime" : "<time>", // R! Value of extension
|
|
156
|
-
// "valueInstant" : "<instant>", // R! Value of extension
|
|
157
|
-
// "valueDecimal" : <decimal>, // R! Value of extension
|
|
158
|
-
// "valueInteger" : <integer>, // R! Value of extension
|
|
159
|
-
// }
|
|
160
|
-
case "minExclusive":
|
|
161
|
-
case "minInclusive":
|
|
162
|
-
// http://hl7.org/fhir/StructureDefinition/maxValue
|
|
163
|
-
case "maxExclusive":
|
|
164
|
-
case "maxInclusive":
|
|
165
|
-
extValue = this._exportMinMax(dataType, value, valueKey, key);
|
|
166
|
-
break;
|
|
167
|
-
// http://hl7.org/fhir/StructureDefinition/minLength
|
|
168
|
-
case "minLength":
|
|
169
|
-
if (dataType === "ST" || dataType === "TX" || dataType === "URL" ||
|
|
170
|
-
dataType === "QTY") {
|
|
171
|
-
extValue = {
|
|
172
|
-
"url":"http://hl7.org/fhir/StructureDefinition/minLength",
|
|
173
|
-
"valueInteger": parseInt(value)
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
break;
|
|
177
|
-
// maxLength, not an extension, directly on item
|
|
178
|
-
case "maxLength":
|
|
179
|
-
if (dataType === "ST" || dataType === "TX" || dataType === "URL" ||
|
|
180
|
-
dataType === "QTY") {
|
|
181
|
-
targetItem.maxLength = parseInt(value);
|
|
182
|
-
}
|
|
183
|
-
break;
|
|
184
|
-
// http://hl7.org/fhir/StructureDefinition/regex
|
|
185
|
-
case "pattern":
|
|
186
|
-
if (dataType === "ST" || dataType === "TX" ) {
|
|
187
|
-
extValue = {
|
|
188
|
-
"url":"http://hl7.org/fhir/StructureDefinition/regex",
|
|
189
|
-
"valueString": value
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
break
|
|
193
|
-
}
|
|
194
|
-
if (extValue) {
|
|
195
|
-
targetItem.extension.push(extValue);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
},
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Check if a LForms item has repeating questions
|
|
204
|
-
* @param item a LForms item
|
|
205
|
-
* @returns {*|boolean}
|
|
206
|
-
* @private
|
|
207
|
-
*/
|
|
208
|
-
_questionRepeats: function(item) {
|
|
209
|
-
return item && item.questionCardinality && item.questionCardinality.max &&
|
|
210
|
-
(item.questionCardinality.max === "*" || parseInt(item.questionCardinality.max) > 1)
|
|
211
|
-
},
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Check if a LForms item has repeating answers
|
|
216
|
-
* @param item a LForms item
|
|
217
|
-
* @returns {*|boolean}
|
|
218
|
-
* @private
|
|
219
|
-
*/
|
|
220
|
-
_answerRepeats: function(item) {
|
|
221
|
-
return item && item.answerCardinality && item.answerCardinality.max &&
|
|
222
|
-
(item.answerCardinality.max === "*" || parseInt(item.answerCardinality.max) > 1)
|
|
223
|
-
},
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Processes settings for a list field with choices.
|
|
228
|
-
* @param targetItem an item in FHIR SDC Questionnaire object
|
|
229
|
-
* @param item an item in the LForms form object
|
|
230
|
-
* @param noExtensions a flag that a standard FHIR Questionnaire is to be created without any extensions.
|
|
231
|
-
* The default is false.
|
|
232
|
-
*/
|
|
233
|
-
_handleChoiceField: function(targetItem, item, noExtensions) {
|
|
234
|
-
// an extension for the search url of the auto-complete field.
|
|
235
|
-
if(item.externallyDefined) {
|
|
236
|
-
this._handleExternallyDefined(targetItem, item);
|
|
237
|
-
}
|
|
238
|
-
// option, for answer list
|
|
239
|
-
else if (item.answers && !item.answerValueSet) {
|
|
240
|
-
// Make sure the answers did not come from answerExpression.
|
|
241
|
-
if (!item._fhirExt || !item._fhirExt[this.fhirExtAnswerExp])
|
|
242
|
-
targetItem.option = this._handleAnswers(item, noExtensions);
|
|
243
|
-
}
|
|
244
|
-
else if (item.answerValueSet)
|
|
245
|
-
targetItem.options = item.answerValueSet;
|
|
246
|
-
},
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Process an item's answer list
|
|
251
|
-
* @param item an item in the LForms form object
|
|
252
|
-
* @param noExtensions a flag that a standard FHIR Questionnaire is to be created without any extensions.
|
|
253
|
-
* The default is false.
|
|
254
|
-
* @returns {Array}
|
|
255
|
-
* @private
|
|
256
|
-
*/
|
|
257
|
-
_handleAnswers: function(item, noExtensions) {
|
|
258
|
-
var optionArray = [];
|
|
259
|
-
for (var i=0, iLen=item.answers.length; i<iLen; i++) {
|
|
260
|
-
var answer = item.answers[i];
|
|
261
|
-
var option = {};
|
|
262
|
-
|
|
263
|
-
// needs an extension for label
|
|
264
|
-
if (!noExtensions) {
|
|
265
|
-
var ext = [];
|
|
266
|
-
if(answer.label) {
|
|
267
|
-
ext.push({
|
|
268
|
-
"url" : "http://hl7.org/fhir/StructureDefinition/questionnaire-optionPrefix",
|
|
269
|
-
"valueString" : answer.label
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (answer.score !== null && answer.score !== undefined) {
|
|
274
|
-
ext.push({
|
|
275
|
-
"url" : "http://hl7.org/fhir/StructureDefinition/questionnaire-ordinalValue",
|
|
276
|
-
"valueDecimal" : parseFloat(answer.score)
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
if(ext.length > 0) {
|
|
280
|
-
option.extension = ext;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
// option's value supports integer, date, time, string and Coding
|
|
284
|
-
// for LForms, all answers are Coding
|
|
285
|
-
option.valueCoding = {};
|
|
286
|
-
if (answer.code) option.valueCoding.code = answer.code;
|
|
287
|
-
if (answer.text) option.valueCoding.display = answer.text;
|
|
288
|
-
|
|
289
|
-
if (answer.system) {
|
|
290
|
-
option.valueCoding.system = LForms.Util.getCodeSystem(answer.system);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
optionArray.push(option);
|
|
294
|
-
}
|
|
295
|
-
return optionArray;
|
|
296
|
-
},
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Process default values
|
|
301
|
-
* @param targetItem an item in FHIR SDC Questionnaire object
|
|
302
|
-
* @param item an item in LForms form object
|
|
303
|
-
* @private
|
|
304
|
-
*/
|
|
305
|
-
_handleInitialValues: function(targetItem, item) {
|
|
306
|
-
// dataType:
|
|
307
|
-
// boolean, decimal, integer, date, dateTime, instant, time, string, uri,
|
|
308
|
-
// Attachment, Coding, Quantity, Reference(Resource)
|
|
309
|
-
|
|
310
|
-
if (item.defaultAnswer !== null && item.defaultAnswer !== undefined && item.defaultAnswer !== '') {
|
|
311
|
-
|
|
312
|
-
var dataType = this._getAssumedDataTypeForExport(item);
|
|
313
|
-
var valueKey = this._getValueKeyByDataType("initial", item);
|
|
314
|
-
// for Coding
|
|
315
|
-
// multiple selections, item.value is an array
|
|
316
|
-
// NO support of multiple selections in FHIR SDC, just pick one
|
|
317
|
-
if (dataType === 'CWE' || dataType === 'CNE' ) {
|
|
318
|
-
var codeSystem = null, coding = null;
|
|
319
|
-
|
|
320
|
-
// item.defaultAnswer could be an array of multiple default values or a single value.
|
|
321
|
-
// in STU3 'initial[x]' is a single value. pick the first one if defaultAnswer is an array.
|
|
322
|
-
var defaultAnswer = (this._answerRepeats(item) && Array.isArray(item.defaultAnswer)) ?
|
|
323
|
-
item.defaultAnswer[0] : item.defaultAnswer;
|
|
324
|
-
if (typeof defaultAnswer === 'object') {
|
|
325
|
-
coding = {
|
|
326
|
-
"code": defaultAnswer.code,
|
|
327
|
-
};
|
|
328
|
-
if(defaultAnswer !== undefined) {
|
|
329
|
-
coding.display = defaultAnswer.text;
|
|
330
|
-
}
|
|
331
|
-
// code system
|
|
332
|
-
codeSystem = defaultAnswer.system || item.answerCodeSystem;
|
|
333
|
-
if (codeSystem) {
|
|
334
|
-
coding.system = LForms.Util.getCodeSystem(codeSystem);
|
|
335
|
-
}
|
|
336
|
-
targetItem[valueKey] = coding;
|
|
337
|
-
}
|
|
338
|
-
// user typed answer that is not on the answer list.
|
|
339
|
-
else if (typeof defaultAnswer === 'string') {
|
|
340
|
-
targetItem["initialString"] = defaultAnswer
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
// for Quantity,
|
|
344
|
-
// [{
|
|
345
|
-
// // from Element: extension
|
|
346
|
-
// "value" : <decimal>, // Numerical value (with implicit precision)
|
|
347
|
-
// "comparator" : "<code>", // < | <= | >= | > - how to understand the value
|
|
348
|
-
// "unit" : "<string>", // Unit representation
|
|
349
|
-
// "system" : "<uri>", // Code System that defines coded unit form
|
|
350
|
-
// "code" : "<code>" // Coded form of the unit
|
|
351
|
-
// }]
|
|
352
|
-
else if (dataType === 'QTY') { // for now, handling only simple quantities without the comparators.
|
|
353
|
-
var fhirQuantity = this._makeQuantity(item.defaultAnswer, item.units);
|
|
354
|
-
if(fhirQuantity) {
|
|
355
|
-
targetItem[valueKey] = fhirQuantity;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
// for boolean, decimal, integer, date, dateTime, instant, time, string, uri
|
|
359
|
-
else if (dataType === "BL" || dataType === "REAL" || dataType === "INT" ||
|
|
360
|
-
dataType === "TM" || dataType === "ST" || dataType === "TX" || dataType === "URL") {
|
|
361
|
-
targetItem[valueKey] = item.defaultAnswer;
|
|
362
|
-
}
|
|
363
|
-
else if (dataType === "DT" || dataType === "DTM") { // transform to FHIR date/datetime format.
|
|
364
|
-
var dateValue = LForms.Util.stringToDate(item.defaultAnswer);
|
|
365
|
-
if(dateValue) {
|
|
366
|
-
dateValue = dataType === "DTM"?
|
|
367
|
-
LForms.Util.dateToDTMString(dateValue): LForms.Util.dateToDTStringISO(dateValue);
|
|
368
|
-
targetItem[valueKey] = dateValue;
|
|
369
|
-
}
|
|
370
|
-
else { // LForms.Util.stringToDate returns null on invalid string
|
|
371
|
-
//TODO: should save the errors or emitting events.
|
|
372
|
-
console.error(item.defaultAnswer + ': Invalid date/datetime string as defaultAnswer for ' + item.questionCode);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
// no support for reference
|
|
376
|
-
}
|
|
377
|
-
},
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Process units list
|
|
382
|
-
* @param targetItem an item in FHIR SDC Questionnaire object
|
|
383
|
-
* @param item an item in LForms form object
|
|
384
|
-
* @private
|
|
385
|
-
*/
|
|
386
|
-
_handleLFormsUnits: function(targetItem, item) {
|
|
387
|
-
if (item.units && item.units.length > 0) {
|
|
388
|
-
var dataType = this._getAssumedDataTypeForExport(item);
|
|
389
|
-
if(dataType === "REAL" || dataType === "INT") {
|
|
390
|
-
|
|
391
|
-
targetItem.extension.push({
|
|
392
|
-
"url": this.fhirExtUrlUnit,
|
|
393
|
-
// Datatype with multiple units is quantity. There is only one unit here.
|
|
394
|
-
"valueCoding" : self._createFhirUnitCoding(item.units[0])
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
else if(dataType === 'QTY') {
|
|
398
|
-
var defUnit = this._getDefaultUnit(item.units);
|
|
399
|
-
if ((defUnit && defUnit.default) || targetItem.initialQuantity) {
|
|
400
|
-
// Use initial[].valueQuantity.unit to export the default unit.
|
|
401
|
-
if (!targetItem.initialQuantity) {
|
|
402
|
-
targetItem.initialQuantity = {};
|
|
403
|
-
}
|
|
404
|
-
self._setUnitAttributesToFhirQuantity(targetItem.initialQuantity, defUnit);
|
|
405
|
-
}
|
|
406
|
-
for (var i=0, iLen=item.units.length; i<iLen; i++) {
|
|
407
|
-
var unit = item.units[i];
|
|
408
|
-
var fhirUnitExt = {
|
|
409
|
-
"url": this.fhirExtUrlUnitOption,
|
|
410
|
-
"valueCoding": self._createFhirUnitCoding(unit)
|
|
411
|
-
};
|
|
412
|
-
targetItem.extension.push(fhirUnitExt);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
},
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
/**
|
|
420
|
-
* Process skip logic
|
|
421
|
-
* @param targetItem an item in FHIR SDC Questionnaire object
|
|
422
|
-
* @param item an item in LForms form object
|
|
423
|
-
* @param source a LForms form object
|
|
424
|
-
* @private
|
|
425
|
-
*/
|
|
426
|
-
_handleSkipLogic: function(targetItem, item, source) {
|
|
427
|
-
if (item.skipLogic) {
|
|
428
|
-
var enableWhen = [];
|
|
429
|
-
|
|
430
|
-
// ignore "ANY", "ALL" on item.skipLogic.logic
|
|
431
|
-
// ignore "show" on item.skipLogic.action
|
|
432
|
-
|
|
433
|
-
for (var i=0, iLen=item.skipLogic.conditions.length; i<iLen; i++) {
|
|
434
|
-
var condition = item.skipLogic.conditions[i];
|
|
435
|
-
var sourceItem = source._getSkipLogicSourceItem(item,condition.source);
|
|
436
|
-
|
|
437
|
-
var enableWhenRule = {
|
|
438
|
-
"question": sourceItem.linkId
|
|
439
|
-
};
|
|
440
|
-
// dataTypes:
|
|
441
|
-
// boolean, decimal, integer, date, dateTime, instant, time, string, uri,
|
|
442
|
-
// Attachment, Coding, Quantity, Reference(Resource)
|
|
443
|
-
var valueKey = this._getValueKeyByDataType("answer", sourceItem);
|
|
444
|
-
var dataType = this._getAssumedDataTypeForExport(sourceItem);
|
|
445
|
-
|
|
446
|
-
if(condition.trigger.hasOwnProperty('exists')) {
|
|
447
|
-
enableWhenRule.hasAnswer = condition.trigger.exists;
|
|
448
|
-
}
|
|
449
|
-
// for Coding
|
|
450
|
-
// multiple selections, item.value is an array
|
|
451
|
-
// NO support of multiple selections in FHIR SDC, just pick one
|
|
452
|
-
else if (dataType === 'CWE' || dataType === 'CNE' ) {
|
|
453
|
-
let answerCoding = self._copyTriggerCoding(condition.trigger.value, null, true);
|
|
454
|
-
if (answerCoding) {
|
|
455
|
-
enableWhenRule[valueKey] = answerCoding;
|
|
456
|
-
}
|
|
457
|
-
else {
|
|
458
|
-
throw new Error("Unable to convert trigger to answerCoding: " + condition.trigger.value);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
// for Quantity,
|
|
462
|
-
// [{
|
|
463
|
-
// // from Element: extension
|
|
464
|
-
// "value" : <decimal>, // Numerical value (with implicit precision)
|
|
465
|
-
// "comparator" : "<code>", // < | <= | >= | > - how to understand the value
|
|
466
|
-
// "unit" : "<string>", // Unit representation
|
|
467
|
-
// "system" : "<uri>", // Code System that defines coded unit form
|
|
468
|
-
// "code" : "<code>" // Coded form of the unit
|
|
469
|
-
// }]
|
|
470
|
-
else if (dataType === 'QTY') { // for now, handling only simple quantities without the comparators.
|
|
471
|
-
let fhirQuantity = this._makeQuantity(condition.trigger.value, sourceItem.units);
|
|
472
|
-
if(fhirQuantity) {
|
|
473
|
-
enableWhenRule[valueKey] = fhirQuantity;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
// for boolean, decimal, integer, date, dateTime, instant, time, string, uri
|
|
477
|
-
else if (dataType === "BL" || dataType === "REAL" || dataType === "INT" ||
|
|
478
|
-
dataType === "DT" || dataType === "DTM" || dataType === "TM" ||
|
|
479
|
-
dataType === "ST" || dataType === "TX" || dataType === "URL") {
|
|
480
|
-
enableWhenRule[valueKey] = condition.trigger.value;
|
|
481
|
-
// TODO luanx2: similarly, REAL, INT with unit should be valueQuantity? Leave as is for now.
|
|
482
|
-
}
|
|
483
|
-
// add a rule to enableWhen
|
|
484
|
-
enableWhen.push(enableWhenRule)
|
|
485
|
-
}
|
|
486
|
-
targetItem.enableWhen = enableWhen;
|
|
487
|
-
}
|
|
488
|
-
},
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
};
|
|
492
|
-
|
|
493
|
-
export default self;
|