@glowgreen/gg-questionnaire-v2 0.0.82 → 0.0.84
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/bundles/glowgreen-gg-questionnaire-v2.umd.js +306 -1240
- package/bundles/glowgreen-gg-questionnaire-v2.umd.js.map +1 -1
- package/bundles/glowgreen-gg-questionnaire-v2.umd.min.js +15 -1
- package/bundles/glowgreen-gg-questionnaire-v2.umd.min.js.map +1 -1
- package/esm2015/glowgreen-gg-questionnaire-v2.js +2 -8
- package/esm2015/lib/enums/condition-relationship.enum.js +6 -11
- package/esm2015/lib/enums/condition-type.enum.js +10 -15
- package/esm2015/lib/enums/input-type.enum.js +15 -20
- package/esm2015/lib/enums/question-type.enum.js +15 -20
- package/esm2015/lib/enums/repeater-question-type.enum.js +7 -12
- package/esm2015/lib/enums/validation-type.enum.js +10 -15
- package/esm2015/lib/gg-questionnaire-v2.module.js +17 -13
- package/esm2015/lib/interfaces/attachment.js +1 -15
- package/esm2015/lib/interfaces/checklist-item.js +1 -15
- package/esm2015/lib/interfaces/condition-group.js +1 -15
- package/esm2015/lib/interfaces/condition.js +1 -17
- package/esm2015/lib/interfaces/question.js +1 -59
- package/esm2015/lib/interfaces/questionnaire-options.js +1 -21
- package/esm2015/lib/interfaces/questionnaire.js +1 -15
- package/esm2015/lib/interfaces/repeater-question.js +1 -33
- package/esm2015/lib/interfaces/section.js +1 -19
- package/esm2015/lib/interfaces/select-option.js +1 -19
- package/esm2015/lib/interfaces/validator.js +1 -15
- package/esm2015/lib/services/filter.service.js +45 -124
- package/esm2015/lib/services/form-constructor.service.js +30 -113
- package/esm2015/lib/services/questionnaire.service.js +97 -377
- package/esm2015/public_api.js +1 -5
- package/esm5/glowgreen-gg-questionnaire-v2.js +2 -8
- package/esm5/lib/enums/condition-relationship.enum.js +6 -11
- package/esm5/lib/enums/condition-type.enum.js +10 -15
- package/esm5/lib/enums/input-type.enum.js +15 -20
- package/esm5/lib/enums/question-type.enum.js +15 -20
- package/esm5/lib/enums/repeater-question-type.enum.js +7 -12
- package/esm5/lib/enums/validation-type.enum.js +10 -15
- package/esm5/lib/gg-questionnaire-v2.module.js +27 -27
- package/esm5/lib/interfaces/attachment.js +1 -15
- package/esm5/lib/interfaces/checklist-item.js +1 -15
- package/esm5/lib/interfaces/condition-group.js +1 -15
- package/esm5/lib/interfaces/condition.js +1 -17
- package/esm5/lib/interfaces/question.js +1 -59
- package/esm5/lib/interfaces/questionnaire-options.js +1 -21
- package/esm5/lib/interfaces/questionnaire.js +1 -15
- package/esm5/lib/interfaces/repeater-question.js +1 -33
- package/esm5/lib/interfaces/section.js +1 -19
- package/esm5/lib/interfaces/select-option.js +1 -19
- package/esm5/lib/interfaces/validator.js +1 -15
- package/esm5/lib/services/filter.service.js +47 -264
- package/esm5/lib/services/form-constructor.service.js +35 -247
- package/esm5/lib/services/questionnaire.service.js +105 -608
- package/esm5/public_api.js +1 -5
- package/fesm2015/glowgreen-gg-questionnaire-v2.js +245 -712
- package/fesm2015/glowgreen-gg-questionnaire-v2.js.map +1 -1
- package/fesm5/glowgreen-gg-questionnaire-v2.js +243 -1204
- package/fesm5/glowgreen-gg-questionnaire-v2.js.map +1 -1
- package/glowgreen-gg-questionnaire-v2.d.ts +1 -2
- package/lib/gg-questionnaire-v2.module.d.ts +5 -1
- package/lib/services/filter.service.d.ts +3 -0
- package/lib/services/form-constructor.service.d.ts +3 -0
- package/lib/services/questionnaire.service.d.ts +12 -9
- package/package.json +5 -3
- package/glowgreen-gg-questionnaire-v2.metadata.json +0 -1
|
@@ -1,72 +1,53 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ɵɵdefineInjectable, ɵsetClassMetadata, Injectable, ɵɵinject, EventEmitter, Inject, ɵɵdefineNgModule, ɵɵdefineInjector, ɵɵsetNgModuleScope, NgModule } from '@angular/core';
|
|
2
2
|
import { Validators, FormBuilder, FormArray, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
3
3
|
import { clone, get, keys, cloneDeep } from 'lodash';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Slider: 'slider',
|
|
20
|
-
Info: 'info',
|
|
21
|
-
Feedback: 'feedback',
|
|
22
|
-
};
|
|
5
|
+
var QuestionType;
|
|
6
|
+
(function (QuestionType) {
|
|
7
|
+
QuestionType["Input"] = "input";
|
|
8
|
+
QuestionType["Select"] = "select";
|
|
9
|
+
QuestionType["Textarea"] = "textarea";
|
|
10
|
+
QuestionType["Repeater"] = "repeater";
|
|
11
|
+
QuestionType["Checklist"] = "checklist";
|
|
12
|
+
QuestionType["Attachment"] = "attachment";
|
|
13
|
+
QuestionType["Upload"] = "upload";
|
|
14
|
+
QuestionType["Signature"] = "signature";
|
|
15
|
+
QuestionType["Slider"] = "slider";
|
|
16
|
+
QuestionType["Info"] = "info";
|
|
17
|
+
QuestionType["Feedback"] = "feedback";
|
|
18
|
+
})(QuestionType || (QuestionType = {}));
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
GreaterThan: 'greaterThan',
|
|
34
|
-
Includes: 'includes',
|
|
35
|
-
Excludes: 'excludes',
|
|
36
|
-
};
|
|
20
|
+
var ConditionType;
|
|
21
|
+
(function (ConditionType) {
|
|
22
|
+
ConditionType["EqualTo"] = "equalTo";
|
|
23
|
+
ConditionType["NotEqualTo"] = "notEqualTo";
|
|
24
|
+
ConditionType["LessThan"] = "lessThan";
|
|
25
|
+
ConditionType["GreaterThan"] = "greaterThan";
|
|
26
|
+
ConditionType["Includes"] = "includes";
|
|
27
|
+
ConditionType["Excludes"] = "excludes";
|
|
28
|
+
})(ConditionType || (ConditionType = {}));
|
|
37
29
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const ConditionRelationship = {
|
|
44
|
-
Every: 'every',
|
|
45
|
-
Any: 'any',
|
|
46
|
-
};
|
|
30
|
+
var ConditionRelationship;
|
|
31
|
+
(function (ConditionRelationship) {
|
|
32
|
+
ConditionRelationship["Every"] = "every";
|
|
33
|
+
ConditionRelationship["Any"] = "any";
|
|
34
|
+
})(ConditionRelationship || (ConditionRelationship = {}));
|
|
47
35
|
|
|
48
|
-
/**
|
|
49
|
-
* @fileoverview added by tsickle
|
|
50
|
-
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
51
|
-
*/
|
|
52
36
|
class FilterService {
|
|
53
37
|
constructor() { }
|
|
54
38
|
/**
|
|
55
39
|
* Filters an array of sections based on their condition groups.
|
|
40
|
+
* @param sections The array of sections to filter.
|
|
41
|
+
* @param currentQuestionnaireForm The current form data, can be null/undefined.
|
|
42
|
+
* @returns An array of filtered sections with their filtered questions.
|
|
56
43
|
* @author Will Poulson
|
|
57
|
-
* @param {?} sections The array of sections to filter.
|
|
58
|
-
* @param {?} currentQuestionnaireForm The current form data, can be null/undefined.
|
|
59
|
-
* @param {?=} additionalData
|
|
60
|
-
* @return {?} An array of filtered sections with their filtered questions.
|
|
61
44
|
*/
|
|
62
45
|
filterSections(sections, currentQuestionnaireForm, additionalData) {
|
|
63
|
-
/** @type {?} */
|
|
64
46
|
const filteredSections = [];
|
|
65
47
|
for (const section of sections) {
|
|
66
48
|
if (!this.meetsConditionGroups(section.conditionGroups, currentQuestionnaireForm, additionalData)) {
|
|
67
49
|
continue;
|
|
68
50
|
}
|
|
69
|
-
/** @type {?} */
|
|
70
51
|
const filteredQuestions = [];
|
|
71
52
|
for (const question of section.questions) {
|
|
72
53
|
if (!this.meetsConditionGroups(question.conditionGroups, currentQuestionnaireForm, additionalData)) {
|
|
@@ -74,23 +55,18 @@ class FilterService {
|
|
|
74
55
|
}
|
|
75
56
|
// If it's a repeater we need to do a lot of extra filtering due to per item conditions.
|
|
76
57
|
if (question.type === 'repeater' && currentQuestionnaireForm) {
|
|
77
|
-
|
|
78
|
-
const items = (/** @type {?} */ (currentQuestionnaireForm.get([section.name, question.name])));
|
|
58
|
+
const items = currentQuestionnaireForm.get([section.name, question.name]);
|
|
79
59
|
if (items && items.controls) {
|
|
80
60
|
for (const repeaterItem of items.controls) {
|
|
81
|
-
/** @type {?} */
|
|
82
61
|
const filteredRepeaterItemQuestions = [];
|
|
83
62
|
for (const repeaterQuestion of question.repeaterQuestions) {
|
|
84
|
-
|
|
85
|
-
const meetsConditions = this.meetsConditionGroups(repeaterQuestion.conditionGroups, currentQuestionnaireForm, additionalData, (/** @type {?} */ (repeaterItem)));
|
|
63
|
+
const meetsConditions = this.meetsConditionGroups(repeaterQuestion.conditionGroups, currentQuestionnaireForm, additionalData, repeaterItem);
|
|
86
64
|
if (meetsConditions) {
|
|
87
|
-
/** @type {?} */
|
|
88
65
|
const cloneQuestion = clone(repeaterQuestion);
|
|
89
|
-
cloneQuestion.selectOptions = this.getFetchOptionsForQuestion(repeaterQuestion, additionalData, currentQuestionnaireForm,
|
|
66
|
+
cloneQuestion.selectOptions = this.getFetchOptionsForQuestion(repeaterQuestion, additionalData, currentQuestionnaireForm, repeaterItem);
|
|
90
67
|
filteredRepeaterItemQuestions.push(cloneQuestion);
|
|
91
68
|
}
|
|
92
69
|
}
|
|
93
|
-
/** @type {?} */
|
|
94
70
|
const index = items.controls.indexOf(repeaterItem);
|
|
95
71
|
if (!question.filteredRepeaterQuestions) {
|
|
96
72
|
question.filteredRepeaterQuestions = [];
|
|
@@ -110,22 +86,12 @@ class FilterService {
|
|
|
110
86
|
}
|
|
111
87
|
return filteredSections;
|
|
112
88
|
}
|
|
113
|
-
/**
|
|
114
|
-
* @private
|
|
115
|
-
* @param {?} question
|
|
116
|
-
* @param {?} additionalData
|
|
117
|
-
* @param {?} currentQuestionnaireForm
|
|
118
|
-
* @param {?=} repeaterItem
|
|
119
|
-
* @return {?}
|
|
120
|
-
*/
|
|
121
89
|
getFetchOptionsForQuestion(question, additionalData, currentQuestionnaireForm, repeaterItem) {
|
|
122
90
|
if (!question.fetchPath) {
|
|
123
91
|
return question.selectOptions;
|
|
124
92
|
}
|
|
125
|
-
/** @type {?} */
|
|
126
93
|
let options = additionalData[question.fetchPath];
|
|
127
94
|
if (question.fetchSelectors && question.fetchSelectors.length > 0) {
|
|
128
|
-
/** @type {?} */
|
|
129
95
|
const values = this.getValuesForArray(question.fetchSelectors, currentQuestionnaireForm, additionalData, repeaterItem);
|
|
130
96
|
options = get(additionalData[question.fetchPath], values);
|
|
131
97
|
}
|
|
@@ -135,11 +101,6 @@ class FilterService {
|
|
|
135
101
|
}
|
|
136
102
|
return question.selectOptions.concat(options);
|
|
137
103
|
}
|
|
138
|
-
/**
|
|
139
|
-
* @private
|
|
140
|
-
* @param {?} items
|
|
141
|
-
* @return {?}
|
|
142
|
-
*/
|
|
143
104
|
getFinalFetchArray(items) {
|
|
144
105
|
if (!items) {
|
|
145
106
|
return null;
|
|
@@ -150,11 +111,10 @@ class FilterService {
|
|
|
150
111
|
if (items.length <= 0) {
|
|
151
112
|
return null;
|
|
152
113
|
}
|
|
153
|
-
/** @type {?} */
|
|
154
114
|
const convertedArray = [];
|
|
155
115
|
for (const item of items) {
|
|
156
116
|
if (item) {
|
|
157
|
-
if (item instanceof Object && item.value && item.label) {
|
|
117
|
+
if (item instanceof Object && (item.value !== undefined) && item.label) {
|
|
158
118
|
convertedArray.push(item);
|
|
159
119
|
}
|
|
160
120
|
else {
|
|
@@ -164,111 +124,76 @@ class FilterService {
|
|
|
164
124
|
}
|
|
165
125
|
return convertedArray;
|
|
166
126
|
}
|
|
167
|
-
/**
|
|
168
|
-
* @private
|
|
169
|
-
* @param {?} item
|
|
170
|
-
* @return {?}
|
|
171
|
-
*/
|
|
172
127
|
uppercase(item) {
|
|
128
|
+
if (!isNaN(item)) {
|
|
129
|
+
return item;
|
|
130
|
+
}
|
|
173
131
|
return item.charAt(0).toUpperCase() + item.slice(1);
|
|
174
132
|
}
|
|
175
133
|
/**
|
|
176
134
|
* Checks if each condition groups conditions have been met.
|
|
135
|
+
* @param conditionGroups The array of condition groups.
|
|
136
|
+
* @param currentQuestionnaireForm The current form data, can be null/undefined.
|
|
137
|
+
* @returns A boolean stating if the condition groups conditions has been met.
|
|
177
138
|
* @author Will Poulson
|
|
178
|
-
* @private
|
|
179
|
-
* @param {?} conditionGroups The array of condition groups.
|
|
180
|
-
* @param {?} currentQuestionnaireForm The current form data, can be null/undefined.
|
|
181
|
-
* @param {?=} additionalData
|
|
182
|
-
* @param {?=} repeaterItem
|
|
183
|
-
* @return {?} A boolean stating if the condition groups conditions has been met.
|
|
184
139
|
*/
|
|
185
140
|
meetsConditionGroups(conditionGroups, currentQuestionnaireForm, additionalData, repeaterItem) {
|
|
186
141
|
if (!conditionGroups || conditionGroups.length === 0) {
|
|
187
142
|
return true;
|
|
188
143
|
}
|
|
189
|
-
return conditionGroups.every((
|
|
190
|
-
* @param {?} x
|
|
191
|
-
* @return {?}
|
|
192
|
-
*/
|
|
193
|
-
(x) => {
|
|
144
|
+
return conditionGroups.every((x) => {
|
|
194
145
|
return this.meetsConditionGroup(x, currentQuestionnaireForm, additionalData, repeaterItem) === true;
|
|
195
|
-
})
|
|
146
|
+
});
|
|
196
147
|
}
|
|
197
148
|
/**
|
|
198
149
|
* Checks if a condition groups conditions have been met.
|
|
150
|
+
* @param conditionGroup The condition group to check.
|
|
151
|
+
* @param currentQuestionnaireForm The current form data, can be null/undefined.
|
|
152
|
+
* @returns A boolean stating if the condition group conditions has been met.
|
|
199
153
|
* @author Will Poulson
|
|
200
|
-
* @private
|
|
201
|
-
* @param {?} conditionGroup The condition group to check.
|
|
202
|
-
* @param {?} currentQuestionnaireForm The current form data, can be null/undefined.
|
|
203
|
-
* @param {?=} additionalData
|
|
204
|
-
* @param {?=} repeaterItem
|
|
205
|
-
* @return {?} A boolean stating if the condition group conditions has been met.
|
|
206
154
|
*/
|
|
207
155
|
meetsConditionGroup(conditionGroup, currentQuestionnaireForm, additionalData, repeaterItem) {
|
|
208
156
|
if (!conditionGroup.conditions || conditionGroup.conditions.length === 0) {
|
|
209
157
|
return true;
|
|
210
158
|
}
|
|
211
|
-
/** @type {?} */
|
|
212
159
|
const results = [];
|
|
213
160
|
for (const condition of conditionGroup.conditions) {
|
|
214
161
|
results.push(this.meetsCondition(condition, currentQuestionnaireForm, additionalData, repeaterItem));
|
|
215
162
|
}
|
|
216
163
|
switch (conditionGroup.relationship) {
|
|
217
164
|
case ConditionRelationship.Every:
|
|
218
|
-
return results.every((
|
|
219
|
-
* @param {?} x
|
|
220
|
-
* @return {?}
|
|
221
|
-
*/
|
|
222
|
-
(x) => {
|
|
165
|
+
return results.every((x) => {
|
|
223
166
|
return x === true;
|
|
224
|
-
})
|
|
167
|
+
});
|
|
225
168
|
case ConditionRelationship.Any:
|
|
226
|
-
return !!results.find((
|
|
227
|
-
* @param {?} x
|
|
228
|
-
* @return {?}
|
|
229
|
-
*/
|
|
230
|
-
(x) => {
|
|
169
|
+
return !!results.find((x) => {
|
|
231
170
|
return x === true;
|
|
232
|
-
})
|
|
171
|
+
});
|
|
233
172
|
default:
|
|
234
173
|
return true;
|
|
235
174
|
}
|
|
236
175
|
}
|
|
237
176
|
/**
|
|
238
177
|
* Checks if a condition has been met.
|
|
178
|
+
* @param condition The condition to check.
|
|
179
|
+
* @param currentQuestionnaireForm The current form data, can be null/undefined.
|
|
180
|
+
* @returns A boolean stating if the condition group conditions has been met.
|
|
239
181
|
* @author Will Poulson
|
|
240
|
-
* @private
|
|
241
|
-
* @param {?} condition The condition to check.
|
|
242
|
-
* @param {?} currentQuestionnaireForm The current form data, can be null/undefined.
|
|
243
|
-
* @param {?=} additionalData
|
|
244
|
-
* @param {?=} repeaterItem
|
|
245
|
-
* @return {?} A boolean stating if the condition group conditions has been met.
|
|
246
182
|
*/
|
|
247
183
|
meetsCondition(condition, currentQuestionnaireForm, additionalData, repeaterItem) {
|
|
248
|
-
/** @type {?} */
|
|
249
184
|
const v1s = this.getValuesForArray(condition.v1s, currentQuestionnaireForm, additionalData, repeaterItem);
|
|
250
|
-
/** @type {?} */
|
|
251
185
|
const v2s = this.getValuesForArray(condition.v2s, currentQuestionnaireForm, additionalData, repeaterItem);
|
|
252
|
-
/** @type {?} */
|
|
253
186
|
let result = false;
|
|
254
187
|
switch (condition.type) {
|
|
255
188
|
case ConditionType.Excludes:
|
|
256
|
-
result = v1s.filter((
|
|
257
|
-
* @param {?} v1
|
|
258
|
-
* @return {?}
|
|
259
|
-
*/
|
|
260
|
-
(v1) => {
|
|
189
|
+
result = v1s.filter((v1) => {
|
|
261
190
|
return v2s.indexOf(v1) > -1;
|
|
262
|
-
})
|
|
191
|
+
}).length === 0;
|
|
263
192
|
break;
|
|
264
193
|
case ConditionType.Includes:
|
|
265
|
-
result = v1s.filter((
|
|
266
|
-
* @param {?} v1
|
|
267
|
-
* @return {?}
|
|
268
|
-
*/
|
|
269
|
-
(v1) => {
|
|
194
|
+
result = v1s.filter((v1) => {
|
|
270
195
|
return v2s.indexOf(v1) > -1;
|
|
271
|
-
})
|
|
196
|
+
}).length !== 0;
|
|
272
197
|
break;
|
|
273
198
|
default:
|
|
274
199
|
for (let v2 of v2s) {
|
|
@@ -308,11 +233,6 @@ class FilterService {
|
|
|
308
233
|
}
|
|
309
234
|
return result;
|
|
310
235
|
}
|
|
311
|
-
/**
|
|
312
|
-
* @private
|
|
313
|
-
* @param {?} value
|
|
314
|
-
* @return {?}
|
|
315
|
-
*/
|
|
316
236
|
getStringForValue(value) {
|
|
317
237
|
switch (value) {
|
|
318
238
|
case null:
|
|
@@ -323,20 +243,15 @@ class FilterService {
|
|
|
323
243
|
}
|
|
324
244
|
/**
|
|
325
245
|
* Gets the current values for an array of strings.
|
|
246
|
+
* @param paths The array of strings to check.
|
|
247
|
+
* @param currentQuestionnaireForm The current form data, can be null/undefined.
|
|
248
|
+
* @returns An array of strings/values
|
|
326
249
|
* @author Will Poulson
|
|
327
|
-
* @private
|
|
328
|
-
* @param {?} paths The array of strings to check.
|
|
329
|
-
* @param {?} currentQuestionnaireForm The current form data, can be null/undefined.
|
|
330
|
-
* @param {?=} additionalData
|
|
331
|
-
* @param {?=} repeaterItem
|
|
332
|
-
* @return {?} An array of strings/values
|
|
333
250
|
*/
|
|
334
251
|
getValuesForArray(paths, currentQuestionnaireForm, additionalData, repeaterItem) {
|
|
335
252
|
if (currentQuestionnaireForm) {
|
|
336
|
-
/** @type {?} */
|
|
337
253
|
const values = [];
|
|
338
254
|
for (const path of paths) {
|
|
339
|
-
/** @type {?} */
|
|
340
255
|
const value = this.getValueForString(path, currentQuestionnaireForm, additionalData, repeaterItem);
|
|
341
256
|
values.push(value);
|
|
342
257
|
}
|
|
@@ -348,25 +263,20 @@ class FilterService {
|
|
|
348
263
|
}
|
|
349
264
|
/**
|
|
350
265
|
* Gets a current value for a string.
|
|
266
|
+
* @param path The string value to check.
|
|
267
|
+
* @param currentQuestionnaireForm The current form data, can be null/undefined.
|
|
268
|
+
* @returns A string/value.
|
|
351
269
|
* @author Will Poulson
|
|
352
|
-
* @private
|
|
353
|
-
* @param {?} path The string value to check.
|
|
354
|
-
* @param {?} currentQuestionnaireForm The current form data, can be null/undefined.
|
|
355
|
-
* @param {?=} additionalData
|
|
356
|
-
* @param {?=} repeaterItem
|
|
357
|
-
* @return {?} A string/value.
|
|
358
270
|
*/
|
|
359
271
|
getValueForString(path, currentQuestionnaireForm, additionalData, repeaterItem) {
|
|
360
272
|
if (currentQuestionnaireForm) {
|
|
361
273
|
if (!additionalData) {
|
|
362
274
|
additionalData = {};
|
|
363
275
|
}
|
|
364
|
-
/** @type {?} */
|
|
365
276
|
let control = currentQuestionnaireForm.get(path.toString());
|
|
366
277
|
if (!control && repeaterItem) {
|
|
367
278
|
control = repeaterItem.get(path);
|
|
368
279
|
}
|
|
369
|
-
/** @type {?} */
|
|
370
280
|
const value = control ? control.value : this.convertStringToValue(path);
|
|
371
281
|
return get(additionalData, path, value);
|
|
372
282
|
}
|
|
@@ -377,10 +287,9 @@ class FilterService {
|
|
|
377
287
|
/**
|
|
378
288
|
* Converts a string to a value.
|
|
379
289
|
* Eg. true/false.
|
|
290
|
+
* @param path The string value to check for conversion;
|
|
291
|
+
* @returns Either a string or the converted value.
|
|
380
292
|
* @author Will Poulson
|
|
381
|
-
* @private
|
|
382
|
-
* @param {?} path The string value to check for conversion;
|
|
383
|
-
* @return {?} Either a string or the converted value.
|
|
384
293
|
*/
|
|
385
294
|
convertStringToValue(path) {
|
|
386
295
|
switch (path) {
|
|
@@ -395,38 +304,26 @@ class FilterService {
|
|
|
395
304
|
}
|
|
396
305
|
}
|
|
397
306
|
}
|
|
398
|
-
FilterService
|
|
399
|
-
|
|
307
|
+
FilterService.ɵfac = function FilterService_Factory(t) { return new (t || FilterService)(); };
|
|
308
|
+
FilterService.ɵprov = ɵɵdefineInjectable({ token: FilterService, factory: FilterService.ɵfac, providedIn: 'root' });
|
|
309
|
+
/*@__PURE__*/ (function () { ɵsetClassMetadata(FilterService, [{
|
|
310
|
+
type: Injectable,
|
|
311
|
+
args: [{
|
|
400
312
|
providedIn: 'root'
|
|
401
|
-
}
|
|
402
|
-
];
|
|
403
|
-
/** @nocollapse */
|
|
404
|
-
FilterService.ctorParameters = () => [];
|
|
405
|
-
/** @nocollapse */ FilterService.ngInjectableDef = ɵɵdefineInjectable({ factory: function FilterService_Factory() { return new FilterService(); }, token: FilterService, providedIn: "root" });
|
|
313
|
+
}]
|
|
314
|
+
}], function () { return []; }, null); })();
|
|
406
315
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
String: 'string',
|
|
417
|
-
Email: 'email',
|
|
418
|
-
Telephone: 'telephone',
|
|
419
|
-
};
|
|
316
|
+
var ValidationType;
|
|
317
|
+
(function (ValidationType) {
|
|
318
|
+
ValidationType["Required"] = "required";
|
|
319
|
+
ValidationType["Boolean"] = "boolean";
|
|
320
|
+
ValidationType["Number"] = "number";
|
|
321
|
+
ValidationType["String"] = "string";
|
|
322
|
+
ValidationType["Email"] = "email";
|
|
323
|
+
ValidationType["Telephone"] = "telephone";
|
|
324
|
+
})(ValidationType || (ValidationType = {}));
|
|
420
325
|
|
|
421
|
-
/**
|
|
422
|
-
* @fileoverview added by tsickle
|
|
423
|
-
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
424
|
-
*/
|
|
425
326
|
class FormConstructorService {
|
|
426
|
-
/**
|
|
427
|
-
* @param {?} fb
|
|
428
|
-
* @param {?} filterService
|
|
429
|
-
*/
|
|
430
327
|
constructor(fb, filterService) {
|
|
431
328
|
this.fb = fb;
|
|
432
329
|
this.filterService = filterService;
|
|
@@ -434,39 +331,24 @@ class FormConstructorService {
|
|
|
434
331
|
/**
|
|
435
332
|
* Constructs a form group based on the questionnaire data.
|
|
436
333
|
* This form group has been filtered down based on the conditions of the sections and questions.
|
|
334
|
+
* @param questionnaire The questionnaire data to build the form group on.
|
|
335
|
+
* @returns A filted form group.
|
|
437
336
|
* @author Will Poulson
|
|
438
|
-
* @param {?} questionnaire The questionnaire data to build the form group on.
|
|
439
|
-
* @param {?} currentQuestionnaire
|
|
440
|
-
* @param {?} currentQuestionnaireForm
|
|
441
|
-
* @param {?=} additionalData
|
|
442
|
-
* @param {?=} skipFilter
|
|
443
|
-
* @return {?} A filted form group.
|
|
444
337
|
*/
|
|
445
338
|
generateFormsForQuestionnaire(questionnaire, currentQuestionnaire, currentQuestionnaireForm, additionalData, skipFilter) {
|
|
446
|
-
/** @type {?} */
|
|
447
339
|
const sections = skipFilter ?
|
|
448
340
|
questionnaire.sections :
|
|
449
341
|
this.filterService.filterSections(questionnaire.sections, currentQuestionnaireForm, additionalData);
|
|
450
|
-
/** @type {?} */
|
|
451
342
|
const noChange = currentQuestionnaireForm && (sections === currentQuestionnaire.sections);
|
|
452
343
|
if (noChange && !skipFilter) {
|
|
453
344
|
return null;
|
|
454
345
|
}
|
|
455
|
-
/** @type {?} */
|
|
456
346
|
const questionnaireForms = this.generateFormsForSections(sections, currentQuestionnaireForm);
|
|
457
347
|
return { sections: sections, forms: questionnaireForms };
|
|
458
348
|
}
|
|
459
|
-
/**
|
|
460
|
-
* @private
|
|
461
|
-
* @param {?} sections
|
|
462
|
-
* @param {?} currentQuestionnaireForm
|
|
463
|
-
* @return {?}
|
|
464
|
-
*/
|
|
465
349
|
generateFormsForSections(sections, currentQuestionnaireForm) {
|
|
466
|
-
/** @type {?} */
|
|
467
350
|
const questionnaireForms = this.fb.group({});
|
|
468
351
|
for (const section of sections) {
|
|
469
|
-
/** @type {?} */
|
|
470
352
|
const sectionForms = this.generateFormsForSection(section, currentQuestionnaireForm);
|
|
471
353
|
questionnaireForms.addControl(section.name, sectionForms);
|
|
472
354
|
}
|
|
@@ -475,20 +357,16 @@ class FormConstructorService {
|
|
|
475
357
|
/**
|
|
476
358
|
* Constructs a form group based on the section data.
|
|
477
359
|
* This form group has been filtered down based on the conditions of the questions.
|
|
360
|
+
* @param section The section data to build the form group on.
|
|
361
|
+
* @returns A filtered form group.
|
|
478
362
|
* @author Will Poulson
|
|
479
|
-
* @private
|
|
480
|
-
* @param {?} section The section data to build the form group on.
|
|
481
|
-
* @param {?} currentQuestionnaireForm
|
|
482
|
-
* @return {?} A filtered form group.
|
|
483
363
|
*/
|
|
484
364
|
generateFormsForSection(section, currentQuestionnaireForm) {
|
|
485
|
-
/** @type {?} */
|
|
486
365
|
const sectionForms = this.fb.group({});
|
|
487
366
|
for (const question of section.questions) {
|
|
488
367
|
if (question.type === QuestionType.Info) {
|
|
489
368
|
continue;
|
|
490
369
|
}
|
|
491
|
-
/** @type {?} */
|
|
492
370
|
const questionControl = this.generateControlForQuestion(question, section, currentQuestionnaireForm);
|
|
493
371
|
sectionForms.addControl(question.name, questionControl);
|
|
494
372
|
}
|
|
@@ -496,62 +374,40 @@ class FormConstructorService {
|
|
|
496
374
|
}
|
|
497
375
|
/**
|
|
498
376
|
* Constructs an astract form control based on the question data.
|
|
377
|
+
* @param question The question data to build the abstract control on.
|
|
378
|
+
* @returns An abstract control.
|
|
499
379
|
* @author Will Poulson
|
|
500
|
-
* @private
|
|
501
|
-
* @param {?} question The question data to build the abstract control on.
|
|
502
|
-
* @param {?} section
|
|
503
|
-
* @param {?} currentQuestionnaireForm
|
|
504
|
-
* @return {?} An abstract control.
|
|
505
380
|
*/
|
|
506
381
|
generateControlForQuestion(question, section, currentQuestionnaireForm) {
|
|
507
|
-
/** @type {?} */
|
|
508
382
|
const convertedValidators = this.convertValidators(question.validators);
|
|
509
|
-
/** @type {?} */
|
|
510
383
|
const defaultValue = question.defaultValue ? question.defaultValue : null;
|
|
511
384
|
switch (question.type) {
|
|
512
385
|
case QuestionType.Repeater:
|
|
513
|
-
/** @type {?} */
|
|
514
386
|
const newArray = this.fb.array([], convertedValidators);
|
|
515
|
-
|
|
516
|
-
const currentArray = currentQuestionnaireForm ? ((/** @type {?} */ (currentQuestionnaireForm.get([section.name, question.name])))) : false;
|
|
387
|
+
const currentArray = currentQuestionnaireForm ? currentQuestionnaireForm.get([section.name, question.name]) : false;
|
|
517
388
|
if (currentArray && question.filteredRepeaterQuestions) {
|
|
518
389
|
for (const control of currentArray.controls) {
|
|
519
|
-
/** @type {?} */
|
|
520
390
|
const index = currentArray.controls.indexOf(control);
|
|
521
391
|
if (index === -1) {
|
|
522
392
|
continue;
|
|
523
393
|
}
|
|
524
|
-
/** @type {?} */
|
|
525
394
|
const filteredQuestions = question.filteredRepeaterQuestions[index];
|
|
526
395
|
if (!filteredQuestions) {
|
|
527
396
|
continue;
|
|
528
397
|
}
|
|
529
|
-
|
|
530
|
-
const
|
|
531
|
-
* @param {?} x
|
|
532
|
-
* @return {?}
|
|
533
|
-
*/
|
|
534
|
-
x => x.name));
|
|
535
|
-
/** @type {?} */
|
|
536
|
-
const filteredOutQuestions = question.repeaterQuestions.filter((/**
|
|
537
|
-
* @param {?} x
|
|
538
|
-
* @return {?}
|
|
539
|
-
*/
|
|
540
|
-
x => !filteredQuestionNames.includes(x.name)));
|
|
398
|
+
const filteredQuestionNames = filteredQuestions.map(x => x.name);
|
|
399
|
+
const filteredOutQuestions = question.repeaterQuestions.filter(x => !filteredQuestionNames.includes(x.name));
|
|
541
400
|
for (const filteredOutQuestion of filteredOutQuestions) {
|
|
542
|
-
/** @type {?} */
|
|
543
401
|
const childControl = control.get(filteredOutQuestion.name);
|
|
544
402
|
childControl.setValidators([]);
|
|
545
403
|
childControl.updateValueAndValidity({ onlySelf: true, emitEvent: false });
|
|
546
404
|
}
|
|
547
405
|
for (const filteredQuestion of filteredQuestions) {
|
|
548
|
-
/** @type {?} */
|
|
549
406
|
const childControl = control.get(filteredQuestion.name);
|
|
550
407
|
if (childControl.value) {
|
|
551
408
|
// If there's a value just skip it, no need to redo the validators each time.
|
|
552
409
|
continue;
|
|
553
410
|
}
|
|
554
|
-
/** @type {?} */
|
|
555
411
|
const convertedValidators = this.convertValidators(filteredQuestion.validators);
|
|
556
412
|
childControl.setValidators(convertedValidators);
|
|
557
413
|
childControl.updateValueAndValidity({ onlySelf: true, emitEvent: false });
|
|
@@ -569,20 +425,16 @@ class FormConstructorService {
|
|
|
569
425
|
}
|
|
570
426
|
/**
|
|
571
427
|
* Generates the form group for a checklist question.
|
|
428
|
+
* @param question The question. Must be of type checklist or else null is returned.
|
|
429
|
+
* @returns A form group.
|
|
572
430
|
* @author Will Poulson
|
|
573
|
-
* @private
|
|
574
|
-
* @param {?} question The question. Must be of type checklist or else null is returned.
|
|
575
|
-
* @param {?} convertedValidators
|
|
576
|
-
* @return {?} A form group.
|
|
577
431
|
*/
|
|
578
432
|
generateGroupForChecklist(question, convertedValidators) {
|
|
579
433
|
if (question.type !== QuestionType.Checklist || question.checklistItems.length === 0) {
|
|
580
434
|
return null;
|
|
581
435
|
}
|
|
582
|
-
/** @type {?} */
|
|
583
436
|
const checklistForms = this.fb.group({});
|
|
584
437
|
for (const checklistItem of question.checklistItems) {
|
|
585
|
-
/** @type {?} */
|
|
586
438
|
const checklistItemControl = this.fb.control(null, convertedValidators);
|
|
587
439
|
checklistForms.addControl(checklistItem.name, checklistItemControl);
|
|
588
440
|
}
|
|
@@ -590,20 +442,17 @@ class FormConstructorService {
|
|
|
590
442
|
}
|
|
591
443
|
/**
|
|
592
444
|
* Generates the form template for a repeater question.
|
|
445
|
+
* @param question The question. Must be of type repeater or else null is returned.
|
|
446
|
+
* @returns A form group.
|
|
593
447
|
* @author Will Poulson
|
|
594
|
-
* @param {?} question The question. Must be of type repeater or else null is returned.
|
|
595
|
-
* @param {?=} index
|
|
596
|
-
* @return {?} A form group.
|
|
597
448
|
*/
|
|
598
449
|
generateFormsForRepeater(question, index) {
|
|
599
450
|
if (question.type !== QuestionType.Repeater || question.repeaterQuestions.length === 0) {
|
|
600
451
|
console.log('Question isnt a repeater or has no questions, returning null');
|
|
601
452
|
return null;
|
|
602
453
|
}
|
|
603
|
-
/** @type {?} */
|
|
604
454
|
const repeaterForms = this.fb.group({});
|
|
605
455
|
for (const repeaterQuestion of question.repeaterQuestions) {
|
|
606
|
-
/** @type {?} */
|
|
607
456
|
const repeaterQuestionControl = this.generateControlForRepeaterQuestion(repeaterQuestion);
|
|
608
457
|
repeaterForms.addControl(repeaterQuestion.name, repeaterQuestionControl);
|
|
609
458
|
}
|
|
@@ -611,31 +460,26 @@ class FormConstructorService {
|
|
|
611
460
|
}
|
|
612
461
|
/**
|
|
613
462
|
* Generates a control for a repeaters question.
|
|
463
|
+
* @param repeaterQuestion A repeater question.
|
|
464
|
+
* @returns An abstract control.
|
|
614
465
|
* @author Will Poulson
|
|
615
|
-
* @private
|
|
616
|
-
* @param {?} repeaterQuestion A repeater question.
|
|
617
|
-
* @return {?} An abstract control.
|
|
618
466
|
*/
|
|
619
467
|
generateControlForRepeaterQuestion(repeaterQuestion) {
|
|
620
|
-
/** @type {?} */
|
|
621
468
|
const convertedValidators = this.convertValidators(repeaterQuestion.validators);
|
|
622
469
|
return this.fb.control(null, { validators: convertedValidators, updateOn: repeaterQuestion.type === 'select' ? 'change' : 'blur' });
|
|
623
470
|
}
|
|
624
471
|
/**
|
|
625
472
|
* Converts an array of validators into form validators.
|
|
473
|
+
* @param validators The uncoverted array of validators.
|
|
474
|
+
* @returns A convered array of form validators.
|
|
626
475
|
* @author Will Poulson
|
|
627
|
-
* @private
|
|
628
|
-
* @param {?} validators The uncoverted array of validators.
|
|
629
|
-
* @return {?} A convered array of form validators.
|
|
630
476
|
*/
|
|
631
477
|
convertValidators(validators) {
|
|
632
478
|
if (!validators || validators.length === 0) {
|
|
633
479
|
return [];
|
|
634
480
|
}
|
|
635
|
-
/** @type {?} */
|
|
636
481
|
const convertedValidators = [];
|
|
637
482
|
for (const validator of validators) {
|
|
638
|
-
/** @type {?} */
|
|
639
483
|
const convertedValidator = this.convertValidator(validator);
|
|
640
484
|
if (convertedValidator) {
|
|
641
485
|
convertedValidators.push(convertedValidator);
|
|
@@ -645,10 +489,9 @@ class FormConstructorService {
|
|
|
645
489
|
}
|
|
646
490
|
/**
|
|
647
491
|
* Converts a single validator into a form validator.
|
|
492
|
+
* @param validator The unconverted validator.
|
|
493
|
+
* @returns A converted form validator.
|
|
648
494
|
* @author Will Poulson
|
|
649
|
-
* @private
|
|
650
|
-
* @param {?} validator The unconverted validator.
|
|
651
|
-
* @return {?} A converted form validator.
|
|
652
495
|
*/
|
|
653
496
|
convertValidator(validator) {
|
|
654
497
|
switch (validator.type) {
|
|
@@ -660,10 +503,8 @@ class FormConstructorService {
|
|
|
660
503
|
}
|
|
661
504
|
/**
|
|
662
505
|
* Constructs the forms for repeaters from saved state.
|
|
663
|
-
* @param
|
|
664
|
-
* @param
|
|
665
|
-
* @param {?} currentQuestionnaireForm
|
|
666
|
-
* @return {?}
|
|
506
|
+
* @param savedState The saved state to load.
|
|
507
|
+
* @param sections The sections already generated by the form constructor.
|
|
667
508
|
*/
|
|
668
509
|
constructRepeaterFromsFromState(savedState, sections, currentQuestionnaireForm) {
|
|
669
510
|
for (const section of sections) {
|
|
@@ -671,21 +512,17 @@ class FormConstructorService {
|
|
|
671
512
|
if (question.type !== QuestionType.Repeater) {
|
|
672
513
|
continue;
|
|
673
514
|
}
|
|
674
|
-
/** @type {?} */
|
|
675
515
|
const repeaterArray = savedState[section.name][question.name];
|
|
676
516
|
if (!repeaterArray || repeaterArray.length === 0) {
|
|
677
517
|
continue;
|
|
678
518
|
}
|
|
679
|
-
|
|
680
|
-
const repeaterFormArray = (/** @type {?} */ (currentQuestionnaireForm.get([section.name, question.name])));
|
|
519
|
+
const repeaterFormArray = currentQuestionnaireForm.get([section.name, question.name]);
|
|
681
520
|
if (repeaterFormArray.controls.length === repeaterArray.length) {
|
|
682
521
|
continue;
|
|
683
522
|
}
|
|
684
523
|
// For each item that used to be there push a new empty template there to be populated.
|
|
685
524
|
for (const repeaterItem of repeaterArray) {
|
|
686
|
-
/** @type {?} */
|
|
687
525
|
const index = repeaterArray.indexOf(repeaterItem);
|
|
688
|
-
/** @type {?} */
|
|
689
526
|
const repeaterItemTemplate = this.generateFormsForRepeater(question, index);
|
|
690
527
|
repeaterFormArray.push(repeaterItemTemplate);
|
|
691
528
|
}
|
|
@@ -693,39 +530,16 @@ class FormConstructorService {
|
|
|
693
530
|
}
|
|
694
531
|
}
|
|
695
532
|
}
|
|
696
|
-
FormConstructorService
|
|
697
|
-
|
|
533
|
+
FormConstructorService.ɵfac = function FormConstructorService_Factory(t) { return new (t || FormConstructorService)(ɵɵinject(FormBuilder), ɵɵinject(FilterService)); };
|
|
534
|
+
FormConstructorService.ɵprov = ɵɵdefineInjectable({ token: FormConstructorService, factory: FormConstructorService.ɵfac, providedIn: 'root' });
|
|
535
|
+
/*@__PURE__*/ (function () { ɵsetClassMetadata(FormConstructorService, [{
|
|
536
|
+
type: Injectable,
|
|
537
|
+
args: [{
|
|
698
538
|
providedIn: 'root'
|
|
699
|
-
}
|
|
700
|
-
];
|
|
701
|
-
/** @nocollapse */
|
|
702
|
-
FormConstructorService.ctorParameters = () => [
|
|
703
|
-
{ type: FormBuilder },
|
|
704
|
-
{ type: FilterService }
|
|
705
|
-
];
|
|
706
|
-
/** @nocollapse */ FormConstructorService.ngInjectableDef = ɵɵdefineInjectable({ factory: function FormConstructorService_Factory() { return new FormConstructorService(ɵɵinject(FormBuilder), ɵɵinject(FilterService)); }, token: FormConstructorService, providedIn: "root" });
|
|
707
|
-
if (false) {
|
|
708
|
-
/**
|
|
709
|
-
* @type {?}
|
|
710
|
-
* @private
|
|
711
|
-
*/
|
|
712
|
-
FormConstructorService.prototype.fb;
|
|
713
|
-
/**
|
|
714
|
-
* @type {?}
|
|
715
|
-
* @private
|
|
716
|
-
*/
|
|
717
|
-
FormConstructorService.prototype.filterService;
|
|
718
|
-
}
|
|
539
|
+
}]
|
|
540
|
+
}], function () { return [{ type: FormBuilder }, { type: FilterService }]; }, null); })();
|
|
719
541
|
|
|
720
|
-
/**
|
|
721
|
-
* @fileoverview added by tsickle
|
|
722
|
-
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
723
|
-
*/
|
|
724
542
|
class QuestionnaireService {
|
|
725
|
-
/**
|
|
726
|
-
* @param {?} formConstuctor
|
|
727
|
-
* @param {?} options
|
|
728
|
-
*/
|
|
729
543
|
constructor(formConstuctor, options) {
|
|
730
544
|
this.formConstuctor = formConstuctor;
|
|
731
545
|
this.options = options;
|
|
@@ -735,18 +549,16 @@ class QuestionnaireService {
|
|
|
735
549
|
}
|
|
736
550
|
/**
|
|
737
551
|
* Loads a questionnaire from data.
|
|
552
|
+
* @param questionnaire The questionnaire data to load, often parsed JSON from the editor.
|
|
553
|
+
* @param savedState The saved state of the questionnaire, often from localstorage.
|
|
554
|
+
* @returns null
|
|
738
555
|
* @author Will Poulson
|
|
739
|
-
* @param {?} questionnaire The questionnaire data to load, often parsed JSON from the editor.
|
|
740
|
-
* @param {?=} savedState The saved state of the questionnaire, often from localstorage.
|
|
741
|
-
* @param {?=} additionalData
|
|
742
|
-
* @return {?} null
|
|
743
556
|
*/
|
|
744
557
|
loadQuestionnaire(questionnaire, savedState, additionalData) {
|
|
745
558
|
this.originalQuestionnaire = cloneDeep(questionnaire);
|
|
746
559
|
this.currentQuestionnaire = cloneDeep(questionnaire);
|
|
747
560
|
this.additionalData = additionalData;
|
|
748
561
|
if (savedState && Object.keys(savedState).length > 0) {
|
|
749
|
-
/** @type {?} */
|
|
750
562
|
const newData = this.formConstuctor.generateFormsForQuestionnaire(cloneDeep(this.originalQuestionnaire), cloneDeep(this.currentQuestionnaire), this.currentQuestionnaireForm, this.additionalData, true);
|
|
751
563
|
if (newData) {
|
|
752
564
|
this.formConstuctor.constructRepeaterFromsFromState(savedState, newData.sections, newData.forms);
|
|
@@ -764,23 +576,12 @@ class QuestionnaireService {
|
|
|
764
576
|
}
|
|
765
577
|
/**
|
|
766
578
|
* Updates the current questionnaire, used when a value is updated to check conditions.
|
|
579
|
+
* @param savedState The saved state of the questionnaire, often from localstorage.
|
|
580
|
+
* @returns null
|
|
767
581
|
* @author Will Poulson
|
|
768
|
-
* @param {?=} savedState The saved state of the questionnaire, often from localstorage.
|
|
769
|
-
* @return {?} null
|
|
770
582
|
*/
|
|
771
583
|
updateQuestionnaire(savedState) {
|
|
772
|
-
|
|
773
|
-
const oldLength = this.currentQuestionnaire.sections.map((/**
|
|
774
|
-
* @param {?} x
|
|
775
|
-
* @return {?}
|
|
776
|
-
*/
|
|
777
|
-
x => x.questions.length)).reduce((/**
|
|
778
|
-
* @param {?} a
|
|
779
|
-
* @param {?} b
|
|
780
|
-
* @return {?}
|
|
781
|
-
*/
|
|
782
|
-
(a, b) => a + b), 0);
|
|
783
|
-
/** @type {?} */
|
|
584
|
+
const oldLength = this.currentQuestionnaire.sections.map(x => x.questions.length).reduce((a, b) => a + b, 0);
|
|
784
585
|
const newData = this.formConstuctor.generateFormsForQuestionnaire(cloneDeep(this.originalQuestionnaire), cloneDeep(this.currentQuestionnaire), this.currentQuestionnaireForm, this.additionalData);
|
|
785
586
|
if (newData) {
|
|
786
587
|
this.currentQuestionnaireForm = newData.forms;
|
|
@@ -795,36 +596,19 @@ class QuestionnaireService {
|
|
|
795
596
|
if (this.questionValueChangeSubscription) {
|
|
796
597
|
this.questionValueChangeSubscription.unsubscribe();
|
|
797
598
|
}
|
|
798
|
-
this.questionnaireValueChangeSubscription = this.currentQuestionnaireForm.valueChanges.subscribe((
|
|
799
|
-
* @return {?}
|
|
800
|
-
*/
|
|
801
|
-
() => {
|
|
599
|
+
this.questionnaireValueChangeSubscription = this.currentQuestionnaireForm.valueChanges.subscribe(() => {
|
|
802
600
|
this.dataChangedEvent.emit();
|
|
803
601
|
this.updateQuestionnaire(this.currentQuestionnaireForm.getRawValue());
|
|
804
|
-
})
|
|
602
|
+
});
|
|
805
603
|
if (this.currentQuestion && this.currentQuestion.formControl) {
|
|
806
|
-
this.questionValueChangeSubscription = this.currentQuestion.formControl.valueChanges.subscribe((
|
|
807
|
-
* @return {?}
|
|
808
|
-
*/
|
|
809
|
-
() => {
|
|
604
|
+
this.questionValueChangeSubscription = this.currentQuestion.formControl.valueChanges.subscribe(() => {
|
|
810
605
|
this.clearFields(this.currentQuestion.data.clearfields);
|
|
811
|
-
})
|
|
606
|
+
});
|
|
812
607
|
}
|
|
813
|
-
|
|
814
|
-
const newLength = this.currentQuestionnaire.sections.map((/**
|
|
815
|
-
* @param {?} x
|
|
816
|
-
* @return {?}
|
|
817
|
-
*/
|
|
818
|
-
x => x.questions.length)).reduce((/**
|
|
819
|
-
* @param {?} a
|
|
820
|
-
* @param {?} b
|
|
821
|
-
* @return {?}
|
|
822
|
-
*/
|
|
823
|
-
(a, b) => a + b), 0);
|
|
608
|
+
const newLength = this.currentQuestionnaire.sections.map(x => x.questions.length).reduce((a, b) => a + b, 0);
|
|
824
609
|
if (oldLength !== newLength) {
|
|
825
610
|
for (const section of this.currentQuestionnaire.sections) {
|
|
826
611
|
for (const question of section.questions) {
|
|
827
|
-
/** @type {?} */
|
|
828
612
|
const control = this.currentQuestionnaireForm.get([section.name, question.name]);
|
|
829
613
|
if (control && control.value === null && question.defaultValue) {
|
|
830
614
|
control.setValue(question.defaultValue);
|
|
@@ -833,95 +617,60 @@ class QuestionnaireService {
|
|
|
833
617
|
}
|
|
834
618
|
}
|
|
835
619
|
}
|
|
836
|
-
/**
|
|
837
|
-
* @param {?} payload
|
|
838
|
-
* @return {?}
|
|
839
|
-
*/
|
|
840
620
|
updateAdditionalData(payload) {
|
|
841
621
|
this.additionalData = Object.assign(this.additionalData, payload);
|
|
842
622
|
this.updateQuestionnaire(this.currentQuestionnaireForm.getRawValue());
|
|
843
623
|
}
|
|
844
|
-
/**
|
|
845
|
-
* @return {?}
|
|
846
|
-
*/
|
|
847
624
|
clearAdditionalData() {
|
|
848
625
|
this.additionalData = {};
|
|
849
626
|
this.updateQuestionnaire(this.currentQuestionnaireForm.getRawValue());
|
|
850
627
|
}
|
|
851
|
-
/**
|
|
852
|
-
* @return {?}
|
|
853
|
-
*/
|
|
854
628
|
get isValid() {
|
|
855
629
|
return this.currentQuestionnaireForm.valid;
|
|
856
630
|
}
|
|
857
|
-
/**
|
|
858
|
-
* @return {?}
|
|
859
|
-
*/
|
|
860
631
|
get isFirstQuestion() {
|
|
861
632
|
if (!this.currentSection || !this.currentQuestion) {
|
|
862
633
|
return false;
|
|
863
634
|
}
|
|
864
|
-
/** @type {?} */
|
|
865
635
|
const currentIndex = this.currentSection.data.questions.indexOf(this.currentQuestion.data);
|
|
866
636
|
return currentIndex === 0;
|
|
867
637
|
}
|
|
868
|
-
/**
|
|
869
|
-
* @return {?}
|
|
870
|
-
*/
|
|
871
638
|
get isLastQuestion() {
|
|
872
639
|
if (!this.currentSection || !this.currentQuestion) {
|
|
873
640
|
return false;
|
|
874
641
|
}
|
|
875
|
-
/** @type {?} */
|
|
876
642
|
const currentIndex = this.currentSection.data.questions.indexOf(this.currentQuestion.data);
|
|
877
|
-
/** @type {?} */
|
|
878
643
|
const maxIndex = this.currentSection.data.questions.length - 1;
|
|
879
644
|
return currentIndex === maxIndex;
|
|
880
645
|
}
|
|
881
|
-
/**
|
|
882
|
-
* @return {?}
|
|
883
|
-
*/
|
|
884
646
|
get isFirstSection() {
|
|
885
647
|
if (!this.currentSection) {
|
|
886
648
|
return false;
|
|
887
649
|
}
|
|
888
|
-
/** @type {?} */
|
|
889
650
|
const currentIndex = this.currentQuestionnaire.sections.indexOf(this.currentSection.data);
|
|
890
651
|
return currentIndex === 0;
|
|
891
652
|
}
|
|
892
|
-
/**
|
|
893
|
-
* @return {?}
|
|
894
|
-
*/
|
|
895
653
|
get isLastSection() {
|
|
896
654
|
if (!this.currentSection) {
|
|
897
655
|
return false;
|
|
898
656
|
}
|
|
899
|
-
/** @type {?} */
|
|
900
657
|
const currentIndex = this.currentQuestionnaire.sections.indexOf(this.currentSection.data);
|
|
901
|
-
/** @type {?} */
|
|
902
658
|
const maxIndex = this.currentQuestionnaire.sections.length - 1;
|
|
903
659
|
return currentIndex === maxIndex;
|
|
904
660
|
}
|
|
905
|
-
/**
|
|
906
|
-
* @param {?} name
|
|
907
|
-
* @return {?}
|
|
908
|
-
*/
|
|
909
661
|
sectionValid(name) {
|
|
910
662
|
return this.currentQuestionnaireForm.get(name).valid;
|
|
911
663
|
}
|
|
912
664
|
/**
|
|
913
665
|
* Clears all the fields parsed
|
|
666
|
+
* @param clearfields An array of strings, paths to clear.
|
|
914
667
|
* @author Will Poulson
|
|
915
|
-
* @private
|
|
916
|
-
* @param {?} clearfields An array of strings, paths to clear.
|
|
917
|
-
* @return {?}
|
|
918
668
|
*/
|
|
919
669
|
clearFields(clearfields) {
|
|
920
670
|
if (!clearfields || clearfields.length === 0) {
|
|
921
671
|
return;
|
|
922
672
|
}
|
|
923
673
|
for (const clearfield of clearfields) {
|
|
924
|
-
/** @type {?} */
|
|
925
674
|
const control = this.currentQuestionnaireForm.get(clearfield);
|
|
926
675
|
if (control) {
|
|
927
676
|
control.reset(undefined);
|
|
@@ -932,7 +681,6 @@ class QuestionnaireService {
|
|
|
932
681
|
* Unloads the current questionnaire.
|
|
933
682
|
* Useful when exiting a questionnaire page or completing a questionnaire.
|
|
934
683
|
* @author Will Poulson
|
|
935
|
-
* @return {?}
|
|
936
684
|
*/
|
|
937
685
|
unloadQuestionnaire() {
|
|
938
686
|
this.originalQuestionnaire = undefined;
|
|
@@ -944,33 +692,28 @@ class QuestionnaireService {
|
|
|
944
692
|
}
|
|
945
693
|
/**
|
|
946
694
|
* Gets the current selected section.
|
|
695
|
+
* @returns An object containing the section data and the related form group.
|
|
947
696
|
* @author Will Poulson
|
|
948
|
-
* @return {?} An object containing the section data and the related form group.
|
|
949
697
|
*/
|
|
950
698
|
get currentSection() {
|
|
951
699
|
if (!this.currentSectionName) {
|
|
952
700
|
return null;
|
|
953
701
|
}
|
|
954
|
-
|
|
955
|
-
const data = this.currentQuestionnaire.sections.find((/**
|
|
956
|
-
* @param {?} x
|
|
957
|
-
* @return {?}
|
|
958
|
-
*/
|
|
959
|
-
(x) => {
|
|
702
|
+
const data = this.currentQuestionnaire.sections.find((x) => {
|
|
960
703
|
return x.name === this.currentSectionName;
|
|
961
|
-
})
|
|
704
|
+
});
|
|
962
705
|
if (!data) {
|
|
963
706
|
return null;
|
|
964
707
|
}
|
|
965
708
|
return {
|
|
966
709
|
data: data,
|
|
967
|
-
formGroup:
|
|
710
|
+
formGroup: this.currentQuestionnaireForm.get(data.name)
|
|
968
711
|
};
|
|
969
712
|
}
|
|
970
713
|
/**
|
|
971
714
|
* Gets all the avaialble sections.
|
|
715
|
+
* @returns An array of all avaialble sections.
|
|
972
716
|
* @author Will Poulson
|
|
973
|
-
* @return {?} An array of all avaialble sections.
|
|
974
717
|
*/
|
|
975
718
|
get availableSections() {
|
|
976
719
|
if (!this.currentQuestionnaire || !this.currentQuestionnaire.sections) {
|
|
@@ -980,34 +723,28 @@ class QuestionnaireService {
|
|
|
980
723
|
}
|
|
981
724
|
/**
|
|
982
725
|
* Gets the current data for the entire questionnaire.
|
|
726
|
+
* @returns An object of data.
|
|
983
727
|
* @author Will Poulson
|
|
984
|
-
* @return {?} An object of data.
|
|
985
728
|
*/
|
|
986
729
|
get currentData() {
|
|
987
730
|
return this.currentQuestionnaireForm ? this.currentQuestionnaireForm.getRawValue() : {};
|
|
988
731
|
}
|
|
989
732
|
/**
|
|
990
733
|
* Gets the current selected question.
|
|
734
|
+
* @returns An object containing the question data and the related form control.
|
|
991
735
|
* @author Will Poulson
|
|
992
|
-
* @return {?} An object containing the question data and the related form control.
|
|
993
736
|
*/
|
|
994
737
|
get currentQuestion() {
|
|
995
738
|
if (!this.currentQuestionName) {
|
|
996
739
|
return null;
|
|
997
740
|
}
|
|
998
|
-
|
|
999
|
-
const data = this.currentSection.data.questions.find((/**
|
|
1000
|
-
* @param {?} x
|
|
1001
|
-
* @return {?}
|
|
1002
|
-
*/
|
|
1003
|
-
(x) => {
|
|
741
|
+
const data = this.currentSection.data.questions.find((x) => {
|
|
1004
742
|
return x.name === this.currentQuestionName;
|
|
1005
|
-
})
|
|
743
|
+
});
|
|
1006
744
|
if (!data) {
|
|
1007
745
|
return null;
|
|
1008
746
|
}
|
|
1009
|
-
|
|
1010
|
-
const formControl = (/** @type {?} */ (this.currentSection.formGroup.get(data.name)));
|
|
747
|
+
const formControl = this.currentSection.formGroup.get(data.name);
|
|
1011
748
|
return {
|
|
1012
749
|
data: data,
|
|
1013
750
|
formControl: formControl
|
|
@@ -1018,270 +755,158 @@ class QuestionnaireService {
|
|
|
1018
755
|
* If there is no question to navigate to it will reject with a out of bounds exception.
|
|
1019
756
|
* If allowSkipRequiredField is false then it will reject if the current question is invalid.
|
|
1020
757
|
* If emitSectionFinishEvent is true then it will emit an event if it's navigating past the length of questions.
|
|
758
|
+
* @returns A promise which will resolve when the question has been navigated to.
|
|
1021
759
|
* @author Will Poulson
|
|
1022
|
-
* @return {?} A promise which will resolve when the question has been navigated to.
|
|
1023
760
|
*/
|
|
1024
761
|
nextQuestion() {
|
|
1025
|
-
return new Promise((
|
|
1026
|
-
* @param {?} resolve
|
|
1027
|
-
* @param {?} reject
|
|
1028
|
-
* @return {?}
|
|
1029
|
-
*/
|
|
1030
|
-
(resolve, reject) => {
|
|
762
|
+
return new Promise((resolve, reject) => {
|
|
1031
763
|
if (!this.options.allowSkipRequiredField) {
|
|
1032
764
|
if (this.currentQuestion.formControl && !this.currentQuestion.formControl.valid) {
|
|
1033
765
|
return reject('Current question is invalid');
|
|
1034
766
|
}
|
|
1035
767
|
}
|
|
1036
|
-
this.getCurrentQuestionIndex().then((
|
|
1037
|
-
* @param {?} currentIndex
|
|
1038
|
-
* @return {?}
|
|
1039
|
-
*/
|
|
1040
|
-
(currentIndex) => {
|
|
1041
|
-
/** @type {?} */
|
|
768
|
+
this.getCurrentQuestionIndex().then((currentIndex) => {
|
|
1042
769
|
const lastQuestionIndex = this.currentSection.data.questions.length - 1;
|
|
1043
|
-
/** @type {?} */
|
|
1044
770
|
const isLastQuestion = lastQuestionIndex === currentIndex;
|
|
1045
771
|
if (isLastQuestion) {
|
|
1046
772
|
this.sectionFinishedEvent.emit();
|
|
1047
773
|
return resolve();
|
|
1048
774
|
}
|
|
1049
|
-
/** @type {?} */
|
|
1050
775
|
const newIndex = currentIndex + 1;
|
|
1051
|
-
this.navigateToQuestion(newIndex).then((
|
|
1052
|
-
* @return {?}
|
|
1053
|
-
*/
|
|
1054
|
-
() => {
|
|
776
|
+
this.navigateToQuestion(newIndex).then(() => {
|
|
1055
777
|
return resolve();
|
|
1056
|
-
})
|
|
1057
|
-
* @param {?} error
|
|
1058
|
-
* @return {?}
|
|
1059
|
-
*/
|
|
1060
|
-
(error) => {
|
|
778
|
+
}).catch((error) => {
|
|
1061
779
|
return reject(error);
|
|
1062
|
-
})
|
|
1063
|
-
})
|
|
1064
|
-
* @param {?} error
|
|
1065
|
-
* @return {?}
|
|
1066
|
-
*/
|
|
1067
|
-
(error) => {
|
|
780
|
+
});
|
|
781
|
+
}).catch((error) => {
|
|
1068
782
|
return reject(error);
|
|
1069
|
-
})
|
|
1070
|
-
})
|
|
783
|
+
});
|
|
784
|
+
});
|
|
1071
785
|
}
|
|
1072
786
|
/**
|
|
1073
787
|
* Navigates to the previous question.
|
|
1074
788
|
* If there is no question to navigate to it will reject with a out of bounds exception.
|
|
1075
789
|
* If allowNavigateBackwards is false then it will reject.
|
|
790
|
+
* @returns A promise which will resolve when the question has been navigated to.
|
|
1076
791
|
* @author Will Poulson
|
|
1077
|
-
* @return {?} A promise which will resolve when the question has been navigated to.
|
|
1078
792
|
*/
|
|
1079
793
|
prevQuestion() {
|
|
1080
|
-
return new Promise((
|
|
1081
|
-
* @param {?} resolve
|
|
1082
|
-
* @param {?} reject
|
|
1083
|
-
* @return {?}
|
|
1084
|
-
*/
|
|
1085
|
-
(resolve, reject) => {
|
|
794
|
+
return new Promise((resolve, reject) => {
|
|
1086
795
|
if (!this.options.allowNavigateBackwards) {
|
|
1087
796
|
return reject('This questionnaire does not allow for backwards navigation');
|
|
1088
797
|
}
|
|
1089
|
-
this.getCurrentQuestionIndex().then((
|
|
1090
|
-
* @param {?} currentIndex
|
|
1091
|
-
* @return {?}
|
|
1092
|
-
*/
|
|
1093
|
-
(currentIndex) => {
|
|
1094
|
-
/** @type {?} */
|
|
798
|
+
this.getCurrentQuestionIndex().then((currentIndex) => {
|
|
1095
799
|
const newIndex = currentIndex - 1;
|
|
1096
|
-
this.navigateToQuestion(newIndex).then((
|
|
1097
|
-
* @return {?}
|
|
1098
|
-
*/
|
|
1099
|
-
() => {
|
|
800
|
+
this.navigateToQuestion(newIndex).then(() => {
|
|
1100
801
|
return resolve();
|
|
1101
|
-
})
|
|
1102
|
-
* @param {?} error
|
|
1103
|
-
* @return {?}
|
|
1104
|
-
*/
|
|
1105
|
-
(error) => {
|
|
802
|
+
}).catch((error) => {
|
|
1106
803
|
return reject(error);
|
|
1107
|
-
})
|
|
1108
|
-
})
|
|
1109
|
-
* @param {?} error
|
|
1110
|
-
* @return {?}
|
|
1111
|
-
*/
|
|
1112
|
-
(error) => {
|
|
804
|
+
});
|
|
805
|
+
}).catch((error) => {
|
|
1113
806
|
return reject(error);
|
|
1114
|
-
})
|
|
1115
|
-
})
|
|
807
|
+
});
|
|
808
|
+
});
|
|
1116
809
|
}
|
|
1117
810
|
/**
|
|
1118
811
|
* Gets the current questions index.
|
|
812
|
+
* @returns A promise which resolves a number.
|
|
1119
813
|
* @author Will Poulson
|
|
1120
|
-
* @private
|
|
1121
|
-
* @return {?} A promise which resolves a number.
|
|
1122
814
|
*/
|
|
1123
815
|
getCurrentQuestionIndex() {
|
|
1124
|
-
return new Promise((
|
|
1125
|
-
* @param {?} resolve
|
|
1126
|
-
* @param {?} reject
|
|
1127
|
-
* @return {?}
|
|
1128
|
-
*/
|
|
1129
|
-
(resolve, reject) => {
|
|
1130
|
-
/** @type {?} */
|
|
816
|
+
return new Promise((resolve, reject) => {
|
|
1131
817
|
const currentIndex = this.currentSection.data.questions.indexOf(this.currentQuestion.data);
|
|
1132
818
|
if (currentIndex === -1) {
|
|
1133
819
|
return reject('Could not find current question');
|
|
1134
820
|
}
|
|
1135
821
|
return resolve(currentIndex);
|
|
1136
|
-
})
|
|
822
|
+
});
|
|
1137
823
|
}
|
|
1138
824
|
/**
|
|
1139
825
|
* Checks a question is in bounds then navigates to it.
|
|
826
|
+
* @param index The index to navigate to.
|
|
827
|
+
* @returns A promise which will resolve when the question has been navigated to.
|
|
1140
828
|
* @author Will Poulson
|
|
1141
|
-
* @param {?} index The index to navigate to.
|
|
1142
|
-
* @return {?} A promise which will resolve when the question has been navigated to.
|
|
1143
829
|
*/
|
|
1144
830
|
navigateToQuestion(index) {
|
|
1145
|
-
return new Promise((
|
|
1146
|
-
* @param {?} resolve
|
|
1147
|
-
* @param {?} reject
|
|
1148
|
-
* @return {?}
|
|
1149
|
-
*/
|
|
1150
|
-
(resolve, reject) => {
|
|
831
|
+
return new Promise((resolve, reject) => {
|
|
1151
832
|
if (this.currentSection.data.questions.length - 1 < index || index < 0) {
|
|
1152
833
|
return reject('Out of bounds exception');
|
|
1153
834
|
}
|
|
1154
835
|
this.currentQuestionName = this.currentSection.data.questions[index].name;
|
|
1155
836
|
return resolve();
|
|
1156
|
-
})
|
|
837
|
+
});
|
|
1157
838
|
}
|
|
1158
839
|
/**
|
|
1159
840
|
* Navigates to the next section.
|
|
841
|
+
* @returns A promise which will resolve when the section has been navigated to.
|
|
1160
842
|
* @author Will Poulson
|
|
1161
|
-
* @return {?} A promise which will resolve when the section has been navigated to.
|
|
1162
843
|
*/
|
|
1163
844
|
nextSection() {
|
|
1164
|
-
return new Promise((
|
|
1165
|
-
|
|
1166
|
-
* @param {?} reject
|
|
1167
|
-
* @return {?}
|
|
1168
|
-
*/
|
|
1169
|
-
(resolve, reject) => {
|
|
1170
|
-
this.getCurrentSectionIndex().then((/**
|
|
1171
|
-
* @param {?} currentIndex
|
|
1172
|
-
* @return {?}
|
|
1173
|
-
*/
|
|
1174
|
-
(currentIndex) => {
|
|
1175
|
-
/** @type {?} */
|
|
845
|
+
return new Promise((resolve, reject) => {
|
|
846
|
+
this.getCurrentSectionIndex().then((currentIndex) => {
|
|
1176
847
|
const newIndex = currentIndex + 1;
|
|
1177
|
-
this.navigateToSection(newIndex).then((
|
|
1178
|
-
* @return {?}
|
|
1179
|
-
*/
|
|
1180
|
-
() => {
|
|
848
|
+
this.navigateToSection(newIndex).then(() => {
|
|
1181
849
|
return resolve();
|
|
1182
|
-
})
|
|
1183
|
-
* @param {?} error
|
|
1184
|
-
* @return {?}
|
|
1185
|
-
*/
|
|
1186
|
-
(error) => {
|
|
850
|
+
}).catch((error) => {
|
|
1187
851
|
return reject(error);
|
|
1188
|
-
})
|
|
1189
|
-
})
|
|
1190
|
-
* @param {?} error
|
|
1191
|
-
* @return {?}
|
|
1192
|
-
*/
|
|
1193
|
-
(error) => {
|
|
852
|
+
});
|
|
853
|
+
}).catch((error) => {
|
|
1194
854
|
return reject(error);
|
|
1195
|
-
})
|
|
1196
|
-
})
|
|
855
|
+
});
|
|
856
|
+
});
|
|
1197
857
|
}
|
|
1198
858
|
/**
|
|
1199
859
|
* Navigates to the previous section.
|
|
860
|
+
* @returns A promise which will resolve when the section has been navigated to.
|
|
1200
861
|
* @author Will Poulson
|
|
1201
|
-
* @return {?} A promise which will resolve when the section has been navigated to.
|
|
1202
862
|
*/
|
|
1203
863
|
prevSection() {
|
|
1204
|
-
return new Promise((
|
|
1205
|
-
|
|
1206
|
-
* @param {?} reject
|
|
1207
|
-
* @return {?}
|
|
1208
|
-
*/
|
|
1209
|
-
(resolve, reject) => {
|
|
1210
|
-
this.getCurrentSectionIndex().then((/**
|
|
1211
|
-
* @param {?} currentIndex
|
|
1212
|
-
* @return {?}
|
|
1213
|
-
*/
|
|
1214
|
-
(currentIndex) => {
|
|
1215
|
-
/** @type {?} */
|
|
864
|
+
return new Promise((resolve, reject) => {
|
|
865
|
+
this.getCurrentSectionIndex().then((currentIndex) => {
|
|
1216
866
|
const newIndex = currentIndex - 1;
|
|
1217
|
-
this.navigateToSection(newIndex).then((
|
|
1218
|
-
* @return {?}
|
|
1219
|
-
*/
|
|
1220
|
-
() => {
|
|
867
|
+
this.navigateToSection(newIndex).then(() => {
|
|
1221
868
|
return resolve();
|
|
1222
|
-
})
|
|
1223
|
-
* @param {?} error
|
|
1224
|
-
* @return {?}
|
|
1225
|
-
*/
|
|
1226
|
-
(error) => {
|
|
869
|
+
}).catch((error) => {
|
|
1227
870
|
return reject(error);
|
|
1228
|
-
})
|
|
1229
|
-
})
|
|
1230
|
-
* @param {?} error
|
|
1231
|
-
* @return {?}
|
|
1232
|
-
*/
|
|
1233
|
-
(error) => {
|
|
871
|
+
});
|
|
872
|
+
}).catch((error) => {
|
|
1234
873
|
return reject(error);
|
|
1235
|
-
})
|
|
1236
|
-
})
|
|
874
|
+
});
|
|
875
|
+
});
|
|
1237
876
|
}
|
|
1238
877
|
/**
|
|
1239
878
|
* Gets the current section index.
|
|
879
|
+
* @returns A promise which resolves a number.
|
|
1240
880
|
* @author Will Poulson
|
|
1241
|
-
* @private
|
|
1242
|
-
* @return {?} A promise which resolves a number.
|
|
1243
881
|
*/
|
|
1244
882
|
getCurrentSectionIndex() {
|
|
1245
|
-
return new Promise((
|
|
1246
|
-
* @param {?} resolve
|
|
1247
|
-
* @param {?} reject
|
|
1248
|
-
* @return {?}
|
|
1249
|
-
*/
|
|
1250
|
-
(resolve, reject) => {
|
|
1251
|
-
/** @type {?} */
|
|
883
|
+
return new Promise((resolve, reject) => {
|
|
1252
884
|
const currentIndex = this.currentQuestionnaire.sections.indexOf(this.currentSection.data);
|
|
1253
885
|
if (currentIndex === -1) {
|
|
1254
886
|
return reject('Could not find current section');
|
|
1255
887
|
}
|
|
1256
888
|
return resolve(currentIndex);
|
|
1257
|
-
})
|
|
889
|
+
});
|
|
1258
890
|
}
|
|
1259
891
|
/**
|
|
1260
892
|
* Checks a section is in bounds then navigates to it.
|
|
893
|
+
* @param index The index to navigate to.
|
|
894
|
+
* @returns A promise which will resolve when the section has been navigated to.
|
|
1261
895
|
* @author Will Poulson
|
|
1262
|
-
* @param {?} index The index to navigate to.
|
|
1263
|
-
* @return {?} A promise which will resolve when the section has been navigated to.
|
|
1264
896
|
*/
|
|
1265
897
|
navigateToSection(index) {
|
|
1266
|
-
return new Promise((
|
|
1267
|
-
* @param {?} resolve
|
|
1268
|
-
* @param {?} reject
|
|
1269
|
-
* @return {?}
|
|
1270
|
-
*/
|
|
1271
|
-
(resolve, reject) => {
|
|
898
|
+
return new Promise((resolve, reject) => {
|
|
1272
899
|
if (this.currentQuestionnaire.sections.length - 1 < index || index < 0) {
|
|
1273
900
|
return reject('Out of bounds exception');
|
|
1274
901
|
}
|
|
1275
902
|
this.currentSectionName = this.currentQuestionnaire.sections[index].name;
|
|
1276
903
|
return resolve();
|
|
1277
|
-
})
|
|
904
|
+
});
|
|
1278
905
|
}
|
|
1279
906
|
/**
|
|
1280
907
|
* Answers the current question with the parsed value.
|
|
908
|
+
* @param answer The value to answer the question with.
|
|
1281
909
|
* @author Will Poulson
|
|
1282
|
-
* @param {?} answer The value to answer the question with.
|
|
1283
|
-
* @param {?=} sendToNextQuestion
|
|
1284
|
-
* @return {?}
|
|
1285
910
|
*/
|
|
1286
911
|
answerCurrentQuestion(answer, sendToNextQuestion) {
|
|
1287
912
|
if (!sendToNextQuestion) {
|
|
@@ -1290,37 +915,25 @@ class QuestionnaireService {
|
|
|
1290
915
|
}
|
|
1291
916
|
if (this.skippable) { // Timeout to prevent skipping glitch.
|
|
1292
917
|
this.skippable = false;
|
|
1293
|
-
setTimeout((
|
|
1294
|
-
* @return {?}
|
|
1295
|
-
*/
|
|
1296
|
-
() => {
|
|
918
|
+
setTimeout(() => {
|
|
1297
919
|
this.currentQuestion.formControl.setValue(answer);
|
|
1298
|
-
this.nextQuestion().then((
|
|
1299
|
-
* @return {?}
|
|
1300
|
-
*/
|
|
1301
|
-
() => {
|
|
920
|
+
this.nextQuestion().then(() => {
|
|
1302
921
|
this.skippable = true;
|
|
1303
|
-
})
|
|
1304
|
-
}
|
|
922
|
+
});
|
|
923
|
+
}, 150);
|
|
1305
924
|
}
|
|
1306
925
|
}
|
|
1307
926
|
/**
|
|
1308
927
|
* Adds a repeater item to the current question.
|
|
1309
928
|
* Current question must be of type Repeater.
|
|
929
|
+
* @returns A promise which resolves when the repeater item has been added.
|
|
1310
930
|
* @author Will Poulson
|
|
1311
|
-
* @return {?} A promise which resolves when the repeater item has been added.
|
|
1312
931
|
*/
|
|
1313
932
|
addRepeaterItem() {
|
|
1314
|
-
return new Promise((
|
|
1315
|
-
* @param {?} resolve
|
|
1316
|
-
* @param {?} reject
|
|
1317
|
-
* @return {?}
|
|
1318
|
-
*/
|
|
1319
|
-
(resolve, reject) => {
|
|
933
|
+
return new Promise((resolve, reject) => {
|
|
1320
934
|
if (this.currentQuestion.data.type !== QuestionType.Repeater) {
|
|
1321
935
|
return reject(`Current question isn't a repeater`);
|
|
1322
936
|
}
|
|
1323
|
-
/** @type {?} */
|
|
1324
937
|
const repeaterForm = this.formConstuctor.generateFormsForRepeater(this.currentQuestion.data);
|
|
1325
938
|
if (!repeaterForm) {
|
|
1326
939
|
return reject(`Repeater template failed to generate. May be due to the repeater having no items in the editor.`);
|
|
@@ -1330,22 +943,17 @@ class QuestionnaireService {
|
|
|
1330
943
|
}
|
|
1331
944
|
this.currentQuestion.formControl.push(repeaterForm);
|
|
1332
945
|
return resolve();
|
|
1333
|
-
})
|
|
946
|
+
});
|
|
1334
947
|
}
|
|
1335
948
|
/**
|
|
1336
949
|
* Removes a repeater item on the current question.
|
|
1337
950
|
* Current question must be of type Repeater.
|
|
951
|
+
* @param index The index at which to remove.
|
|
952
|
+
* @returns A promise which resolves when the repeater item has been removed.
|
|
1338
953
|
* @author Will Poulson
|
|
1339
|
-
* @param {?} index The index at which to remove.
|
|
1340
|
-
* @return {?} A promise which resolves when the repeater item has been removed.
|
|
1341
954
|
*/
|
|
1342
955
|
removeRepeaterItem(index) {
|
|
1343
|
-
return new Promise((
|
|
1344
|
-
* @param {?} resolve
|
|
1345
|
-
* @param {?} reject
|
|
1346
|
-
* @return {?}
|
|
1347
|
-
*/
|
|
1348
|
-
(resolve, reject) => {
|
|
956
|
+
return new Promise((resolve, reject) => {
|
|
1349
957
|
if (this.currentQuestion.data.type !== QuestionType.Repeater) {
|
|
1350
958
|
return reject(`Current question isn't a repeater`);
|
|
1351
959
|
}
|
|
@@ -1354,36 +962,29 @@ class QuestionnaireService {
|
|
|
1354
962
|
}
|
|
1355
963
|
this.currentQuestion.formControl.removeAt(index);
|
|
1356
964
|
return resolve();
|
|
1357
|
-
})
|
|
965
|
+
});
|
|
1358
966
|
}
|
|
1359
967
|
/**
|
|
1360
968
|
* Returns the display text for a given repeater item
|
|
969
|
+
* @param index The index at which to get the label for.
|
|
970
|
+
* @returns A string which is the display text.
|
|
1361
971
|
* @author Will Poulson
|
|
1362
|
-
* @param {?} index The index at which to get the label for.
|
|
1363
|
-
* @return {?} A string which is the display text.
|
|
1364
972
|
*/
|
|
1365
973
|
getRepeaterItemLabel(index) {
|
|
1366
974
|
if (!this.currentQuestion.formControl || !(this.currentQuestion.formControl instanceof FormArray)) {
|
|
1367
975
|
return '';
|
|
1368
976
|
}
|
|
1369
|
-
/** @type {?} */
|
|
1370
977
|
const repeaterItem = this.currentQuestion.formControl.controls[index];
|
|
1371
978
|
if (!repeaterItem) {
|
|
1372
979
|
return '';
|
|
1373
980
|
}
|
|
1374
|
-
/** @type {?} */
|
|
1375
981
|
const template = this.currentQuestion.data.repeaterDisplayName;
|
|
1376
|
-
/** @type {?} */
|
|
1377
982
|
const splitTemplate = template.split(' ');
|
|
1378
|
-
/** @type {?} */
|
|
1379
983
|
const displayArray = [];
|
|
1380
984
|
for (const templateItem of splitTemplate) {
|
|
1381
985
|
if (templateItem.match(/\[.*?\]/)) {
|
|
1382
|
-
/** @type {?} */
|
|
1383
986
|
const path = templateItem.replace(/[\[\]']+/g, '');
|
|
1384
|
-
/** @type {?} */
|
|
1385
987
|
const item = repeaterItem.get(path);
|
|
1386
|
-
/** @type {?} */
|
|
1387
988
|
const value = (item && item.value ? item.value : '?');
|
|
1388
989
|
displayArray.push(value);
|
|
1389
990
|
}
|
|
@@ -1391,90 +992,23 @@ class QuestionnaireService {
|
|
|
1391
992
|
displayArray.push(templateItem);
|
|
1392
993
|
}
|
|
1393
994
|
}
|
|
1394
|
-
/** @type {?} */
|
|
1395
995
|
const display = displayArray.join(' ');
|
|
1396
996
|
return display;
|
|
1397
997
|
}
|
|
1398
998
|
}
|
|
1399
|
-
QuestionnaireService
|
|
1400
|
-
|
|
999
|
+
QuestionnaireService.ɵfac = function QuestionnaireService_Factory(t) { return new (t || QuestionnaireService)(ɵɵinject(FormConstructorService), ɵɵinject('options')); };
|
|
1000
|
+
QuestionnaireService.ɵprov = ɵɵdefineInjectable({ token: QuestionnaireService, factory: QuestionnaireService.ɵfac, providedIn: 'root' });
|
|
1001
|
+
/*@__PURE__*/ (function () { ɵsetClassMetadata(QuestionnaireService, [{
|
|
1002
|
+
type: Injectable,
|
|
1003
|
+
args: [{
|
|
1401
1004
|
providedIn: 'root'
|
|
1402
|
-
}
|
|
1403
|
-
]
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
{ type: undefined, decorators: [{ type: Inject, args: ['options',] }] }
|
|
1408
|
-
];
|
|
1409
|
-
/** @nocollapse */ QuestionnaireService.ngInjectableDef = ɵɵdefineInjectable({ factory: function QuestionnaireService_Factory() { return new QuestionnaireService(ɵɵinject(FormConstructorService), ɵɵinject("options")); }, token: QuestionnaireService, providedIn: "root" });
|
|
1410
|
-
if (false) {
|
|
1411
|
-
/** @type {?} */
|
|
1412
|
-
QuestionnaireService.prototype.dataChangedEvent;
|
|
1413
|
-
/** @type {?} */
|
|
1414
|
-
QuestionnaireService.prototype.sectionFinishedEvent;
|
|
1415
|
-
/**
|
|
1416
|
-
* @type {?}
|
|
1417
|
-
* @private
|
|
1418
|
-
*/
|
|
1419
|
-
QuestionnaireService.prototype.originalQuestionnaire;
|
|
1420
|
-
/**
|
|
1421
|
-
* @type {?}
|
|
1422
|
-
* @private
|
|
1423
|
-
*/
|
|
1424
|
-
QuestionnaireService.prototype.currentQuestionnaire;
|
|
1425
|
-
/**
|
|
1426
|
-
* @type {?}
|
|
1427
|
-
* @private
|
|
1428
|
-
*/
|
|
1429
|
-
QuestionnaireService.prototype.currentQuestionnaireForm;
|
|
1430
|
-
/**
|
|
1431
|
-
* @type {?}
|
|
1432
|
-
* @private
|
|
1433
|
-
*/
|
|
1434
|
-
QuestionnaireService.prototype.currentSectionName;
|
|
1435
|
-
/**
|
|
1436
|
-
* @type {?}
|
|
1437
|
-
* @private
|
|
1438
|
-
*/
|
|
1439
|
-
QuestionnaireService.prototype.currentQuestionName;
|
|
1440
|
-
/**
|
|
1441
|
-
* @type {?}
|
|
1442
|
-
* @private
|
|
1443
|
-
*/
|
|
1444
|
-
QuestionnaireService.prototype.questionnaireValueChangeSubscription;
|
|
1445
|
-
/**
|
|
1446
|
-
* @type {?}
|
|
1447
|
-
* @private
|
|
1448
|
-
*/
|
|
1449
|
-
QuestionnaireService.prototype.questionValueChangeSubscription;
|
|
1450
|
-
/** @type {?} */
|
|
1451
|
-
QuestionnaireService.prototype.additionalData;
|
|
1452
|
-
/**
|
|
1453
|
-
* @type {?}
|
|
1454
|
-
* @private
|
|
1455
|
-
*/
|
|
1456
|
-
QuestionnaireService.prototype.skippable;
|
|
1457
|
-
/**
|
|
1458
|
-
* @type {?}
|
|
1459
|
-
* @private
|
|
1460
|
-
*/
|
|
1461
|
-
QuestionnaireService.prototype.formConstuctor;
|
|
1462
|
-
/**
|
|
1463
|
-
* @type {?}
|
|
1464
|
-
* @private
|
|
1465
|
-
*/
|
|
1466
|
-
QuestionnaireService.prototype.options;
|
|
1467
|
-
}
|
|
1005
|
+
}]
|
|
1006
|
+
}], function () { return [{ type: FormConstructorService }, { type: undefined, decorators: [{
|
|
1007
|
+
type: Inject,
|
|
1008
|
+
args: ['options']
|
|
1009
|
+
}] }]; }, null); })();
|
|
1468
1010
|
|
|
1469
|
-
/**
|
|
1470
|
-
* @fileoverview added by tsickle
|
|
1471
|
-
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1472
|
-
*/
|
|
1473
1011
|
class GgQuestionnaireV2Module {
|
|
1474
|
-
/**
|
|
1475
|
-
* @param {?} options
|
|
1476
|
-
* @return {?}
|
|
1477
|
-
*/
|
|
1478
1012
|
static forRoot(options) {
|
|
1479
1013
|
return {
|
|
1480
1014
|
ngModule: GgQuestionnaireV2Module,
|
|
@@ -1488,8 +1022,19 @@ class GgQuestionnaireV2Module {
|
|
|
1488
1022
|
};
|
|
1489
1023
|
}
|
|
1490
1024
|
}
|
|
1491
|
-
GgQuestionnaireV2Module
|
|
1492
|
-
|
|
1025
|
+
GgQuestionnaireV2Module.ɵmod = ɵɵdefineNgModule({ type: GgQuestionnaireV2Module });
|
|
1026
|
+
GgQuestionnaireV2Module.ɵinj = ɵɵdefineInjector({ factory: function GgQuestionnaireV2Module_Factory(t) { return new (t || GgQuestionnaireV2Module)(); }, providers: [
|
|
1027
|
+
FormConstructorService,
|
|
1028
|
+
FilterService
|
|
1029
|
+
], imports: [[
|
|
1030
|
+
FormsModule,
|
|
1031
|
+
ReactiveFormsModule
|
|
1032
|
+
]] });
|
|
1033
|
+
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && ɵɵsetNgModuleScope(GgQuestionnaireV2Module, { imports: [FormsModule,
|
|
1034
|
+
ReactiveFormsModule] }); })();
|
|
1035
|
+
/*@__PURE__*/ (function () { ɵsetClassMetadata(GgQuestionnaireV2Module, [{
|
|
1036
|
+
type: NgModule,
|
|
1037
|
+
args: [{
|
|
1493
1038
|
declarations: [],
|
|
1494
1039
|
providers: [
|
|
1495
1040
|
FormConstructorService,
|
|
@@ -1499,48 +1044,36 @@ GgQuestionnaireV2Module.decorators = [
|
|
|
1499
1044
|
FormsModule,
|
|
1500
1045
|
ReactiveFormsModule
|
|
1501
1046
|
],
|
|
1502
|
-
}
|
|
1503
|
-
];
|
|
1047
|
+
}]
|
|
1048
|
+
}], null, null); })();
|
|
1504
1049
|
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
Time: 'time',
|
|
1520
|
-
Month: 'month',
|
|
1521
|
-
Week: 'week',
|
|
1522
|
-
};
|
|
1050
|
+
var InputType;
|
|
1051
|
+
(function (InputType) {
|
|
1052
|
+
InputType["Text"] = "text";
|
|
1053
|
+
InputType["Number"] = "number";
|
|
1054
|
+
InputType["Email"] = "email";
|
|
1055
|
+
InputType["Telephone"] = "tel";
|
|
1056
|
+
InputType["Password"] = "password";
|
|
1057
|
+
InputType["Color"] = "color";
|
|
1058
|
+
InputType["Date"] = "date";
|
|
1059
|
+
InputType["DateTimeLocal"] = "datetime-local";
|
|
1060
|
+
InputType["Time"] = "time";
|
|
1061
|
+
InputType["Month"] = "month";
|
|
1062
|
+
InputType["Week"] = "week";
|
|
1063
|
+
})(InputType || (InputType = {}));
|
|
1523
1064
|
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
Input: 'input',
|
|
1531
|
-
Select: 'select',
|
|
1532
|
-
Upload: 'upload',
|
|
1533
|
-
};
|
|
1065
|
+
var RepeaterQuestionType;
|
|
1066
|
+
(function (RepeaterQuestionType) {
|
|
1067
|
+
RepeaterQuestionType["Input"] = "input";
|
|
1068
|
+
RepeaterQuestionType["Select"] = "select";
|
|
1069
|
+
RepeaterQuestionType["Upload"] = "upload";
|
|
1070
|
+
})(RepeaterQuestionType || (RepeaterQuestionType = {}));
|
|
1534
1071
|
|
|
1535
|
-
|
|
1536
|
-
* @fileoverview added by tsickle
|
|
1537
|
-
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1538
|
-
*/
|
|
1072
|
+
// Services
|
|
1539
1073
|
|
|
1540
1074
|
/**
|
|
1541
|
-
*
|
|
1542
|
-
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1075
|
+
* Generated bundle index. Do not edit.
|
|
1543
1076
|
*/
|
|
1544
1077
|
|
|
1545
|
-
export { ConditionRelationship, ConditionType, GgQuestionnaireV2Module, InputType, QuestionType, QuestionnaireService, RepeaterQuestionType, ValidationType
|
|
1078
|
+
export { ConditionRelationship, ConditionType, GgQuestionnaireV2Module, InputType, QuestionType, QuestionnaireService, RepeaterQuestionType, ValidationType };
|
|
1546
1079
|
//# sourceMappingURL=glowgreen-gg-questionnaire-v2.js.map
|