lforms 29.3.0 → 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 +261 -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,494 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A package to handle conversion from FHIR SDC (STU2) Questionnaire to LForms
|
|
3
|
-
* STU2 Ballot:
|
|
4
|
-
* http://hl7.org/fhir/us/sdc/sdc-questionnaire.html
|
|
5
|
-
* http://hl7.org/fhir/us/sdc/sdc-questionnaireresponse.html
|
|
6
|
-
*
|
|
7
|
-
* It provides the following functions:
|
|
8
|
-
* convertQuestionnaireToLForms()
|
|
9
|
-
* -- Convert FHIR SDC QuestionnaireResponse data into corresponding LForms data
|
|
10
|
-
* mergeQuestionnaireResponseToLForms() (defined in sdc-import-common.js)
|
|
11
|
-
* -- Merge FHIR SDC QuestionnaireResponse data into corresponding LForms data
|
|
12
|
-
*/
|
|
13
|
-
function addSDCImportFns(ns) {
|
|
14
|
-
"use strict";
|
|
15
|
-
|
|
16
|
-
var self = ns;
|
|
17
|
-
|
|
18
|
-
self.fhirExtUrlOptionScore = "http://hl7.org/fhir/StructureDefinition/questionnaire-ordinalValue";
|
|
19
|
-
self.fhirExtUrlValueSetScore = "http://hl7.org/fhir/StructureDefinition/valueset-ordinalValue";
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Extract contained VS (if any) from the given questionnaire resource object.
|
|
24
|
-
* @param questionnaire the FHIR questionnaire resource object
|
|
25
|
-
* @return when there are contained value sets, returns a hash from "#<ValueSet.id>" (the character "#"
|
|
26
|
-
* followed by the ValueSet id) to the answers options object, which, in turn, is a hash with 4 entries:
|
|
27
|
-
* - "answers" is the list of LF answers converted from the value set.
|
|
28
|
-
* - "systems" is the list of code systems for each answer item; and
|
|
29
|
-
* returns undefined if no contained value set is present.
|
|
30
|
-
* @private
|
|
31
|
-
*/
|
|
32
|
-
self._extractContainedVS = function (questionnaire) {
|
|
33
|
-
var answersVS;
|
|
34
|
-
|
|
35
|
-
if(questionnaire.contained && questionnaire.contained.length > 0) {
|
|
36
|
-
answersVS = {};
|
|
37
|
-
questionnaire.contained.forEach(function(vs) {
|
|
38
|
-
if(vs.resourceType === 'ValueSet' && vs.expansion && vs.expansion.contains && vs.expansion.contains.length > 0) {
|
|
39
|
-
var answers = self.answersFromVS(vs);
|
|
40
|
-
if (!answers)
|
|
41
|
-
answers = []; // continuing with previous default; not sure if needed
|
|
42
|
-
|
|
43
|
-
// support both id and url based lookup. STU3 reference is quite vague.
|
|
44
|
-
var lfVS = {answers: answers};
|
|
45
|
-
if(vs.id) {
|
|
46
|
-
answersVS['#' + vs.id] = lfVS;
|
|
47
|
-
}
|
|
48
|
-
if(vs.url) {
|
|
49
|
-
answersVS[vs.url] = lfVS;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return answersVS;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Process questionnaire item recursively
|
|
60
|
-
*
|
|
61
|
-
* @param qItem - item object as defined in FHIR Questionnaire.
|
|
62
|
-
* @param linkIdItemMap - Map of items from link ID to item from the imported resource.
|
|
63
|
-
* @param containedVS - contained ValueSet info, see _extractContainedVS() for data format details
|
|
64
|
-
* @returns {{}} - Converted 'item' field object as defined by LForms definition.
|
|
65
|
-
* @private
|
|
66
|
-
*/
|
|
67
|
-
self._processQuestionnaireItem = function (qItem, containedVS, linkIdItemMap) {
|
|
68
|
-
|
|
69
|
-
var targetItem = {};
|
|
70
|
-
//A lot of parsing depends on data type. Extract it first.
|
|
71
|
-
self._processDataType(targetItem, qItem);
|
|
72
|
-
self._processTextAndPrefix(targetItem, qItem);
|
|
73
|
-
self._processCodeAndLinkId(targetItem, qItem);
|
|
74
|
-
_processDisplayItemCode(targetItem, qItem);
|
|
75
|
-
_processEditable(targetItem, qItem);
|
|
76
|
-
self._processFHIRQuestionAndAnswerCardinality(targetItem, qItem);
|
|
77
|
-
self._processDisplayControl(targetItem, qItem);
|
|
78
|
-
self._processDataControl(targetItem, qItem);
|
|
79
|
-
self._processRestrictions(targetItem, qItem);
|
|
80
|
-
self._processHiddenItem(targetItem, qItem);
|
|
81
|
-
self._processUnitList(targetItem, qItem);
|
|
82
|
-
_processAnswers(targetItem, qItem, containedVS);
|
|
83
|
-
self._processDefaultAnswer(targetItem, qItem);
|
|
84
|
-
_processExternallyDefined(targetItem, qItem);
|
|
85
|
-
self._processTerminologyServer(targetItem, qItem);
|
|
86
|
-
_processSkipLogic(targetItem, qItem, linkIdItemMap);
|
|
87
|
-
self._processExtensions(targetItem, qItem);
|
|
88
|
-
self._processChildItems(targetItem, qItem, containedVS, linkIdItemMap);
|
|
89
|
-
|
|
90
|
-
return targetItem;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Parse questionnaire object for answer cardinality
|
|
96
|
-
*
|
|
97
|
-
* @param lfItem {object} - LForms item object to assign answer cardinality
|
|
98
|
-
* @param qItem {object} - Questionnaire item object
|
|
99
|
-
* @private
|
|
100
|
-
*/
|
|
101
|
-
function _processAnswerCardinality(lfItem, qItem) {
|
|
102
|
-
if(qItem.required) {
|
|
103
|
-
lfItem.answerCardinality = {min: '1'};
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
lfItem.answerCardinality = {min: '0'};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
var answerRepeats = LForms.Util.findObjectInArray(qItem.extension, 'url', self.fhirExtUrlAnswerRepeats);
|
|
110
|
-
if(answerRepeats && answerRepeats.valueBoolean) {
|
|
111
|
-
lfItem.answerCardinality.max = '*';
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
lfItem.answerCardinality.max = '1';
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Parse questionnaire object for skip logic information
|
|
121
|
-
*
|
|
122
|
-
* @param lfItem {object} - LForms item object to assign the skip logic
|
|
123
|
-
* @param qItem {object} - Questionnaire item object
|
|
124
|
-
* @param sourceQuestionnaire - Questionnaire resource object. This is to provide top level
|
|
125
|
-
* item to navigate the tree for skip logic source items.
|
|
126
|
-
* @private
|
|
127
|
-
*/
|
|
128
|
-
function _processSkipLogic(lfItem, qItem, linkIdItemMap) {
|
|
129
|
-
if(qItem.enableWhen) {
|
|
130
|
-
lfItem.skipLogic = {conditions: [], action: 'show'};
|
|
131
|
-
for(var i = 0; i < qItem.enableWhen.length; i++) {
|
|
132
|
-
|
|
133
|
-
var dataType = self._getDataType(linkIdItemMap[qItem.enableWhen[i].question]);
|
|
134
|
-
var condition = {source: qItem.enableWhen[i].question};
|
|
135
|
-
if(qItem.enableWhen[i].hasOwnProperty('hasAnswer')) {
|
|
136
|
-
condition.trigger = {exists: qItem.enableWhen[i].hasAnswer};
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
var answer = self._getFHIRValueWithPrefixKey(qItem.enableWhen[i], /^answer/);
|
|
140
|
-
if(dataType === 'CWE' || dataType === 'CNE') {
|
|
141
|
-
condition.trigger = {value: self._copyTriggerCoding(answer, null, false)};
|
|
142
|
-
}
|
|
143
|
-
else if(dataType === 'QTY') {
|
|
144
|
-
condition.trigger = {value: answer.value};
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
condition.trigger = {value: answer};
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
lfItem.skipLogic.conditions.push(condition);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Parse Questionnaire item for externallyDefined url
|
|
158
|
-
*
|
|
159
|
-
* @param lfItem - LForms item object to assign externallyDefined
|
|
160
|
-
* @param qItem - Questionnaire item object
|
|
161
|
-
* @private
|
|
162
|
-
*/
|
|
163
|
-
function _processExternallyDefined(lfItem, qItem) {
|
|
164
|
-
var externallyDefined = LForms.Util.findObjectInArray(qItem.extension, 'url', self.fhirExtUrlExternallyDefined);
|
|
165
|
-
if (externallyDefined && externallyDefined.valueUri) {
|
|
166
|
-
lfItem.externallyDefined = externallyDefined.valueUri;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Parse questionnaire item for "hidden" extension
|
|
173
|
-
*
|
|
174
|
-
* @param lfItem {object} - LForms item object to be assigned the _isHiddenInDef flag if the item is to be hidden.
|
|
175
|
-
* @param qItem {object} - Questionnaire item object
|
|
176
|
-
* @private
|
|
177
|
-
* @return true if the item is hidden or if its ancestor is hidden, false otherwise
|
|
178
|
-
*/
|
|
179
|
-
self._processHiddenItem = function (lfItem, qItem) {
|
|
180
|
-
var ci = LForms.Util.findObjectInArray(qItem.extension, 'url', self.fhirExtUrlHidden);
|
|
181
|
-
if(ci) {
|
|
182
|
-
lfItem._isHiddenInDef = typeof ci.valueBoolean === 'boolean'? ci.valueBoolean: ci.valueBoolean === 'true';
|
|
183
|
-
}
|
|
184
|
-
return lfItem._isHiddenInDef;
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Parse questionnaire item for answers list
|
|
190
|
-
*
|
|
191
|
-
* @param lfItem {object} - LForms item object to assign answer list
|
|
192
|
-
* @param qItem {object} - Questionnaire item object
|
|
193
|
-
* @param containedVS - contained ValueSet info, see _extractContainedVS() for data format details
|
|
194
|
-
* @private
|
|
195
|
-
*/
|
|
196
|
-
function _processAnswers(lfItem, qItem, containedVS) {
|
|
197
|
-
if(qItem.option) {
|
|
198
|
-
lfItem.answers = [];
|
|
199
|
-
for(var i = 0; i < qItem.option.length; i++) {
|
|
200
|
-
var answer = {};
|
|
201
|
-
var option = qItem.option[i];
|
|
202
|
-
var label = LForms.Util.findObjectInArray(option.extension, 'url', self.fhirExtUrlOptionPrefix);
|
|
203
|
-
if(label) {
|
|
204
|
-
answer.label = label.valueString;
|
|
205
|
-
}
|
|
206
|
-
var score = LForms.Util.findObjectInArray(option.extension, 'url', self.fhirExtUrlOptionScore);
|
|
207
|
-
// Look for argonaut extension.
|
|
208
|
-
score = !score ? LForms.Util.findObjectInArray(option.extension, 'url', self.argonautExtUrlExtensionScore) : score;
|
|
209
|
-
if(score) {
|
|
210
|
-
answer.score = score.valueDecimal.toString();
|
|
211
|
-
}
|
|
212
|
-
var optionKey = Object.keys(option).filter(function(key) {return (key.indexOf('value') === 0);});
|
|
213
|
-
if(optionKey && optionKey.length > 0) {
|
|
214
|
-
if(optionKey[0] === 'valueCoding') { // Only one value[x] is expected
|
|
215
|
-
if(option[optionKey[0]].code !== undefined) answer.code = option[optionKey[0]].code;
|
|
216
|
-
if(option[optionKey[0]].display !== undefined) answer.text = option[optionKey[0]].display;
|
|
217
|
-
// TBD- Lforms has answer code system at item level, expects all options to have one code system!
|
|
218
|
-
if(option[optionKey[0]].system !== undefined) {
|
|
219
|
-
answer.system = option[optionKey[0]].system;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
answer.text = option[optionKey[0]].toString();
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
lfItem.answers.push(answer);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
else if (qItem.options) {
|
|
231
|
-
if (containedVS)
|
|
232
|
-
var vs = containedVS[qItem.options.reference];
|
|
233
|
-
if(vs) {
|
|
234
|
-
lfItem.answers = vs.answers;
|
|
235
|
-
}
|
|
236
|
-
else
|
|
237
|
-
lfItem.answerValueSet = qItem.options.reference;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Parse questionnaire item for editable
|
|
245
|
-
*
|
|
246
|
-
* @param lfItem {object} - LForms item object to assign editable
|
|
247
|
-
* @param qItem {object} - Questionnaire item object
|
|
248
|
-
* @private
|
|
249
|
-
*/
|
|
250
|
-
function _processEditable(lfItem, qItem) {
|
|
251
|
-
if (qItem.readOnly) {
|
|
252
|
-
lfItem.editable = '0';
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Parse questionnaire item for default answer
|
|
259
|
-
*
|
|
260
|
-
* @param lfItem {object} - LForms item object to assign default answer
|
|
261
|
-
* @param qItem {object} - Questionnaire item object
|
|
262
|
-
* @private
|
|
263
|
-
*/
|
|
264
|
-
self._processDefaultAnswer = function (lfItem, qItem) {
|
|
265
|
-
|
|
266
|
-
var val = LForms.Util.deepCopy(qItem.initialCoding);
|
|
267
|
-
if (val)
|
|
268
|
-
val._type = 'Coding';
|
|
269
|
-
else
|
|
270
|
-
val = self._getFHIRValueWithPrefixKey(qItem, /^initial/);
|
|
271
|
-
if (val) {
|
|
272
|
-
this._processFHIRValues(lfItem, [val], true);
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Returns the first initial quanitity for the given Questionnaire item, or
|
|
279
|
-
* null if there isn't one.
|
|
280
|
-
*/
|
|
281
|
-
self.getFirstInitialQuantity = function(qItem) {
|
|
282
|
-
return qItem.initialQuantity || null;
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Parse 'linkId' for the LForms questionCode of a 'display' item, which does not have a 'code'
|
|
288
|
-
*
|
|
289
|
-
* @param lfItem {object} - LForms item object to assign questionCode
|
|
290
|
-
* @param qItem {object} - Questionnaire item object
|
|
291
|
-
* @private
|
|
292
|
-
*/
|
|
293
|
-
function _processDisplayItemCode(lfItem, qItem) {
|
|
294
|
-
if (qItem.type === "display" && qItem.linkId) {
|
|
295
|
-
var codes = qItem.linkId.split("/");
|
|
296
|
-
if (codes && codes[codes.length-1]) {
|
|
297
|
-
lfItem.questionCode = codes[codes.length-1];
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Parse questionnaire item for data type
|
|
305
|
-
*
|
|
306
|
-
* @param lfItem {object} - LForms item object to assign data type
|
|
307
|
-
* @param qItem {object} - Questionnaire item object
|
|
308
|
-
* @private
|
|
309
|
-
*/
|
|
310
|
-
self._processDataType = function (lfItem, qItem) {
|
|
311
|
-
var type = self._getDataType(qItem);
|
|
312
|
-
if(type === 'SECTION' || type === 'TITLE') {
|
|
313
|
-
lfItem.header = true;
|
|
314
|
-
}
|
|
315
|
-
lfItem.dataType = type;
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
// QuesitonnaireResponse Import
|
|
321
|
-
self._mergeQR = {
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Get structure information of a QuestionnaireResponse instance
|
|
325
|
-
* @param qr a QuestionnaireResponse instance
|
|
326
|
-
* @returns {{}} a QuestionnaireResponse data structure object
|
|
327
|
-
* @private
|
|
328
|
-
*/
|
|
329
|
-
_getQRStructure : function(qr) {
|
|
330
|
-
var qrInfo = {
|
|
331
|
-
qrItemsInfo: []
|
|
332
|
-
};
|
|
333
|
-
if (qr) {
|
|
334
|
-
this._checkQRItems(qrInfo, qr);
|
|
335
|
-
}
|
|
336
|
-
return qrInfo;
|
|
337
|
-
},
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Get structural info of a QuestionnaireResponse by going though each level of items
|
|
342
|
-
* @param parentQRItemInfo the structural info of a parent item
|
|
343
|
-
* @param parentItem a parent item in a QuestionnaireResponse object
|
|
344
|
-
* @private
|
|
345
|
-
*/
|
|
346
|
-
_checkQRItems : function(parentQRItemInfo, parentQRItem) {
|
|
347
|
-
|
|
348
|
-
var qrItemsInfo = [];
|
|
349
|
-
var repeatingItemProcessed = {};
|
|
350
|
-
|
|
351
|
-
if (parentQRItem && parentQRItem.item) {
|
|
352
|
-
for (var i=0, iLen=parentQRItem.item.length; i<iLen; i++) {
|
|
353
|
-
var item = parentQRItem.item[i];
|
|
354
|
-
var linkId = item.linkId; //code is not necessary included in linkId
|
|
355
|
-
// first item that has the same code, either repeating or non-repeating
|
|
356
|
-
if (!repeatingItemProcessed[linkId]) {
|
|
357
|
-
var repeatingInfo = this._findTotalRepeatingNum(linkId, parentQRItem);
|
|
358
|
-
|
|
359
|
-
// create structure info for the item
|
|
360
|
-
var repeatingItems = repeatingInfo.repeatingItems;
|
|
361
|
-
for (var j=0, jLen=repeatingItems.length; j<jLen; j++) {
|
|
362
|
-
var qrItemInfo = {
|
|
363
|
-
linkId: linkId,
|
|
364
|
-
item: repeatingItems[j],
|
|
365
|
-
index: j,
|
|
366
|
-
total: repeatingInfo.total
|
|
367
|
-
};
|
|
368
|
-
// check observation instances in the sub level
|
|
369
|
-
this._checkQRItems(qrItemInfo, repeatingItems[j]);
|
|
370
|
-
self._checkQRItemAnswerItems(qrItemInfo, repeatingItems[j]);
|
|
371
|
-
qrItemsInfo.push(qrItemInfo);
|
|
372
|
-
}
|
|
373
|
-
repeatingItemProcessed[linkId] = true;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
parentQRItemInfo.qrItemsInfo = qrItemsInfo;
|
|
377
|
-
}
|
|
378
|
-
},
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* Find the number of the repeating items that have the same code
|
|
383
|
-
* @param linkId an item's linkId
|
|
384
|
-
* @param parentQRItem a parent item in a QuestionnaireResponse object
|
|
385
|
-
* @returns a structural info object for a repeating item
|
|
386
|
-
* @private
|
|
387
|
-
*/
|
|
388
|
-
_findTotalRepeatingNum : function(linkId, parentQRItem) {
|
|
389
|
-
|
|
390
|
-
var total = 0;
|
|
391
|
-
var repeatingItems = [];
|
|
392
|
-
for (var i=0, iLen=parentQRItem.item.length; i<iLen; i++) {
|
|
393
|
-
var item = parentQRItem.item[i];
|
|
394
|
-
if (linkId === item.linkId) {
|
|
395
|
-
repeatingItems.push(item);
|
|
396
|
-
if (Array.isArray(item.answer)) {
|
|
397
|
-
total += item.answer.length; // answers for repeating questions and repeating answers
|
|
398
|
-
}
|
|
399
|
-
else {
|
|
400
|
-
total += 1;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
return {
|
|
406
|
-
total: total,
|
|
407
|
-
repeatingItems: repeatingItems
|
|
408
|
-
};
|
|
409
|
-
},
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Add repeating items into LForms definition data object
|
|
414
|
-
* @param parentItem a parent item
|
|
415
|
-
* @param linkId code of a repeating item
|
|
416
|
-
* @param total total number of the repeating item with the same code
|
|
417
|
-
* @private
|
|
418
|
-
*/
|
|
419
|
-
_addRepeatingItems : function(parentItem, linkId, total) {
|
|
420
|
-
// find the first (and the only one) item
|
|
421
|
-
var item = null;
|
|
422
|
-
if (parentItem.items) {
|
|
423
|
-
for(var i=0, iLen=parentItem.items.length; i<iLen; i++) {
|
|
424
|
-
if (linkId === parentItem.items[i].linkId) {
|
|
425
|
-
item = parentItem.items[i];
|
|
426
|
-
break;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
// insert new items
|
|
430
|
-
if (item) {
|
|
431
|
-
while(total > 1) {
|
|
432
|
-
var newItem = LForms.Util.deepCopy(item);
|
|
433
|
-
parentItem.items.splice(i, 0, newItem);
|
|
434
|
-
total -= 1;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
},
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Find a matching repeating item by item code and the index in the items array
|
|
443
|
-
* @param parentItem a parent item
|
|
444
|
-
* @param linkId linkId of a repeating (or non-repeating) item
|
|
445
|
-
* @param index index of the item in the sub item array of the parent item
|
|
446
|
-
* @returns {{}} a matching item
|
|
447
|
-
* @private
|
|
448
|
-
*/
|
|
449
|
-
_findTheMatchingItemByLinkIdAndIndex : function(parentItem, linkId, index) {
|
|
450
|
-
var item = null;
|
|
451
|
-
var idx = 0;
|
|
452
|
-
if (parentItem.items) {
|
|
453
|
-
for(var i=0, iLen=parentItem.items.length; i<iLen; i++) {
|
|
454
|
-
if (linkId === parentItem.items[i].linkId) {
|
|
455
|
-
if (idx === index) {
|
|
456
|
-
item = parentItem.items[i];
|
|
457
|
-
break;
|
|
458
|
-
}
|
|
459
|
-
else {
|
|
460
|
-
idx += 1;
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
return item;
|
|
466
|
-
},
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Find a matching repeating item by item code alone
|
|
471
|
-
* When used on the LForms definition data object, there is no repeating items yet.
|
|
472
|
-
* @param parentItem a parent item
|
|
473
|
-
* @param linkId linkId of an item
|
|
474
|
-
* @returns {{}} a matching item
|
|
475
|
-
* @private
|
|
476
|
-
*/
|
|
477
|
-
_findTheMatchingItemByLinkId : function(parentItem, linkId) {
|
|
478
|
-
var item = null;
|
|
479
|
-
if (parentItem.items) {
|
|
480
|
-
for(var i=0, iLen=parentItem.items.length; i<iLen; i++) {
|
|
481
|
-
if (linkId === parentItem.items[i].linkId) {
|
|
482
|
-
item = parentItem.items[i];
|
|
483
|
-
break;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
return item;
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
export default addSDCImportFns;
|