@ng-formworks/core 16.5.8 → 16.6.2
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/esm2022/lib/json-schema-form.component.mjs +25 -6
- package/esm2022/lib/json-schema-form.service.mjs +139 -27
- package/esm2022/lib/locale/de-validation-messages.mjs +4 -2
- package/esm2022/lib/locale/en-validation-messages.mjs +4 -2
- package/esm2022/lib/locale/es-validation-messages.mjs +4 -2
- package/esm2022/lib/locale/fr-validation-messages.mjs +4 -2
- package/esm2022/lib/locale/it-validation-messages.mjs +4 -2
- package/esm2022/lib/locale/pt-validation-messages.mjs +4 -2
- package/esm2022/lib/locale/zh-validation-messages.mjs +4 -2
- package/esm2022/lib/shared/form-group.functions.mjs +326 -14
- package/esm2022/lib/shared/format-regex.constants.mjs +2 -1
- package/esm2022/lib/shared/index.mjs +6 -6
- package/esm2022/lib/shared/json-schema.functions.mjs +96 -4
- package/esm2022/lib/shared/json.validators.mjs +11 -6
- package/esm2022/lib/shared/jsonpointer.functions.mjs +2 -2
- package/esm2022/lib/shared/layout.functions.mjs +172 -14
- package/esm2022/lib/shared/utility.functions.mjs +31 -1
- package/esm2022/lib/widget-library/add-reference.component.mjs +19 -15
- package/esm2022/lib/widget-library/button.component.mjs +4 -1
- package/esm2022/lib/widget-library/checkbox.component.mjs +12 -4
- package/esm2022/lib/widget-library/checkboxes.component.mjs +9 -2
- package/esm2022/lib/widget-library/file.component.mjs +4 -1
- package/esm2022/lib/widget-library/hidden.component.mjs +4 -1
- package/esm2022/lib/widget-library/input.component.mjs +4 -1
- package/esm2022/lib/widget-library/number.component.mjs +4 -1
- package/esm2022/lib/widget-library/one-of.component.mjs +87 -3
- package/esm2022/lib/widget-library/radios.component.mjs +5 -2
- package/esm2022/lib/widget-library/root.component.mjs +74 -1
- package/esm2022/lib/widget-library/select.component.mjs +91 -6
- package/esm2022/lib/widget-library/submit.component.mjs +2 -1
- package/esm2022/lib/widget-library/tabs.component.mjs +76 -28
- package/esm2022/lib/widget-library/textarea.component.mjs +4 -1
- package/esm2022/lib/widget-library/widget-library.module.mjs +15 -3
- package/fesm2022/ng-formworks-core.mjs +1324 -244
- package/fesm2022/ng-formworks-core.mjs.map +1 -1
- package/lib/json-schema-form.component.d.ts +10 -1
- package/lib/json-schema-form.service.d.ts +22 -4
- package/lib/shared/form-group.functions.d.ts +29 -1
- package/lib/shared/format-regex.constants.d.ts +2 -1
- package/lib/shared/index.d.ts +6 -6
- package/lib/shared/json-schema.functions.d.ts +22 -0
- package/lib/shared/json.validators.d.ts +2 -2
- package/lib/shared/layout.functions.d.ts +1 -1
- package/lib/shared/utility.functions.d.ts +15 -0
- package/lib/widget-library/button.component.d.ts +2 -1
- package/lib/widget-library/checkbox.component.d.ts +2 -1
- package/lib/widget-library/checkboxes.component.d.ts +2 -1
- package/lib/widget-library/file.component.d.ts +2 -1
- package/lib/widget-library/hidden.component.d.ts +2 -1
- package/lib/widget-library/input.component.d.ts +1 -0
- package/lib/widget-library/number.component.d.ts +1 -0
- package/lib/widget-library/one-of.component.d.ts +2 -0
- package/lib/widget-library/radios.component.d.ts +2 -1
- package/lib/widget-library/root.component.d.ts +1 -0
- package/lib/widget-library/select.component.d.ts +5 -2
- package/lib/widget-library/textarea.component.d.ts +2 -1
- package/package.json +1 -1
|
@@ -4,13 +4,16 @@ import * as i0 from '@angular/core';
|
|
|
4
4
|
import { Injectable, ViewContainerRef, Component, Input, ViewChild, Directive, ChangeDetectionStrategy, NgModule, Inject, forwardRef, EventEmitter, Output } from '@angular/core';
|
|
5
5
|
import * as i3 from '@angular/forms';
|
|
6
6
|
import { UntypedFormControl, UntypedFormArray, UntypedFormGroup, FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
7
|
+
import addFormats from 'ajv-formats';
|
|
7
8
|
import Ajv2019 from 'ajv/dist/2019';
|
|
8
9
|
import jsonDraft6 from 'ajv/lib/refs/json-schema-draft-06.json';
|
|
9
10
|
import jsonDraft7 from 'ajv/lib/refs/json-schema-draft-07.json';
|
|
10
11
|
import cloneDeep from 'lodash/cloneDeep';
|
|
11
12
|
import { from, Observable, forkJoin, Subject, BehaviorSubject, lastValueFrom } from 'rxjs';
|
|
13
|
+
import { some, isNil, isEmpty as isEmpty$1, isObject as isObject$1, pick, isEqual as isEqual$2 } from 'lodash';
|
|
12
14
|
import isEqual$1 from 'lodash/isEqual';
|
|
13
15
|
import { map, takeUntil } from 'rxjs/operators';
|
|
16
|
+
import omit from 'lodash/omit';
|
|
14
17
|
import filter from 'lodash/filter';
|
|
15
18
|
import map$1 from 'lodash/map';
|
|
16
19
|
import _isArray from 'lodash/isArray';
|
|
@@ -61,13 +64,15 @@ const deValidationMessages = {
|
|
|
61
64
|
case 'uuid':
|
|
62
65
|
return 'Keine gültige UUID (z. B. "12345678-9ABC-DEF0-1234-56789ABCDEF0")';
|
|
63
66
|
case 'color':
|
|
64
|
-
return 'Kein gültiger Farbwert (z. B. "#FFFFFF"
|
|
67
|
+
return 'Kein gültiger Farbwert (z. B. "#FFFFFF")';
|
|
65
68
|
case 'json-pointer':
|
|
66
69
|
return 'Kein gültiger JSON-Pointer (z. B. "/pointer/to/something")';
|
|
67
70
|
case 'relative-json-pointer':
|
|
68
71
|
return 'Kein gültiger relativer JSON-Pointer (z. B. "2/pointer/to/something")';
|
|
69
72
|
case 'regex':
|
|
70
73
|
return 'Kein gültiger regulärer Ausdruck (z. B. "(1-)?\\d{3}-\\d{3}-\\d{4}")';
|
|
74
|
+
case 'duration':
|
|
75
|
+
return "Muss eine gültige ISO 8601-Dauer sein (z. B. 'PT1H30M')";
|
|
71
76
|
default:
|
|
72
77
|
return 'Muss diesem Format entsprechen: ' + error.requiredFormat;
|
|
73
78
|
}
|
|
@@ -121,13 +126,15 @@ const enValidationMessages = {
|
|
|
121
126
|
case 'uuid':
|
|
122
127
|
return 'Must be a uuid, like "12345678-9ABC-DEF0-1234-56789ABCDEF0"';
|
|
123
128
|
case 'color':
|
|
124
|
-
return 'Must be a color, like "#FFFFFF"
|
|
129
|
+
return 'Must be a color, like "#FFFFFF"';
|
|
125
130
|
case 'json-pointer':
|
|
126
131
|
return 'Must be a JSON Pointer, like "/pointer/to/something"';
|
|
127
132
|
case 'relative-json-pointer':
|
|
128
133
|
return 'Must be a relative JSON Pointer, like "2/pointer/to/something"';
|
|
129
134
|
case 'regex':
|
|
130
135
|
return 'Must be a regular expression, like "(1-)?\\d{3}-\\d{3}-\\d{4}"';
|
|
136
|
+
case 'duration':
|
|
137
|
+
return "Must be a valid ISO 8601 duration (e.g., 'PT1H30M')";
|
|
131
138
|
default:
|
|
132
139
|
return 'Must be a correctly formatted ' + error.requiredFormat;
|
|
133
140
|
}
|
|
@@ -179,13 +186,15 @@ const esValidationMessages = {
|
|
|
179
186
|
case 'uuid':
|
|
180
187
|
return 'Debe ser un UUID, ej "12345678-9ABC-DEF0-1234-56789ABCDEF0"';
|
|
181
188
|
case 'color':
|
|
182
|
-
return 'Debe ser un color, ej "#FFFFFF"
|
|
189
|
+
return 'Debe ser un color, ej "#FFFFFF"';
|
|
183
190
|
case 'json-pointer':
|
|
184
191
|
return 'Debe ser un JSON Pointer, ej "/pointer/to/something"';
|
|
185
192
|
case 'relative-json-pointer':
|
|
186
193
|
return 'Debe ser un JSON Pointer relativo, ej "2/pointer/to/something"';
|
|
187
194
|
case 'regex':
|
|
188
195
|
return 'Debe ser una expresión regular, ej "(1-)?\\d{3}-\\d{3}-\\d{4}"';
|
|
196
|
+
case 'duration':
|
|
197
|
+
return "Debe ser una duración válida en formato ISO 8601 (p. ej., 'PT1H30M')";
|
|
189
198
|
default:
|
|
190
199
|
return 'Debe tener el formato correcto ' + error.requiredFormat;
|
|
191
200
|
}
|
|
@@ -238,13 +247,15 @@ const frValidationMessages = {
|
|
|
238
247
|
case 'uuid':
|
|
239
248
|
return 'Doit être un UUID, tel que "12345678-9ABC-DEF0-1234-56789ABCDEF0"';
|
|
240
249
|
case 'color':
|
|
241
|
-
return 'Doit être une couleur, tel que "#FFFFFF"
|
|
250
|
+
return 'Doit être une couleur, tel que "#FFFFFF"';
|
|
242
251
|
case 'json-pointer':
|
|
243
252
|
return 'Doit être un JSON Pointer, tel que "/pointer/to/something"';
|
|
244
253
|
case 'relative-json-pointer':
|
|
245
254
|
return 'Doit être un relative JSON Pointer, tel que "2/pointer/to/something"';
|
|
246
255
|
case 'regex':
|
|
247
256
|
return 'Doit être une expression régulière, tel que "(1-)?\\d{3}-\\d{3}-\\d{4}"';
|
|
257
|
+
case 'duration':
|
|
258
|
+
return "Doit être une durée valide au format ISO 8601 (par ex., 'PT1H30M')";
|
|
248
259
|
default:
|
|
249
260
|
return 'Doit être avoir le format correct: ' + error.requiredFormat;
|
|
250
261
|
}
|
|
@@ -298,13 +309,15 @@ const itValidationMessages = {
|
|
|
298
309
|
case 'uuid':
|
|
299
310
|
return 'Deve essere un uuid, come "12345678-9ABC-DEF0-1234-56789ABCDEF0"';
|
|
300
311
|
case 'color':
|
|
301
|
-
return 'Deve essere un colore, come "#FFFFFF"
|
|
312
|
+
return 'Deve essere un colore, come "#FFFFFF"';
|
|
302
313
|
case 'json-pointer':
|
|
303
314
|
return 'Deve essere un JSON Pointer, come "/pointer/to/something"';
|
|
304
315
|
case 'relative-json-pointer':
|
|
305
316
|
return 'Deve essere un JSON Pointer relativo, come "2/pointer/to/something"';
|
|
306
317
|
case 'regex':
|
|
307
318
|
return 'Deve essere una regular expression, come "(1-)?\\d{3}-\\d{3}-\\d{4}"';
|
|
319
|
+
case 'duration':
|
|
320
|
+
return "Deve essere una durata valida nel formato ISO 8601 (es. 'PT1H30M')";
|
|
308
321
|
default:
|
|
309
322
|
return 'Deve essere formattato correttamente ' + error.requiredFormat;
|
|
310
323
|
}
|
|
@@ -358,13 +371,15 @@ const ptValidationMessages = {
|
|
|
358
371
|
case 'uuid':
|
|
359
372
|
return 'Tem que ser um uuid, por exemplo "12345678-9ABC-DEF0-1234-56789ABCDEF0"';
|
|
360
373
|
case 'color':
|
|
361
|
-
return 'Tem que ser uma cor, por exemplo "#FFFFFF"
|
|
374
|
+
return 'Tem que ser uma cor, por exemplo "#FFFFFF"';
|
|
362
375
|
case 'json-pointer':
|
|
363
376
|
return 'Tem que ser um JSON Pointer, por exemplo "/referencia/para/algo"';
|
|
364
377
|
case 'relative-json-pointer':
|
|
365
378
|
return 'Tem que ser um JSON Pointer relativo, por exemplo "2/referencia/para/algo"';
|
|
366
379
|
case 'regex':
|
|
367
380
|
return 'Tem que ser uma expressão regular, por exemplo "(1-)?\\d{3}-\\d{3}-\\d{4}"';
|
|
381
|
+
case 'duration':
|
|
382
|
+
return "Deve ser uma duração válida no formato ISO 8601 (ex.: 'PT1H30M')";
|
|
368
383
|
default:
|
|
369
384
|
return 'Tem que ser no formato: ' + error.requiredFormat;
|
|
370
385
|
}
|
|
@@ -418,13 +433,15 @@ const zhValidationMessages = {
|
|
|
418
433
|
case 'uuid':
|
|
419
434
|
return '必须为 uuid, 比如 "12345678-9ABC-DEF0-1234-56789ABCDEF0"';
|
|
420
435
|
case 'color':
|
|
421
|
-
return '必须为颜色值, 比如 "#FFFFFF"
|
|
436
|
+
return '必须为颜色值, 比如 "#FFFFFF"';
|
|
422
437
|
case 'json-pointer':
|
|
423
438
|
return '必须为 JSON Pointer, 比如 "/pointer/to/something"';
|
|
424
439
|
case 'relative-json-pointer':
|
|
425
440
|
return '必须为相对的 JSON Pointer, 比如 "2/pointer/to/something"';
|
|
426
441
|
case 'regex':
|
|
427
442
|
return '必须为正则表达式, 比如 "(1-)?\\d{3}-\\d{3}-\\d{4}"';
|
|
443
|
+
case 'duration':
|
|
444
|
+
return "必须是有效的 ISO 8601 持续时间(例如:'PT1H30M')";
|
|
428
445
|
default:
|
|
429
446
|
return '必须为格式正确的 ' + error.requiredFormat;
|
|
430
447
|
}
|
|
@@ -1410,6 +1427,35 @@ function toTitleCase(input, forceWords) {
|
|
|
1410
1427
|
return newWord;
|
|
1411
1428
|
}
|
|
1412
1429
|
});
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* Recursively checks if at least one property of the given object (including nested objects)
|
|
1433
|
+
* has a non-null and non-undefined value.
|
|
1434
|
+
*
|
|
1435
|
+
* @param obj - The object to check.
|
|
1436
|
+
* @returns `true` if at least one property has a non-null and non-undefined value, otherwise `false`.
|
|
1437
|
+
*
|
|
1438
|
+
* @example
|
|
1439
|
+
* const testObj = { a: null, b: { b1: null, b2: undefined } };
|
|
1440
|
+
* console.log(hasNonNullValue(testObj)); // Output: false
|
|
1441
|
+
*
|
|
1442
|
+
* const testObj2 = { a: 1, b: { b1: null, b2: undefined } };
|
|
1443
|
+
* console.log(hasNonNullValue(testObj2)); // Output: true
|
|
1444
|
+
*/
|
|
1445
|
+
function hasNonNullValue(obj) {
|
|
1446
|
+
// If the object is null or not an object, return false immediately
|
|
1447
|
+
if (obj === null || typeof obj !== 'object') {
|
|
1448
|
+
return false;
|
|
1449
|
+
}
|
|
1450
|
+
// _.some checks if at least one element passes the given condition.
|
|
1451
|
+
return some(obj, (value) => {
|
|
1452
|
+
// If value is an object, recurse deeper into the object.
|
|
1453
|
+
if (isObject(value)) {
|
|
1454
|
+
return hasNonNullValue(value);
|
|
1455
|
+
}
|
|
1456
|
+
// Check if value is neither null nor undefined.
|
|
1457
|
+
return !isNil(value);
|
|
1458
|
+
});
|
|
1413
1459
|
}
|
|
1414
1460
|
|
|
1415
1461
|
class JsonPointer {
|
|
@@ -2475,6 +2521,7 @@ const jsonSchemaFormatTests = {
|
|
|
2475
2521
|
// JSON-pointer: https://tools.ietf.org/html/rfc6901
|
|
2476
2522
|
'json-pointer': /^(?:\/(?:[^~/]|~0|~1)*)*$|^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,
|
|
2477
2523
|
'relative-json-pointer': /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/,
|
|
2524
|
+
'duration': /^P(?!$)(\d+Y)?(\d+M)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?$/,
|
|
2478
2525
|
'regex': function (str) {
|
|
2479
2526
|
if (/[^\\]\\Z/.test(str)) {
|
|
2480
2527
|
return false;
|
|
@@ -2771,7 +2818,7 @@ class JsonValidators {
|
|
|
2771
2818
|
* This validator currently checks the following formsts:
|
|
2772
2819
|
* date, time, date-time, email, hostname, ipv4, ipv6,
|
|
2773
2820
|
* uri, uri-reference, uri-template, url, uuid, color,
|
|
2774
|
-
* json-pointer, relative-json-pointer, regex
|
|
2821
|
+
* json-pointer, relative-json-pointer,duration, regex
|
|
2775
2822
|
*
|
|
2776
2823
|
* Fast format regular expressions copied from AJV:
|
|
2777
2824
|
* https://github.com/epoberezkin/ajv/blob/master/lib/compile/formats.js
|
|
@@ -2790,9 +2837,14 @@ class JsonValidators {
|
|
|
2790
2837
|
let isValid;
|
|
2791
2838
|
const currentValue = control.value;
|
|
2792
2839
|
if (isString(currentValue)) {
|
|
2840
|
+
//TODO fix-Reg exp last index problem
|
|
2841
|
+
//see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test
|
|
2842
|
+
//before every call to .test it needs to be reset
|
|
2843
|
+
//use either formatTest.lastIndex = 0; // Reset the lastIndex before each test
|
|
2844
|
+
//or new RegExp(formatTest.source, formatTest.flags);
|
|
2793
2845
|
const formatTest = jsonSchemaFormatTests[requiredFormat];
|
|
2794
2846
|
if (typeof formatTest === 'object') {
|
|
2795
|
-
isValid = formatTest.test(currentValue);
|
|
2847
|
+
isValid = new RegExp(formatTest.source, formatTest.flags).test(currentValue);
|
|
2796
2848
|
}
|
|
2797
2849
|
else if (typeof formatTest === 'function') {
|
|
2798
2850
|
isValid = formatTest(currentValue);
|
|
@@ -4029,8 +4081,18 @@ function getInputType(schema, layoutNode = null) {
|
|
|
4029
4081
|
if (hasOwn(schema, '$ref')) {
|
|
4030
4082
|
return '$ref';
|
|
4031
4083
|
}
|
|
4032
|
-
if (isArray(schema.
|
|
4084
|
+
//if (isArray(schema.anyOf)) { return 'any-of'; }//treated as allOf
|
|
4085
|
+
if (isArray(schema.oneOf)) {
|
|
4033
4086
|
return 'one-of';
|
|
4087
|
+
} //{ return 'tabarray'; }
|
|
4088
|
+
if (hasOwn(schema, 'if')) {
|
|
4089
|
+
return 'if';
|
|
4090
|
+
}
|
|
4091
|
+
if (hasOwn(schema, 'then')) {
|
|
4092
|
+
return 'then';
|
|
4093
|
+
}
|
|
4094
|
+
if (hasOwn(schema, 'else')) {
|
|
4095
|
+
return 'else';
|
|
4034
4096
|
}
|
|
4035
4097
|
console.error(`getInputType error: Unable to determine input type for ${schemaType}`);
|
|
4036
4098
|
console.error('schema', schema);
|
|
@@ -4443,6 +4505,14 @@ function getSubSchema(schema, pointer, schemaRefLibrary = null, schemaRecursiveR
|
|
|
4443
4505
|
return subSchema;
|
|
4444
4506
|
}, true, pointer);
|
|
4445
4507
|
}
|
|
4508
|
+
function omitKeys(objects, keysToOmit) {
|
|
4509
|
+
return objects.map((obj) => omit(obj, keysToOmit));
|
|
4510
|
+
}
|
|
4511
|
+
function combineAllOfITE(schema) {
|
|
4512
|
+
if (schema && schema.allOf) {
|
|
4513
|
+
const allITE = schema.allOf.map(item => { return item.if && { if: item.if }; });
|
|
4514
|
+
}
|
|
4515
|
+
}
|
|
4446
4516
|
/**
|
|
4447
4517
|
* 'combineAllOf' function
|
|
4448
4518
|
*
|
|
@@ -4456,11 +4526,24 @@ function combineAllOf(schema) {
|
|
|
4456
4526
|
if (!isObject(schema) || !isArray(schema.allOf)) {
|
|
4457
4527
|
return schema;
|
|
4458
4528
|
}
|
|
4459
|
-
|
|
4529
|
+
const allITE = schema.allOf.map(item => { return item.if && item; })
|
|
4530
|
+
.filter(item => !isEmpty$1(item));
|
|
4531
|
+
//adaped to accomodate ITE by merging all non ITE field
|
|
4532
|
+
//then readding the allOf key with only ITE
|
|
4533
|
+
let schemaITEOmitted = omitKeys(schema.allOf, ['if', 'then', 'else']);
|
|
4534
|
+
let mergedSchema = mergeSchemas(...schemaITEOmitted);
|
|
4535
|
+
//mergeSchemas(...schema.allOf);
|
|
4460
4536
|
if (Object.keys(schema).length > 1) {
|
|
4461
4537
|
const extraKeys = { ...schema };
|
|
4462
4538
|
delete extraKeys.allOf;
|
|
4463
|
-
|
|
4539
|
+
//TODO Test-changed order to preserve originial order
|
|
4540
|
+
mergedSchema = mergeSchemas(extraKeys, mergedSchema);
|
|
4541
|
+
//mergeSchemas(mergedSchema, extraKeys);
|
|
4542
|
+
//need to put it back if ITE
|
|
4543
|
+
if (allITE && allITE.length > 0) {
|
|
4544
|
+
mergedSchema.allOf = mergedSchema.allOf || [];
|
|
4545
|
+
mergedSchema.allOf.push(...allITE);
|
|
4546
|
+
}
|
|
4464
4547
|
}
|
|
4465
4548
|
return mergedSchema;
|
|
4466
4549
|
}
|
|
@@ -4485,6 +4568,65 @@ function fixRequiredArrayProperties(schema) {
|
|
|
4485
4568
|
}
|
|
4486
4569
|
}
|
|
4487
4570
|
return schema;
|
|
4571
|
+
}
|
|
4572
|
+
/**
|
|
4573
|
+
* 'convertJSONSchemaIfToCondition' function
|
|
4574
|
+
* converts something like
|
|
4575
|
+
* "if": {
|
|
4576
|
+
* "properties": {
|
|
4577
|
+
* "animal": {
|
|
4578
|
+
* "const": "Cat"
|
|
4579
|
+
* },
|
|
4580
|
+
* "habitat":{
|
|
4581
|
+
* "const": "City"
|
|
4582
|
+
* }
|
|
4583
|
+
* }
|
|
4584
|
+
* }
|
|
4585
|
+
* to "model.animal=='Cat' && habitat=='City" contion
|
|
4586
|
+
* @param schema:any
|
|
4587
|
+
* @param negate:boolean=false
|
|
4588
|
+
* @returns
|
|
4589
|
+
|
|
4590
|
+
*/
|
|
4591
|
+
function convertJSONSchemaIfToCondition(schema, layoutNode, negate = false) {
|
|
4592
|
+
let conditionFun = "";
|
|
4593
|
+
let condition = {};
|
|
4594
|
+
let notOp = negate ? "!" : "";
|
|
4595
|
+
// expects "dataPointer" to be like "/a/b/c"
|
|
4596
|
+
//TODO-test
|
|
4597
|
+
//dataPointer can be something like /cities/-/name
|
|
4598
|
+
//must end up like model.cities[arrayIndices].name
|
|
4599
|
+
//also check can possibly be nested array like /cities/-/sites/-/siteName
|
|
4600
|
+
//in this case must probably end up like
|
|
4601
|
+
// /cities/arrayIndices[0]/sites/arrayIndices[1]/siteName
|
|
4602
|
+
//but it seems evaluatCondition support only one level for now
|
|
4603
|
+
//and uses arrayIndices as the last index only -check?
|
|
4604
|
+
let parentPath = layoutNode.dataPointer ? layoutNode.dataPointer
|
|
4605
|
+
.split("/")
|
|
4606
|
+
.slice(1, -1)
|
|
4607
|
+
.map((part, ind) => {
|
|
4608
|
+
let sep = ind == 0 ? "" : ".";
|
|
4609
|
+
let ret = part == "-" ? "[arrayIndices]" : sep + part;
|
|
4610
|
+
return ret;
|
|
4611
|
+
})
|
|
4612
|
+
.join("")
|
|
4613
|
+
: "";
|
|
4614
|
+
let modelPath = parentPath ? `model.${parentPath}` : "model";
|
|
4615
|
+
let checkPath = modelPath.split(".")
|
|
4616
|
+
.reduce((accumulator, currentPart, index) => {
|
|
4617
|
+
const currentExpression = index === 0 ? currentPart : `${accumulator}.${currentPart}`;
|
|
4618
|
+
return index === 0 ? currentExpression : `${accumulator} && ${currentExpression}`;
|
|
4619
|
+
}, '');
|
|
4620
|
+
if (schema.if) {
|
|
4621
|
+
Object.keys(schema.if.properties).forEach((ifProp, ind) => {
|
|
4622
|
+
let amper = ind > 0 ? "&" : "";
|
|
4623
|
+
//Note the model value is first converted to string and so is the condition
|
|
4624
|
+
//so that booleans and numbers can also be compared
|
|
4625
|
+
conditionFun += `${amper} ${checkPath} && ${modelPath}.${ifProp}+""=='${schema.if.properties[ifProp].const}'`;
|
|
4626
|
+
});
|
|
4627
|
+
}
|
|
4628
|
+
condition["functionBody"] = `return ${notOp}(${conditionFun})`;
|
|
4629
|
+
return condition;
|
|
4488
4630
|
}
|
|
4489
4631
|
|
|
4490
4632
|
function convertSchemaToDraft6(schema, options = {}) {
|
|
@@ -4786,6 +4928,17 @@ function convertSchemaToDraft6(schema, options = {}) {
|
|
|
4786
4928
|
return newSchema;
|
|
4787
4929
|
}
|
|
4788
4930
|
|
|
4931
|
+
/**
|
|
4932
|
+
* path2ControlKey takes a datapointer path like /some/pointer/path
|
|
4933
|
+
* and returns something like $some$pointer$path
|
|
4934
|
+
* used mainly to convert paths so it can be used as keys in FormGroups
|
|
4935
|
+
* fot ITE scenarios
|
|
4936
|
+
* @param path
|
|
4937
|
+
* @returns string
|
|
4938
|
+
*/
|
|
4939
|
+
function path2ControlKey(path) {
|
|
4940
|
+
return path.replace(/\//g, "$");
|
|
4941
|
+
}
|
|
4789
4942
|
/**
|
|
4790
4943
|
* FormGroup function library:
|
|
4791
4944
|
*
|
|
@@ -4834,11 +4987,13 @@ function buildFormGroupTemplate(jsf, nodeValue = null, setValues = true, schemaP
|
|
|
4834
4987
|
}
|
|
4835
4988
|
// TODO: If nodeValue still not set, check layout for default value
|
|
4836
4989
|
const schemaType = JsonPointer.get(schema, '/type');
|
|
4837
|
-
const
|
|
4838
|
-
|
|
4839
|
-
(hasOwn(schema, '
|
|
4840
|
-
schemaType === '
|
|
4841
|
-
|
|
4990
|
+
const isIfThenElse = hasOwn(schema, 'if') || hasOwn(schema, 'then') || hasOwn(schema, 'else');
|
|
4991
|
+
const controlType = isIfThenElse && !schemaType ? 'IfThenElse' :
|
|
4992
|
+
(hasOwn(schema, 'properties') || hasOwn(schema, 'additionalProperties')) &&
|
|
4993
|
+
schemaType === 'object' ? 'FormGroup' :
|
|
4994
|
+
(hasOwn(schema, 'items') || hasOwn(schema, 'additionalItems')) &&
|
|
4995
|
+
schemaType === 'array' ? 'FormArray' :
|
|
4996
|
+
!schemaType && hasOwn(schema, '$ref') ? '$ref' : 'FormControl';
|
|
4842
4997
|
const shortDataPointer = removeRecursiveReferences(dataPointer, jsf.dataRecursiveRefMap, jsf.arrayMap);
|
|
4843
4998
|
if (!jsf.dataMap.has(shortDataPointer)) {
|
|
4844
4999
|
jsf.dataMap.set(shortDataPointer, new Map());
|
|
@@ -4877,11 +5032,175 @@ function buildFormGroupTemplate(jsf, nodeValue = null, setValues = true, schemaP
|
|
|
4877
5032
|
propertyKeys
|
|
4878
5033
|
.filter(key => hasOwn(schema.properties, key) ||
|
|
4879
5034
|
hasOwn(schema, 'additionalProperties'))
|
|
4880
|
-
.forEach(key =>
|
|
4881
|
-
|
|
5035
|
+
.forEach(key => {
|
|
5036
|
+
controls[key] = buildFormGroupTemplate(jsf, JsonPointer.get(nodeValue, [key]), setValues, schemaPointer + (hasOwn(schema.properties, key) ?
|
|
5037
|
+
'/properties/' + key : '/additionalProperties'), dataPointer + '/' + key, templatePointer + '/controls/' + key);
|
|
5038
|
+
//add the $<control> type to the root
|
|
5039
|
+
//so it can be flattened and acceses directly in the formgroup
|
|
5040
|
+
//by its full '$' path
|
|
5041
|
+
["allOf", "anyOf", "oneOf"].forEach(ofType => {
|
|
5042
|
+
if (controls[key].controls && controls[key].controls[`_${ofType}`]) {
|
|
5043
|
+
Object.keys(controls[key].controls[`_${ofType}`]).forEach($key => {
|
|
5044
|
+
controls[$key] = controls[key].controls[`_${ofType}`][$key];
|
|
5045
|
+
delete controls[key].controls[$key];
|
|
5046
|
+
});
|
|
5047
|
+
delete controls[key].controls[`_${ofType}`];
|
|
5048
|
+
}
|
|
5049
|
+
});
|
|
5050
|
+
});
|
|
5051
|
+
if (hasOwn(schema, "if")) {
|
|
5052
|
+
["then", "else"].forEach(con => {
|
|
5053
|
+
if (hasOwn(schema, con)) {
|
|
5054
|
+
const keySchemaPointer = `/${con}`;
|
|
5055
|
+
let thenFGTemplate = buildFormGroupTemplate(jsf, nodeValue, false, //JsonPointer.get(nodeValue, keySchemaPointer), setValues,
|
|
5056
|
+
schemaPointer + keySchemaPointer, dataPointer, templatePointer + `/controls/${con}`);
|
|
5057
|
+
Object.assign(controls, thenFGTemplate.controls);
|
|
5058
|
+
}
|
|
5059
|
+
});
|
|
5060
|
+
}
|
|
5061
|
+
/* treat allOf the same as any of but need to add an extra
|
|
5062
|
+
condition for which anyOf item is to be rendered
|
|
5063
|
+
let allOfControls = {}
|
|
5064
|
+
let allOfAllowedKeys = ["allOf", "anyOf", "oneOf", "if", "then", "else", "type", "properties", "items"];
|
|
5065
|
+
if (hasOwn(schema, "allOf") && isArray(schema.allOf)) {
|
|
5066
|
+
schema.allOf.forEach((allOfItem, ind) => {
|
|
5067
|
+
let aoItemKeys = Object.keys(allOfItem);
|
|
5068
|
+
let foundKeys = allOfAllowedKeys.filter(value =>
|
|
5069
|
+
aoItemKeys.includes(value)
|
|
5070
|
+
);
|
|
5071
|
+
if (foundKeys && foundKeys.length > 0) {
|
|
5072
|
+
const keySchemaPointer = `/allOf/${ind}`;
|
|
5073
|
+
//console.log(`found:${keySchemaPointer}`);
|
|
5074
|
+
let allOfFGTemplate = buildFormGroupTemplate(
|
|
5075
|
+
jsf, JsonPointer.get(nodeValue, keySchemaPointer), setValues,
|
|
5076
|
+
schemaPointer + keySchemaPointer,
|
|
5077
|
+
dataPointer,
|
|
5078
|
+
templatePointer + '/controls/' + ind
|
|
5079
|
+
);
|
|
5080
|
+
if (allOfFGTemplate.controls) {
|
|
5081
|
+
Object.keys(allOfFGTemplate.controls).forEach(key => {
|
|
5082
|
+
let controlKey = allOfFGTemplate.controls[key].schemaPointer || `${schemaPointer}${keySchemaPointer}/${key}`;
|
|
5083
|
+
controlKey = path2ControlKey(controlKey);
|
|
5084
|
+
controls[controlKey] = {
|
|
5085
|
+
key: key,
|
|
5086
|
+
schemaPointer: schemaPointer + keySchemaPointer,
|
|
5087
|
+
controls: allOfFGTemplate.controls[key]
|
|
5088
|
+
}
|
|
5089
|
+
controls[controlKey] = allOfFGTemplate.controls[key];
|
|
5090
|
+
controls[controlKey].key = key;
|
|
5091
|
+
controls[controlKey].schemaPointer = allOfFGTemplate.controls[key].schemaPointer || schemaPointer + keySchemaPointer;
|
|
5092
|
+
|
|
5093
|
+
controls[key] = allOfFGTemplate.controls[key];
|
|
5094
|
+
})
|
|
5095
|
+
}
|
|
5096
|
+
//add ui type items to controls
|
|
5097
|
+
if (allOfItem["type"] || allOfItem["properties"] || allOfItem["items"]) {
|
|
5098
|
+
allOfControls[ind] = allOfFGTemplate
|
|
5099
|
+
}
|
|
5100
|
+
|
|
5101
|
+
}
|
|
5102
|
+
|
|
5103
|
+
})
|
|
5104
|
+
controls["allOf"] = allOfControls;
|
|
5105
|
+
}
|
|
5106
|
+
*/
|
|
5107
|
+
let ofAllowedKeys = ["allOf", "anyOf", "oneOf", "if", "then", "else", "type", "properties", "items"];
|
|
5108
|
+
["allOf", "anyOf", "oneOf"].forEach(ofType => {
|
|
5109
|
+
if (hasOwn(schema, ofType) && isArray(schema[ofType])) {
|
|
5110
|
+
schema[ofType].forEach((ofItem, ind) => {
|
|
5111
|
+
let aoItemKeys = Object.keys(ofItem);
|
|
5112
|
+
let foundKeys = ofAllowedKeys.filter(value => aoItemKeys.includes(value));
|
|
5113
|
+
if (foundKeys && foundKeys.length > 0) {
|
|
5114
|
+
const keySchemaPointer = `/${ofType}/${ind}`;
|
|
5115
|
+
//console.log(`found:${keySchemaPointer}`);
|
|
5116
|
+
let newNodeValue = JsonPointer.get(nodeValue, dataPointer);
|
|
5117
|
+
//JsonPointer.get(nodeValue, keySchemaPointer);
|
|
5118
|
+
if (ofType == "oneOf") {
|
|
5119
|
+
newNodeValue = nodeValue;
|
|
5120
|
+
}
|
|
5121
|
+
let allOfFGTemplate = buildFormGroupTemplate(jsf, newNodeValue, setValues, schemaPointer + keySchemaPointer, dataPointer, templatePointer + '/controls/' + ind);
|
|
5122
|
+
if (allOfFGTemplate.controls) {
|
|
5123
|
+
Object.keys(allOfFGTemplate.controls).forEach(key => {
|
|
5124
|
+
const l2SchemaPointer = hasOwn(schema, 'properties') ?
|
|
5125
|
+
'/properties/' + key : key;
|
|
5126
|
+
let controlKey = allOfFGTemplate.controls[key].schemaPointer || `${schemaPointer}${keySchemaPointer}${l2SchemaPointer}`;
|
|
5127
|
+
controlKey = path2ControlKey(controlKey);
|
|
5128
|
+
/*
|
|
5129
|
+
controls[controlKey] = {
|
|
5130
|
+
key: key,
|
|
5131
|
+
schemaPointer: `${schemaPointer}${keySchemaPointer}/${key}`,//schemaPointer + keySchemaPointer,
|
|
5132
|
+
controls: allOfFGTemplate.controls[key]
|
|
5133
|
+
}
|
|
5134
|
+
*/
|
|
5135
|
+
let controlItem = cloneDeep(allOfFGTemplate.controls[key]);
|
|
5136
|
+
controlItem.key = key;
|
|
5137
|
+
controlItem.schemaPointer = controlItem.schemaPointer || `${schemaPointer}${keySchemaPointer}${l2SchemaPointer}`;
|
|
5138
|
+
controls[controlKey] = controlItem;
|
|
5139
|
+
//need to test if value matches schema,
|
|
5140
|
+
//as the same oneOf item will be assigned to the same value
|
|
5141
|
+
//if key is a $oneOf key then it was inserted at the root of the controls
|
|
5142
|
+
//as form control name will be the full(escaped) path
|
|
5143
|
+
const pointerPath = key.startsWith('$oneOf') ? controlItem.schemaPointer : keySchemaPointer;
|
|
5144
|
+
let oneOfItemSchema = JsonPointer.get(jsf.schema, controlItem.schemaPointer);
|
|
5145
|
+
//JsonPointer.get(schema,pointerPath);
|
|
5146
|
+
let dPointer = controlItem.schemaPointer.replace(/(anyOf|allOf|oneOf|none)\/[\d]+\//g, '')
|
|
5147
|
+
.replace(/(if|then|else|properties)\//g, '');
|
|
5148
|
+
//JsonPointer.toDataPointer(controlItem.schemaPointer,jsf.schema);
|
|
5149
|
+
let dVal = JsonPointer.get(nodeValue, dPointer);
|
|
5150
|
+
let fkey = key;
|
|
5151
|
+
let oneOfItemValue = dVal;
|
|
5152
|
+
/*
|
|
5153
|
+
if(hasOwn(oneOfItemSchema,"if") && controlItem.schemaPointer
|
|
5154
|
+
&& controlItem.schemaPointer.indexOf(keySchemaPointer)==0){
|
|
5155
|
+
let parts=controlItem.schemaPointer
|
|
5156
|
+
.split(keySchemaPointer).join('').split("/")
|
|
5157
|
+
let thenOrElse=parts[1];
|
|
5158
|
+
fkey=parts[parts.length-1];
|
|
5159
|
+
oneOfItemSchema=oneOfItemSchema[thenOrElse];
|
|
5160
|
+
}
|
|
5161
|
+
|
|
5162
|
+
if(oneOfItemSchema.properties && jsf.formValues===undefined){
|
|
5163
|
+
//check if no form data values were supplied
|
|
5164
|
+
//then set it to default otherwise to its nodevalue
|
|
5165
|
+
oneOfItemValue=oneOfItemSchema.default
|
|
5166
|
+
oneOfItemValue[fkey]=oneOfItemSchema.properties[fkey]?.default;
|
|
5167
|
+
}
|
|
5168
|
+
if(oneOfItemSchema.properties && jsf.formValues!=undefined){
|
|
5169
|
+
oneOfItemValue ={};
|
|
5170
|
+
//nodeValue||{};
|
|
5171
|
+
oneOfItemValue[fkey]=nodeValue&&nodeValue[fkey];
|
|
5172
|
+
}
|
|
5173
|
+
if(!oneOfItemSchema.properties && jsf.formValues==undefined){
|
|
5174
|
+
oneOfItemValue=oneOfItemSchema.default;
|
|
5175
|
+
}
|
|
5176
|
+
*/
|
|
5177
|
+
if (hasOwn(controlItem, "value")) {
|
|
5178
|
+
if (!jsf.ajv.validate(oneOfItemSchema, oneOfItemValue)) {
|
|
5179
|
+
controlItem.value.value = null;
|
|
5180
|
+
}
|
|
5181
|
+
else {
|
|
5182
|
+
///controlItem.value.value=oneOfItemValue[fkey];
|
|
5183
|
+
controlItem.value.value = oneOfItemSchema.properties ? oneOfItemValue[fkey] : oneOfItemValue;
|
|
5184
|
+
}
|
|
5185
|
+
}
|
|
5186
|
+
//controls[controlKey] = controlItem;
|
|
5187
|
+
//allOfFGTemplate.controls[key].schemaPointer ||`${schemaPointer}${keySchemaPointer}/${key}`;
|
|
5188
|
+
//allOfFGTemplate.controls[key].schemaPointer || schemaPointer + keySchemaPointer;
|
|
5189
|
+
///////controls[key] = cloneDeep(allOfFGTemplate.controls[key]);
|
|
5190
|
+
//add schemacontrol to root
|
|
5191
|
+
//controls[controlKey]=controlItem
|
|
5192
|
+
controls[`_${ofType}`] = controls[`_${ofType}`] || {};
|
|
5193
|
+
controls[`_${ofType}`][controlKey] = controlItem;
|
|
5194
|
+
//allOfFGTemplate.controls[key];
|
|
5195
|
+
});
|
|
5196
|
+
}
|
|
5197
|
+
}
|
|
5198
|
+
});
|
|
5199
|
+
}
|
|
5200
|
+
});
|
|
4882
5201
|
jsf.formOptions.fieldsRequired = setRequiredFields(schema, controls);
|
|
4883
5202
|
}
|
|
4884
|
-
return { controlType, controls, validators };
|
|
5203
|
+
return { controlType, controls, validators, schemaPointer };
|
|
4885
5204
|
case 'FormArray':
|
|
4886
5205
|
controls = [];
|
|
4887
5206
|
const minItems = Math.max(schema.minItems || 0, nodeOptions.get('minItems') || 0);
|
|
@@ -4938,7 +5257,7 @@ function buildFormGroupTemplate(jsf, nodeValue = null, setValues = true, schemaP
|
|
|
4938
5257
|
}
|
|
4939
5258
|
}
|
|
4940
5259
|
}
|
|
4941
|
-
return { controlType, controls, validators };
|
|
5260
|
+
return { controlType, controls, validators, schemaPointer };
|
|
4942
5261
|
case '$ref':
|
|
4943
5262
|
const schemaRef = JsonPointer.compile(schema.$ref);
|
|
4944
5263
|
const dataRef = JsonPointer.toDataPointer(schemaRef, schema);
|
|
@@ -4960,7 +5279,57 @@ function buildFormGroupTemplate(jsf, nodeValue = null, setValues = true, schemaP
|
|
|
4960
5279
|
value: setValues && isPrimitive(nodeValue) ? nodeValue : null,
|
|
4961
5280
|
disabled: nodeOptions.get('disabled') || false
|
|
4962
5281
|
};
|
|
4963
|
-
return { controlType, value, validators };
|
|
5282
|
+
return { controlType, value, validators, schemaPointer };
|
|
5283
|
+
//TODO may make an IFThenElse widget or integrate it with the section
|
|
5284
|
+
//widget
|
|
5285
|
+
case 'IfThenElse':
|
|
5286
|
+
controls = {};
|
|
5287
|
+
let conditionType;
|
|
5288
|
+
if (hasOwn(schema, "if")) {
|
|
5289
|
+
["then", "else"].forEach(con => {
|
|
5290
|
+
if (hasOwn(schema, con)) {
|
|
5291
|
+
const keySchemaPointer = `/${con}`;
|
|
5292
|
+
let thenTFGTemplate = buildFormGroupTemplate(jsf, nodeValue, false, schemaPointer + keySchemaPointer, dataPointer, templatePointer + `/controls/${con}`);
|
|
5293
|
+
//NB same property can be in both then and else
|
|
5294
|
+
//so key must be the unique path to control
|
|
5295
|
+
//let ifItemSchema=JsonPointer.get(schema,keySchemaPointer);
|
|
5296
|
+
//let ifItemValue;
|
|
5297
|
+
Object.keys(thenTFGTemplate.controls).forEach(key => {
|
|
5298
|
+
let controlKey = thenTFGTemplate.controls[key].schemaPointer;
|
|
5299
|
+
////let controlItem=cloneDeep(thenTFGTemplate.controls[key]);
|
|
5300
|
+
////thenTFGTemplate.controls[key].schemaPointer || `${schemaPointer}${keySchemaPointer}/${key}`;
|
|
5301
|
+
controlKey = path2ControlKey(controlKey);
|
|
5302
|
+
let cItem = Object.assign({}, thenTFGTemplate.controls[key]);
|
|
5303
|
+
////cItem.schemaPointer = `${schemaPointer}${keySchemaPointer}/${key}`;
|
|
5304
|
+
/*
|
|
5305
|
+
if(ifItemSchema.properties && jsf.formValues===undefined){
|
|
5306
|
+
//check if no form data values were supplied
|
|
5307
|
+
//then set it to default otherwise to its nodevalue
|
|
5308
|
+
ifItemValue=ifItemSchema.default
|
|
5309
|
+
ifItemValue[key]=ifItemSchema.properties[key]?.default;
|
|
5310
|
+
}
|
|
5311
|
+
if(ifItemSchema.properties && jsf.formValues!=undefined){
|
|
5312
|
+
ifItemValue ={};
|
|
5313
|
+
//nodeValue||{};
|
|
5314
|
+
ifItemValue[key]=nodeValue&&nodeValue[key];
|
|
5315
|
+
}
|
|
5316
|
+
if(!ifItemSchema.properties && jsf.formValues==undefined){
|
|
5317
|
+
ifItemValue=ifItemSchema.default;
|
|
5318
|
+
}
|
|
5319
|
+
if(hasOwn(cItem,"value")){
|
|
5320
|
+
if(!jsf.ajv.validate(ifItemSchema,ifItemValue)){
|
|
5321
|
+
cItem.value.value=null;
|
|
5322
|
+
}else{
|
|
5323
|
+
cItem.value.value=ifItemValue[key];
|
|
5324
|
+
}
|
|
5325
|
+
}
|
|
5326
|
+
*/
|
|
5327
|
+
controls[controlKey] = cItem;
|
|
5328
|
+
});
|
|
5329
|
+
}
|
|
5330
|
+
});
|
|
5331
|
+
}
|
|
5332
|
+
return { controlType, controls, validators, schemaPointer };
|
|
4964
5333
|
default:
|
|
4965
5334
|
return null;
|
|
4966
5335
|
}
|
|
@@ -4992,7 +5361,23 @@ function buildFormGroup(template) {
|
|
|
4992
5361
|
const groupControls = {};
|
|
4993
5362
|
forEach(template.controls, (controls, key) => {
|
|
4994
5363
|
const newControl = buildFormGroup(controls);
|
|
5364
|
+
//if (newControl) { groupControls[key] = newControl; }
|
|
4995
5365
|
if (newControl) {
|
|
5366
|
+
/* experimental idea was to try to be able to switch
|
|
5367
|
+
conditional controls dynamically based on their schema pointer
|
|
5368
|
+
(not datapointer as that only maps to one control)
|
|
5369
|
+
Object.defineProperty(groupControls, key, {
|
|
5370
|
+
get: () => {
|
|
5371
|
+
//console.log(`Accessed control: ${key}`);
|
|
5372
|
+
//add switch logic here
|
|
5373
|
+
return ncontrol;
|
|
5374
|
+
},
|
|
5375
|
+
set:(value)=>{
|
|
5376
|
+
ncontrol=value
|
|
5377
|
+
},
|
|
5378
|
+
enumerable: true
|
|
5379
|
+
})
|
|
5380
|
+
*/
|
|
4996
5381
|
groupControls[key] = newControl;
|
|
4997
5382
|
}
|
|
4998
5383
|
});
|
|
@@ -5142,6 +5527,9 @@ function formatFormData(formData, dataMap, recursiveRefMap, arrayMap, returnEmpt
|
|
|
5142
5527
|
}
|
|
5143
5528
|
else if (typeof value !== 'object' || isDate(value) ||
|
|
5144
5529
|
(value === null && returnEmptyFields)) {
|
|
5530
|
+
if (genericPointer.indexOf("/$") >= 0) {
|
|
5531
|
+
return formattedData;
|
|
5532
|
+
}
|
|
5145
5533
|
console.error('formatFormData error: ' +
|
|
5146
5534
|
`Schema type not found for form value at ${genericPointer}`);
|
|
5147
5535
|
console.error('dataMap', dataMap);
|
|
@@ -5166,14 +5554,15 @@ function formatFormData(formData, dataMap, recursiveRefMap, arrayMap, returnEmpt
|
|
|
5166
5554
|
* // {Pointer} dataPointer - JSON Pointer (string or array)
|
|
5167
5555
|
* // {boolean = false} returnGroup - If true, return group containing control
|
|
5168
5556
|
* // {group} - Located value (or null, if no control found)
|
|
5557
|
+
* // {string} schemaPointer - string used for conditional controls coming from schema if/then/else
|
|
5169
5558
|
*/
|
|
5170
|
-
function getControl(formGroup, dataPointer, returnGroup = false) {
|
|
5559
|
+
function getControl(formGroup, dataPointer, returnGroup = false, schemaPointer) {
|
|
5171
5560
|
if (!isObject(formGroup) || !JsonPointer.isJsonPointer(dataPointer)) {
|
|
5172
5561
|
if (!JsonPointer.isJsonPointer(dataPointer)) {
|
|
5173
5562
|
// If dataPointer input is not a valid JSON pointer, check to
|
|
5174
5563
|
// see if it is instead a valid object path, using dot notaion
|
|
5175
5564
|
if (typeof dataPointer === 'string') {
|
|
5176
|
-
const formControl = formGroup.get(dataPointer);
|
|
5565
|
+
const formControl = formGroup.get(path2ControlKey(schemaPointer || "")) || formGroup.get(dataPointer);
|
|
5177
5566
|
if (formControl) {
|
|
5178
5567
|
return formControl;
|
|
5179
5568
|
}
|
|
@@ -5193,7 +5582,7 @@ function getControl(formGroup, dataPointer, returnGroup = false) {
|
|
|
5193
5582
|
// try using formGroup.get() to return the control
|
|
5194
5583
|
if (typeof formGroup.get === 'function' &&
|
|
5195
5584
|
dataPointerArray.every(key => key.indexOf('.') === -1)) {
|
|
5196
|
-
const formControl = formGroup.get(dataPointerArray.join('.'));
|
|
5585
|
+
const formControl = formGroup.get(path2ControlKey(schemaPointer || "")) || formGroup.get(dataPointerArray.join('.'));
|
|
5197
5586
|
if (formControl) {
|
|
5198
5587
|
return formControl;
|
|
5199
5588
|
}
|
|
@@ -5212,6 +5601,9 @@ function getControl(formGroup, dataPointer, returnGroup = false) {
|
|
|
5212
5601
|
else if (hasOwn(subGroup, key)) {
|
|
5213
5602
|
subGroup = subGroup[key];
|
|
5214
5603
|
}
|
|
5604
|
+
else if (schemaPointer && hasOwn(subGroup, path2ControlKey(schemaPointer))) {
|
|
5605
|
+
subGroup = subGroup[path2ControlKey(schemaPointer)];
|
|
5606
|
+
}
|
|
5215
5607
|
else {
|
|
5216
5608
|
console.error(`getControl error: Unable to find "${key}" item in FormGroup.`);
|
|
5217
5609
|
console.error(dataPointer);
|
|
@@ -5220,6 +5612,68 @@ function getControl(formGroup, dataPointer, returnGroup = false) {
|
|
|
5220
5612
|
}
|
|
5221
5613
|
}
|
|
5222
5614
|
return subGroup;
|
|
5615
|
+
}
|
|
5616
|
+
/**
|
|
5617
|
+
* 'setControl' function
|
|
5618
|
+
*
|
|
5619
|
+
* Uses a JSON Pointer for a data object to retrieve a control from
|
|
5620
|
+
* an Angular formGroup or formGroup template. (Note: though a formGroup
|
|
5621
|
+
* template is much simpler, its basic structure is idential to a formGroup).
|
|
5622
|
+
*
|
|
5623
|
+
* If the optional third parameter 'returnGroup' is set to TRUE, the group
|
|
5624
|
+
* containing the control is returned, rather than the control itself.
|
|
5625
|
+
*
|
|
5626
|
+
* // {FormGroup} formGroup - Angular FormGroup to get value from
|
|
5627
|
+
* // {Pointer} dataPointer - JSON Pointer (string or array)
|
|
5628
|
+
* // {AbstractControl} control - control used to replace existing or add
|
|
5629
|
+
* // {targetKey} - optional string used as the new key-not implemented as yet
|
|
5630
|
+
*/
|
|
5631
|
+
function setControl(formGroup, dataPointer, control, targetKey) {
|
|
5632
|
+
let dataPointerArray = JsonPointer.parse(dataPointer);
|
|
5633
|
+
// If formGroup input is a real formGroup (not a formGroup template)
|
|
5634
|
+
// try using formGroup.get() to return the control
|
|
5635
|
+
/*
|
|
5636
|
+
if (typeof formGroup.get === 'function' &&
|
|
5637
|
+
dataPointerArray.every(key => key.indexOf('.') === -1)
|
|
5638
|
+
) {
|
|
5639
|
+
formGroup.setControl(dataPointerArray.join('.'), control);
|
|
5640
|
+
return;
|
|
5641
|
+
}
|
|
5642
|
+
*/
|
|
5643
|
+
let currentGroup = formGroup;
|
|
5644
|
+
for (let i = 0; i < dataPointerArray.length - 1; i++) {
|
|
5645
|
+
// Navigate down the form structure to find the correct nested FormGroup
|
|
5646
|
+
currentGroup = currentGroup.get(dataPointerArray[i]);
|
|
5647
|
+
// If it's not a FormGroup, we throw an error since we can't set a control in a non-group.
|
|
5648
|
+
if (!(typeof currentGroup.setControl === 'function')) {
|
|
5649
|
+
throw new Error(`Path '${dataPointerArray[i]}' is not a valid FormGroup or FormArray.`);
|
|
5650
|
+
}
|
|
5651
|
+
}
|
|
5652
|
+
// Now we are at the parent FormGroup, set the control at the last part of the path
|
|
5653
|
+
const lastPart = dataPointerArray[dataPointerArray.length - 1];
|
|
5654
|
+
// Set the control at the final path (like 'name' inside 'state')
|
|
5655
|
+
currentGroup.setControl(lastPart, control);
|
|
5656
|
+
// If formGroup input is a formGroup template,
|
|
5657
|
+
// or formGroup.get() failed to return the control,
|
|
5658
|
+
// search the formGroup object for dataPointer's control
|
|
5659
|
+
//TODO needs to be adapted to setControl
|
|
5660
|
+
/*
|
|
5661
|
+
let subGroup = formGroup;
|
|
5662
|
+
for (const key of dataPointerArray) {
|
|
5663
|
+
if (hasOwn(subGroup, 'controls')) { subGroup = subGroup.controls; }
|
|
5664
|
+
if (isArray(subGroup) && (key === '-')) {
|
|
5665
|
+
subGroup = subGroup[subGroup.length - 1];
|
|
5666
|
+
} else if (hasOwn(subGroup, key)) {
|
|
5667
|
+
subGroup = subGroup[key];
|
|
5668
|
+
} else {
|
|
5669
|
+
console.error(`getControl error: Unable to find "${key}" item in FormGroup.`);
|
|
5670
|
+
console.error(dataPointer);
|
|
5671
|
+
console.error(formGroup);
|
|
5672
|
+
return;
|
|
5673
|
+
}
|
|
5674
|
+
}
|
|
5675
|
+
return subGroup;
|
|
5676
|
+
*/
|
|
5223
5677
|
}
|
|
5224
5678
|
|
|
5225
5679
|
/**
|
|
@@ -5390,7 +5844,6 @@ function buildLayout_original(jsf, widgetLibrary) {
|
|
|
5390
5844
|
schemaPointer = JsonPointer.toSchemaPointer(shortDataPointer, jsf.schema);
|
|
5391
5845
|
nodeDataMap.set('schemaPointer', schemaPointer);
|
|
5392
5846
|
}
|
|
5393
|
-
nodeDataMap.set('disabled', !!newNode.options.disabled);
|
|
5394
5847
|
nodeSchema = JsonPointer.get(jsf.schema, schemaPointer);
|
|
5395
5848
|
if (nodeSchema) {
|
|
5396
5849
|
if (!hasOwn(newNode, 'type')) {
|
|
@@ -5411,6 +5864,7 @@ function buildLayout_original(jsf, widgetLibrary) {
|
|
|
5411
5864
|
newNode.dataType =
|
|
5412
5865
|
nodeSchema.type || (hasOwn(nodeSchema, '$ref') ? '$ref' : null);
|
|
5413
5866
|
updateInputOptions(newNode, nodeSchema, jsf);
|
|
5867
|
+
nodeDataMap.set('disabled', !!newNode.options.disabled);
|
|
5414
5868
|
// Present checkboxes as single control, rather than array
|
|
5415
5869
|
if (newNode.type === 'checkboxes' && hasOwn(nodeSchema, 'items')) {
|
|
5416
5870
|
updateInputOptions(newNode, nodeSchema.items, jsf);
|
|
@@ -5833,16 +6287,50 @@ function fixNestedArrayLayout(options) {
|
|
|
5833
6287
|
* // { string = '' } dataPointerPrefix -
|
|
5834
6288
|
* //
|
|
5835
6289
|
*/
|
|
5836
|
-
function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPointer = '', dataPointer = '', arrayItem = false, arrayItemType = null, removable = null, forRefLibrary = false, dataPointerPrefix = '') {
|
|
5837
|
-
|
|
6290
|
+
function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPointer = '', dataPointer = '', arrayItem = false, arrayItemType = null, removable = null, forRefLibrary = false, dataPointerPrefix = '', jsonSchema) {
|
|
6291
|
+
function applyITEConditions(builtLayout, schPointer, keySchemaPointer, negateClause, parentLayout) {
|
|
6292
|
+
if (builtLayout) {
|
|
6293
|
+
if (parentLayout && parentLayout.isITEItem && parentLayout.options.condition) {
|
|
6294
|
+
return;
|
|
6295
|
+
}
|
|
6296
|
+
if (isArray(builtLayout)) {
|
|
6297
|
+
builtLayout.forEach(item => {
|
|
6298
|
+
item.isITEItem = true;
|
|
6299
|
+
item.options.condition = convertJSONSchemaIfToCondition(schema, item, negateClause);
|
|
6300
|
+
applyITEConditions(item, schPointer, keySchemaPointer, negateClause, builtLayout);
|
|
6301
|
+
//item.schemaPointer = schPointer + keySchemaPointer + item.dataPointer;
|
|
6302
|
+
//item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6303
|
+
//newSection.push(item);
|
|
6304
|
+
});
|
|
6305
|
+
}
|
|
6306
|
+
else if (hasOwn(builtLayout, "items")) {
|
|
6307
|
+
applyITEConditions(builtLayout.items, schPointer, keySchemaPointer, negateClause, builtLayout);
|
|
6308
|
+
// builtLayout.items.forEach(item => {
|
|
6309
|
+
// item.isITEItem=true;
|
|
6310
|
+
// item.options.condition = convertJSONSchemaIfToCondition(schema,item, negateClause);
|
|
6311
|
+
// applyITEConditions(item,schPointer,keySchemaPointer,negateClause)
|
|
6312
|
+
// });
|
|
6313
|
+
}
|
|
6314
|
+
else {
|
|
6315
|
+
builtLayout.isITEItem = true;
|
|
6316
|
+
//builtLayout.schemaPointer = `${schPointer}${keySchemaPointer}/${builtLayout.name}`;
|
|
6317
|
+
builtLayout.options.condition = convertJSONSchemaIfToCondition(schema, builtLayout, negateClause);
|
|
6318
|
+
//newSection.push(builtLayout)
|
|
6319
|
+
}
|
|
6320
|
+
}
|
|
6321
|
+
}
|
|
6322
|
+
const jsSchema = jsonSchema || jsf.schema;
|
|
6323
|
+
const schema = JsonPointer.get(jsSchema, schemaPointer);
|
|
6324
|
+
//JsonPointer.get(jsf.schema, schemaPointer);
|
|
5838
6325
|
if (!hasOwn(schema, 'type') && !hasOwn(schema, '$ref') &&
|
|
5839
|
-
!hasOwn(schema, 'x-schema-form')
|
|
6326
|
+
!hasOwn(schema, 'x-schema-form')
|
|
6327
|
+
&& !hasOwn(schema, 'if') && !hasOwn(schema, 'then') && !hasOwn(schema, 'else')) {
|
|
5840
6328
|
return null;
|
|
5841
6329
|
}
|
|
5842
6330
|
const newNodeType = getInputType(schema);
|
|
5843
6331
|
if (!isDefined(nodeValue) && (jsf.formOptions.setSchemaDefaults === true ||
|
|
5844
6332
|
(jsf.formOptions.setSchemaDefaults === 'auto' && isEmpty(jsf.formValues)))) {
|
|
5845
|
-
nodeValue = JsonPointer.get(
|
|
6333
|
+
nodeValue = JsonPointer.get(jsSchema, schemaPointer + '/default');
|
|
5846
6334
|
}
|
|
5847
6335
|
let newNode = {
|
|
5848
6336
|
_id: forRefLibrary ? null : uniqueId(),
|
|
@@ -5850,7 +6338,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
5850
6338
|
dataPointer: JsonPointer.toGenericPointer(dataPointer, jsf.arrayMap),
|
|
5851
6339
|
dataType: schema.type || (hasOwn(schema, '$ref') ? '$ref' : null),
|
|
5852
6340
|
options: {},
|
|
5853
|
-
required: isInputRequired(
|
|
6341
|
+
required: isInputRequired(jsSchema, schemaPointer),
|
|
5854
6342
|
type: newNodeType,
|
|
5855
6343
|
widget: widgetLibrary.getWidget(newNodeType),
|
|
5856
6344
|
};
|
|
@@ -5868,6 +6356,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
5868
6356
|
if (!jsf.dataMap.has(shortDataPointer)) {
|
|
5869
6357
|
jsf.dataMap.set(shortDataPointer, new Map());
|
|
5870
6358
|
}
|
|
6359
|
+
updateInputOptions(newNode, schema, jsf);
|
|
5871
6360
|
const nodeDataMap = jsf.dataMap.get(shortDataPointer);
|
|
5872
6361
|
if (!nodeDataMap.has('inputType')) {
|
|
5873
6362
|
nodeDataMap.set('schemaPointer', schemaPointer);
|
|
@@ -5875,7 +6364,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
5875
6364
|
nodeDataMap.set('widget', newNode.widget);
|
|
5876
6365
|
nodeDataMap.set('disabled', !!newNode.options.disabled);
|
|
5877
6366
|
}
|
|
5878
|
-
updateInputOptions(newNode, schema, jsf);
|
|
6367
|
+
//updateInputOptions(newNode, schema, jsf);
|
|
5879
6368
|
if (!newNode.options.title && newNode.name && !/^\d+$/.test(newNode.name)) {
|
|
5880
6369
|
newNode.options.title = fixTitle(newNode.name);
|
|
5881
6370
|
}
|
|
@@ -5903,6 +6392,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
5903
6392
|
'/properties/' + key : '/additionalProperties';
|
|
5904
6393
|
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, isObject(nodeValue) ? nodeValue[key] : null, schemaPointer + keySchemaPointer, dataPointer + '/' + key, false, null, null, forRefLibrary, dataPointerPrefix);
|
|
5905
6394
|
if (innerItem) {
|
|
6395
|
+
innerItem.schemaPointer = schemaPointer + keySchemaPointer;
|
|
5906
6396
|
if (isInputRequired(schema, '/' + key)) {
|
|
5907
6397
|
innerItem.options.required = true;
|
|
5908
6398
|
jsf.fieldsRequired = true;
|
|
@@ -5910,6 +6400,102 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
5910
6400
|
newSection.push(innerItem);
|
|
5911
6401
|
}
|
|
5912
6402
|
});
|
|
6403
|
+
//treat allOf the same as any of but need to add an extra
|
|
6404
|
+
//condition for which anyOf item is to be rendered
|
|
6405
|
+
["allOf", "anyOf", "oneOf"].forEach(ofType => {
|
|
6406
|
+
if (hasOwn(schema, ofType) && isArray(schema[ofType])) {
|
|
6407
|
+
let outerOneOfItem;
|
|
6408
|
+
if (ofType == "oneOf") {
|
|
6409
|
+
outerOneOfItem = buildLayoutFromSchema(jsf, widgetLibrary, schema.oneOf, //{type:"tabarray",items:schema.oneOf},
|
|
6410
|
+
"/", //schemaPointer + `/${ofType}`,
|
|
6411
|
+
dataPointer, false, null, null, forRefLibrary, dataPointerPrefix,
|
|
6412
|
+
//{type:"tabarray",items:schema.oneOf,oneOf:schema.oneOf}
|
|
6413
|
+
{ type: "one-of", items: schema.oneOf, oneOf: schema.oneOf });
|
|
6414
|
+
//outerItem.items=cloneDeep(newSection);
|
|
6415
|
+
//newSection.length=0;
|
|
6416
|
+
newSection.push(outerOneOfItem);
|
|
6417
|
+
}
|
|
6418
|
+
schema[ofType].forEach((ofItem, ind) => {
|
|
6419
|
+
const keySchemaPointer = `/${ofType}/${ind}`;
|
|
6420
|
+
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, ofItem, schemaPointer + keySchemaPointer, dataPointer, false, null, null, ofType == "oneOf" /*forRefLibrary*/, dataPointerPrefix);
|
|
6421
|
+
if (innerItem) {
|
|
6422
|
+
//newSection.push(innerItem);
|
|
6423
|
+
if (innerItem.items) {
|
|
6424
|
+
innerItem.items.forEach(innerItemLevel2 => {
|
|
6425
|
+
const l2SchemaPointer = hasOwn(ofItem, 'properties') ?
|
|
6426
|
+
'/properties/' + innerItemLevel2.name : innerItemLevel2.name;
|
|
6427
|
+
//innerItemLevel2.oneOfPointer = schemaPointer + keySchemaPointer + l2SchemaPointer;
|
|
6428
|
+
// innerItemLevel2.schemaPointer=innerItemLevel2.schemaPointer;
|
|
6429
|
+
innerItemLevel2.oneOfPointer = innerItemLevel2.schemaPointer;
|
|
6430
|
+
});
|
|
6431
|
+
}
|
|
6432
|
+
//TODO review-will never reach here if forRefLibrary==true
|
|
6433
|
+
if (isArray(innerItem)) {
|
|
6434
|
+
let outerOneOfItemTpl = cloneDeep(newNode);
|
|
6435
|
+
outerOneOfItemTpl;
|
|
6436
|
+
innerItem.forEach(item => {
|
|
6437
|
+
const l2SchemaPointer = hasOwn(ofItem, 'properties') ?
|
|
6438
|
+
'/properties/' + item.name : item.name;
|
|
6439
|
+
if (outerOneOfItem) {
|
|
6440
|
+
////item.oneOfPointer = schemaPointer + keySchemaPointer + l2SchemaPointer;
|
|
6441
|
+
//schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6442
|
+
////item.schemaPointer=item.oneOfPointer;
|
|
6443
|
+
/*
|
|
6444
|
+
outerOneOfItem.items=outerOneOfItem.items||[];
|
|
6445
|
+
outerOneOfItem.items.push(item);
|
|
6446
|
+
*/
|
|
6447
|
+
outerOneOfItemTpl.items = outerOneOfItemTpl.items || [];
|
|
6448
|
+
outerOneOfItemTpl.items.push(item);
|
|
6449
|
+
}
|
|
6450
|
+
else {
|
|
6451
|
+
newSection.push(item);
|
|
6452
|
+
}
|
|
6453
|
+
});
|
|
6454
|
+
if (outerOneOfItem) {
|
|
6455
|
+
outerOneOfItem.items = outerOneOfItem.items || [];
|
|
6456
|
+
outerOneOfItem.items.push(outerOneOfItemTpl);
|
|
6457
|
+
}
|
|
6458
|
+
//TODO test-might not work for more than 2 levels of nesting
|
|
6459
|
+
}
|
|
6460
|
+
else {
|
|
6461
|
+
if (outerOneOfItem) {
|
|
6462
|
+
innerItem.oneOfPointer = schemaPointer + keySchemaPointer; // + innerItem.dataPointer;
|
|
6463
|
+
////innerItem.schemaPointer=innerItem.oneOfPointer;
|
|
6464
|
+
outerOneOfItem.items = outerOneOfItem.items || [];
|
|
6465
|
+
outerOneOfItem.items.push(innerItem);
|
|
6466
|
+
}
|
|
6467
|
+
else {
|
|
6468
|
+
newSection.push(innerItem);
|
|
6469
|
+
}
|
|
6470
|
+
}
|
|
6471
|
+
}
|
|
6472
|
+
});
|
|
6473
|
+
}
|
|
6474
|
+
});
|
|
6475
|
+
if (hasOwn(schema, "if")) {
|
|
6476
|
+
["then", "else"].forEach(con => {
|
|
6477
|
+
if (hasOwn(schema, con)) {
|
|
6478
|
+
const keySchemaPointer = `/${con}`;
|
|
6479
|
+
const negateClause = con == "else";
|
|
6480
|
+
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, nodeValue.then, schemaPointer + keySchemaPointer, dataPointer, false, null, null, forRefLibrary, dataPointerPrefix);
|
|
6481
|
+
if (innerItem) {
|
|
6482
|
+
applyITEConditions(innerItem, schemaPointer, keySchemaPointer, negateClause);
|
|
6483
|
+
if (isArray(innerItem)) {
|
|
6484
|
+
innerItem.forEach(item => {
|
|
6485
|
+
//item.schemaPointer = schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6486
|
+
//item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6487
|
+
newSection.push(item);
|
|
6488
|
+
});
|
|
6489
|
+
}
|
|
6490
|
+
else {
|
|
6491
|
+
//innerItem.schemaPointer = schemaPointer + keySchemaPointer + innerItem.dataPointer;
|
|
6492
|
+
//innerItem.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6493
|
+
newSection.push(innerItem);
|
|
6494
|
+
}
|
|
6495
|
+
}
|
|
6496
|
+
}
|
|
6497
|
+
});
|
|
6498
|
+
}
|
|
5913
6499
|
if (dataPointer === '' && !forRefLibrary) {
|
|
5914
6500
|
newNode = newSection;
|
|
5915
6501
|
}
|
|
@@ -5926,7 +6512,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
5926
6512
|
newNode.items = [];
|
|
5927
6513
|
newNode.options.maxItems = Math.min(schema.maxItems || 1000, newNode.options.maxItems || 1000);
|
|
5928
6514
|
newNode.options.minItems = Math.max(schema.minItems || 0, newNode.options.minItems || 0);
|
|
5929
|
-
if (!newNode.options.minItems && isInputRequired(
|
|
6515
|
+
if (!newNode.options.minItems && isInputRequired(jsSchema, schemaPointer)) {
|
|
5930
6516
|
newNode.options.minItems = 1;
|
|
5931
6517
|
}
|
|
5932
6518
|
if (!hasOwn(newNode.options, 'listItems')) {
|
|
@@ -6059,7 +6645,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6059
6645
|
}
|
|
6060
6646
|
else if (newNode.dataType === '$ref') {
|
|
6061
6647
|
const schemaRef = JsonPointer.compile(schema.$ref);
|
|
6062
|
-
const dataRef = JsonPointer.toDataPointer(schemaRef,
|
|
6648
|
+
const dataRef = JsonPointer.toDataPointer(schemaRef, jsSchema);
|
|
6063
6649
|
let buttonText = '';
|
|
6064
6650
|
// Get newNode title
|
|
6065
6651
|
if (newNode.options.add) {
|
|
@@ -6071,7 +6657,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6071
6657
|
// If newNode doesn't have a title, look for title of parent array item
|
|
6072
6658
|
}
|
|
6073
6659
|
else {
|
|
6074
|
-
const parentSchema = JsonPointer.get(
|
|
6660
|
+
const parentSchema = JsonPointer.get(jsSchema, schemaPointer, 0, -1);
|
|
6075
6661
|
if (hasOwn(parentSchema, 'title')) {
|
|
6076
6662
|
buttonText = 'Add to ' + parentSchema.title;
|
|
6077
6663
|
}
|
|
@@ -6089,9 +6675,9 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6089
6675
|
removable: false,
|
|
6090
6676
|
title: buttonText,
|
|
6091
6677
|
});
|
|
6092
|
-
if (isNumber(JsonPointer.get(
|
|
6678
|
+
if (isNumber(JsonPointer.get(jsSchema, schemaPointer, 0, -1).maxItems)) {
|
|
6093
6679
|
newNode.options.maxItems =
|
|
6094
|
-
JsonPointer.get(
|
|
6680
|
+
JsonPointer.get(jsSchema, schemaPointer, 0, -1).maxItems;
|
|
6095
6681
|
}
|
|
6096
6682
|
// Add layout template to layoutRefLibrary
|
|
6097
6683
|
if (dataRef.length) {
|
|
@@ -6112,6 +6698,32 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6112
6698
|
}
|
|
6113
6699
|
}
|
|
6114
6700
|
}
|
|
6701
|
+
else if (newNode.type === 'if') {
|
|
6702
|
+
const newSection = [];
|
|
6703
|
+
["then", "else"].forEach(con => {
|
|
6704
|
+
if (hasOwn(schema, con)) {
|
|
6705
|
+
const keySchemaPointer = `/${con}`;
|
|
6706
|
+
const negateClause = con == "else";
|
|
6707
|
+
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, nodeValue.then, schemaPointer + keySchemaPointer, dataPointer, false, null, null, forRefLibrary, dataPointerPrefix);
|
|
6708
|
+
if (innerItem) {
|
|
6709
|
+
applyITEConditions(innerItem, schemaPointer, keySchemaPointer, negateClause);
|
|
6710
|
+
if (isArray(innerItem)) {
|
|
6711
|
+
innerItem.forEach(item => {
|
|
6712
|
+
//item.schemaPointer = schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6713
|
+
//item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6714
|
+
newSection.push(item);
|
|
6715
|
+
newNode = newSection;
|
|
6716
|
+
});
|
|
6717
|
+
}
|
|
6718
|
+
else {
|
|
6719
|
+
//innerItem.schemaPointer = schemaPointer + keySchemaPointer + innerItem.dataPointer;
|
|
6720
|
+
//innerItem.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6721
|
+
newNode = innerItem;
|
|
6722
|
+
}
|
|
6723
|
+
}
|
|
6724
|
+
}
|
|
6725
|
+
});
|
|
6726
|
+
}
|
|
6115
6727
|
return newNode;
|
|
6116
6728
|
}
|
|
6117
6729
|
/**
|
|
@@ -6378,6 +6990,32 @@ class JsonSchemaFormService {
|
|
|
6378
6990
|
setSortableOptions(value) {
|
|
6379
6991
|
this.sortableOptionsSubject.next(value); // Update the sortable options value
|
|
6380
6992
|
}
|
|
6993
|
+
createAjvInstance(ajvOptions) {
|
|
6994
|
+
let ajvInstance = new Ajv2019(ajvOptions);
|
|
6995
|
+
ajvInstance.addMetaSchema(jsonDraft6);
|
|
6996
|
+
ajvInstance.addMetaSchema(jsonDraft7);
|
|
6997
|
+
addFormats(ajvInstance);
|
|
6998
|
+
return ajvInstance;
|
|
6999
|
+
}
|
|
7000
|
+
createAndRegisterAjvInstance(ajvOptions, name) {
|
|
7001
|
+
const intanceName = name || `ajv_${Date.now()}`;
|
|
7002
|
+
if (this.ajvRegistry[intanceName]) {
|
|
7003
|
+
throw new Error(`ajv instance with name:'${intanceName}' has already been registered`);
|
|
7004
|
+
}
|
|
7005
|
+
const ajvInstance = this.createAjvInstance(ajvOptions);
|
|
7006
|
+
this.ajvRegistry[intanceName] = {
|
|
7007
|
+
name: intanceName,
|
|
7008
|
+
ajvInstance: ajvInstance,
|
|
7009
|
+
ajvValidator: null
|
|
7010
|
+
};
|
|
7011
|
+
return this.ajvRegistry[intanceName];
|
|
7012
|
+
}
|
|
7013
|
+
getAjvInstance(name = 'default') {
|
|
7014
|
+
return this.ajvRegistry[name].ajvInstance;
|
|
7015
|
+
}
|
|
7016
|
+
getAjvValidator(name = 'default') {
|
|
7017
|
+
return this.ajvRegistry[name]?.ajvValidator;
|
|
7018
|
+
}
|
|
6381
7019
|
constructor() {
|
|
6382
7020
|
this.JsonFormCompatibility = false;
|
|
6383
7021
|
this.ReactJsonSchemaFormCompatibility = false;
|
|
@@ -6385,10 +7023,11 @@ class JsonSchemaFormService {
|
|
|
6385
7023
|
this.tpldata = {};
|
|
6386
7024
|
this.ajvOptions = {
|
|
6387
7025
|
allErrors: true,
|
|
6388
|
-
validateFormats:
|
|
7026
|
+
//validateFormats:false,
|
|
6389
7027
|
strict: false
|
|
6390
7028
|
};
|
|
6391
7029
|
this.ajv = new Ajv2019(this.ajvOptions); // AJV: Another JSON Schema Validator
|
|
7030
|
+
//Being replaced by getAjvValidator()
|
|
6392
7031
|
this.validateFormData = null; // Compiled AJV function to validate active form's schema
|
|
6393
7032
|
this.formValues = {}; // Internal form data (may not have correct types)
|
|
6394
7033
|
this.data = {}; // Output form data (formValues, formatted with correct data types)
|
|
@@ -6462,6 +7101,7 @@ class JsonSchemaFormService {
|
|
|
6462
7101
|
validationMessages: {} // set by setLanguage()
|
|
6463
7102
|
}
|
|
6464
7103
|
};
|
|
7104
|
+
//TODO-review,may not be needed as sortablejs replaces dnd
|
|
6465
7105
|
//this has been added to enable or disable the dragabble state of a component
|
|
6466
7106
|
//using the OrderableDirective, mainly when an <input type="range">
|
|
6467
7107
|
//elements are present, as the draggable attribute makes it difficult to
|
|
@@ -6474,9 +7114,20 @@ class JsonSchemaFormService {
|
|
|
6474
7114
|
//nxt-sortablejs and sortablejs
|
|
6475
7115
|
this.sortableOptionsSubject = new BehaviorSubject({ disabled: false }); // Default value true
|
|
6476
7116
|
this.sortableOptions$ = this.sortableOptionsSubject.asObservable();
|
|
7117
|
+
this.ajvRegistry = {};
|
|
6477
7118
|
this.setLanguage(this.language);
|
|
6478
7119
|
this.ajv.addMetaSchema(jsonDraft6);
|
|
6479
7120
|
this.ajv.addMetaSchema(jsonDraft7);
|
|
7121
|
+
addFormats(this.ajv);
|
|
7122
|
+
this.ajvRegistry['default'] = { name: 'default', ajvInstance: this.ajv, ajvValidator: null };
|
|
7123
|
+
console.log(this.ajvRegistry);
|
|
7124
|
+
// Add custom 'duration' format using a regex
|
|
7125
|
+
/*
|
|
7126
|
+
this.ajv.addFormat("duration", {
|
|
7127
|
+
type: "string",
|
|
7128
|
+
validate: (duration) => /^P(?!$)(\d+Y)?(\d+M)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?$/.test(duration)
|
|
7129
|
+
});
|
|
7130
|
+
*/
|
|
6480
7131
|
}
|
|
6481
7132
|
ngOnDestroy() {
|
|
6482
7133
|
this.fcValueChangesSubs?.unsubscribe();
|
|
@@ -6515,7 +7166,7 @@ class JsonSchemaFormService {
|
|
|
6515
7166
|
this.ReactJsonSchemaFormCompatibility = false;
|
|
6516
7167
|
this.AngularSchemaFormCompatibility = false;
|
|
6517
7168
|
this.tpldata = {};
|
|
6518
|
-
this.validateFormData = null;
|
|
7169
|
+
this.validateFormData = null; //Being replaced by getAjvValidator()
|
|
6519
7170
|
this.formValues = {};
|
|
6520
7171
|
this.schema = {};
|
|
6521
7172
|
this.layout = [];
|
|
@@ -6534,6 +7185,8 @@ class JsonSchemaFormService {
|
|
|
6534
7185
|
this.schemaRefLibrary = {};
|
|
6535
7186
|
this.templateRefLibrary = {};
|
|
6536
7187
|
this.formOptions = cloneDeep(this.defaultFormOptions);
|
|
7188
|
+
this.ajvRegistry = {};
|
|
7189
|
+
this.ajvRegistry['default'] = { name: 'default', ajvInstance: this.ajv, ajvValidator: null };
|
|
6537
7190
|
}
|
|
6538
7191
|
/**
|
|
6539
7192
|
* 'buildRemoteError' function
|
|
@@ -6565,10 +7218,10 @@ class JsonSchemaFormService {
|
|
|
6565
7218
|
}
|
|
6566
7219
|
});
|
|
6567
7220
|
}
|
|
6568
|
-
validateData(newValue, updateSubscriptions = true) {
|
|
7221
|
+
validateData(newValue, updateSubscriptions = true, ajvInstanceName = 'default') {
|
|
6569
7222
|
// Format raw form data to correct data types
|
|
6570
7223
|
this.data = formatFormData(newValue, this.dataMap, this.dataRecursiveRefMap, this.arrayMap, this.formOptions.returnEmptyFields);
|
|
6571
|
-
this.isValid = this.
|
|
7224
|
+
this.isValid = this.getAjvValidator(ajvInstanceName)(this.data);
|
|
6572
7225
|
this.validData = this.isValid ? this.data : null;
|
|
6573
7226
|
const compileErrors = (errors) => {
|
|
6574
7227
|
const compiledErrors = {};
|
|
@@ -6583,8 +7236,9 @@ class JsonSchemaFormService {
|
|
|
6583
7236
|
});
|
|
6584
7237
|
return compiledErrors;
|
|
6585
7238
|
};
|
|
6586
|
-
|
|
6587
|
-
this.
|
|
7239
|
+
//TODO:store avjErrors per ajvInstance in registry
|
|
7240
|
+
this.ajvErrors = this.getAjvValidator(ajvInstanceName).errors;
|
|
7241
|
+
this.validationErrors = compileErrors(this.ajvErrors);
|
|
6588
7242
|
if (updateSubscriptions) {
|
|
6589
7243
|
this.dataChanges.next(this.data);
|
|
6590
7244
|
this.isValidChanges.next(this.isValid);
|
|
@@ -6594,16 +7248,16 @@ class JsonSchemaFormService {
|
|
|
6594
7248
|
buildFormGroupTemplate(formValues = null, setValues = true) {
|
|
6595
7249
|
this.formGroupTemplate = buildFormGroupTemplate(this, formValues, setValues);
|
|
6596
7250
|
}
|
|
6597
|
-
buildFormGroup() {
|
|
7251
|
+
buildFormGroup(ajvInstanceName) {
|
|
6598
7252
|
this.formGroup = buildFormGroup(this.formGroupTemplate);
|
|
6599
7253
|
if (this.formGroup) {
|
|
6600
|
-
this.compileAjvSchema();
|
|
6601
|
-
this.validateData(this.formGroup.value);
|
|
7254
|
+
this.compileAjvSchema(ajvInstanceName);
|
|
7255
|
+
this.validateData(this.formGroup.value, true, ajvInstanceName);
|
|
6602
7256
|
// Set up observables to emit data and validation info when form data changes
|
|
6603
7257
|
if (this.formValueSubscription) {
|
|
6604
7258
|
this.formValueSubscription.unsubscribe();
|
|
6605
7259
|
}
|
|
6606
|
-
this.formValueSubscription = this.formGroup.valueChanges.subscribe(formValue => this.validateData(formValue));
|
|
7260
|
+
this.formValueSubscription = this.formGroup.valueChanges.subscribe(formValue => this.validateData(formValue, true, ajvInstanceName));
|
|
6607
7261
|
}
|
|
6608
7262
|
}
|
|
6609
7263
|
buildLayout(widgetLibrary) {
|
|
@@ -6632,15 +7286,17 @@ class JsonSchemaFormService {
|
|
|
6632
7286
|
});
|
|
6633
7287
|
}
|
|
6634
7288
|
}
|
|
6635
|
-
compileAjvSchema() {
|
|
6636
|
-
|
|
7289
|
+
compileAjvSchema(ajvInstanceName = 'default') {
|
|
7290
|
+
let ajvValidator = this.getAjvValidator(ajvInstanceName);
|
|
7291
|
+
if (!ajvValidator) {
|
|
6637
7292
|
// if 'ui:order' exists in properties, move it to root before compiling with ajv
|
|
6638
7293
|
if (Array.isArray(this.schema.properties['ui:order'])) {
|
|
6639
7294
|
this.schema['ui:order'] = this.schema.properties['ui:order'];
|
|
6640
7295
|
delete this.schema.properties['ui:order'];
|
|
6641
7296
|
}
|
|
6642
|
-
this.
|
|
6643
|
-
|
|
7297
|
+
this.getAjvInstance(ajvInstanceName).removeSchema(this.schema);
|
|
7298
|
+
ajvValidator = this.getAjvInstance(ajvInstanceName).compile(this.schema);
|
|
7299
|
+
this.ajvRegistry[ajvInstanceName].ajvValidator = ajvValidator;
|
|
6644
7300
|
}
|
|
6645
7301
|
}
|
|
6646
7302
|
buildSchemaFromData(data, requireAllFields = false) {
|
|
@@ -6786,12 +7442,24 @@ class JsonSchemaFormService {
|
|
|
6786
7442
|
if (!isObject(ctx)) {
|
|
6787
7443
|
return false;
|
|
6788
7444
|
}
|
|
7445
|
+
const layoutNode = ctx.layoutNode;
|
|
6789
7446
|
if (isEmpty(ctx.options)) {
|
|
6790
7447
|
ctx.options = !isEmpty((ctx.layoutNode || {}).options)
|
|
6791
7448
|
? ctx.layoutNode.options
|
|
6792
7449
|
: cloneDeep(this.formOptions);
|
|
6793
7450
|
}
|
|
6794
7451
|
ctx.formControl = this.getFormControl(ctx);
|
|
7452
|
+
//introduced to check if the node is part of ITE conditional
|
|
7453
|
+
//then change or add the control
|
|
7454
|
+
if (layoutNode?.schemaPointer && layoutNode.isITEItem ||
|
|
7455
|
+
(layoutNode?.schemaPointer && layoutNode?.oneOfPointer)) {
|
|
7456
|
+
//before changing control, need to set the new data type for data formatting
|
|
7457
|
+
const schemaType = this.dataMap.get(layoutNode?.dataPointer).get("schemaType");
|
|
7458
|
+
if (schemaType != layoutNode.dataType) {
|
|
7459
|
+
this.dataMap.get(layoutNode?.dataPointer).set("schemaType", layoutNode.dataType);
|
|
7460
|
+
}
|
|
7461
|
+
this.setFormControl(ctx, ctx.formControl);
|
|
7462
|
+
}
|
|
6795
7463
|
ctx.boundControl = bind && !!ctx.formControl;
|
|
6796
7464
|
if (ctx.formControl) {
|
|
6797
7465
|
ctx.controlName = this.getFormControlName(ctx);
|
|
@@ -6810,14 +7478,6 @@ class JsonSchemaFormService {
|
|
|
6810
7478
|
? null
|
|
6811
7479
|
: this.formatErrors(ctx.formControl.errors, ctx.options.validationMessages)));
|
|
6812
7480
|
this.fcValueChangesSubs = ctx.formControl.valueChanges.subscribe(value => {
|
|
6813
|
-
//commented out to revert back to previous commits
|
|
6814
|
-
//as seems to be causing some issues
|
|
6815
|
-
/*
|
|
6816
|
-
if (!!value) {
|
|
6817
|
-
ctx.controlValue = value;
|
|
6818
|
-
}
|
|
6819
|
-
*/
|
|
6820
|
-
//TODO-test,this is the original code
|
|
6821
7481
|
if (!isEqual$1(ctx.controlValue, value)) {
|
|
6822
7482
|
ctx.controlValue = value;
|
|
6823
7483
|
}
|
|
@@ -6831,6 +7491,27 @@ class JsonSchemaFormService {
|
|
|
6831
7491
|
console.error(`warning: control "${dataPointer}" is not bound to the Angular FormGroup.`);
|
|
6832
7492
|
}
|
|
6833
7493
|
}
|
|
7494
|
+
//if this is a ITE conditional field, the value would not have been
|
|
7495
|
+
//set, as the control would only be initialized when the condition is true
|
|
7496
|
+
//TODO-review need to decide which of the data sets between data,formValues and default
|
|
7497
|
+
//to use for the value
|
|
7498
|
+
if (ctx.options?.condition || layoutNode?.oneOfPointer) {
|
|
7499
|
+
const dataPointer = this.getDataPointer(ctx);
|
|
7500
|
+
const controlValue = ctx.formControl.value;
|
|
7501
|
+
const dataValue = JsonPointer.has(this.data, dataPointer) ?
|
|
7502
|
+
JsonPointer.get(this.data, dataPointer) : undefined;
|
|
7503
|
+
const formValue = JsonPointer.has(this.formValues, dataPointer) ?
|
|
7504
|
+
JsonPointer.get(this.formValues, dataPointer) : undefined;
|
|
7505
|
+
const schemaDefault = ctx.options?.default;
|
|
7506
|
+
//if initial formValues was supplied and controlValue matches formValue then likely
|
|
7507
|
+
//control was initially created with the formValue then set value to data value
|
|
7508
|
+
//if no formValues was supplied and controlValue matches schemaDefault then likely
|
|
7509
|
+
//control was initially created with the default then set value to data value
|
|
7510
|
+
const value = this.formValues && isEqual$1(formValue, controlValue) ? dataValue
|
|
7511
|
+
: !this.formValues && isEqual$1(schemaDefault, controlValue) ? dataValue
|
|
7512
|
+
: schemaDefault;
|
|
7513
|
+
ctx.formControl?.patchValue(value);
|
|
7514
|
+
}
|
|
6834
7515
|
return ctx.boundControl;
|
|
6835
7516
|
}
|
|
6836
7517
|
formatErrors(errors, validationMessages = {}) {
|
|
@@ -6912,13 +7593,50 @@ class JsonSchemaFormService {
|
|
|
6912
7593
|
}
|
|
6913
7594
|
formArray.markAsDirty();
|
|
6914
7595
|
}
|
|
7596
|
+
updateArrayMultiSelectList(ctx, selectList) {
|
|
7597
|
+
this.updateArrayCheckboxList(ctx, selectList);
|
|
7598
|
+
/* const formArray = <UntypedFormArray>this.getFormControl(ctx);
|
|
7599
|
+
|
|
7600
|
+
// Remove all existing items
|
|
7601
|
+
while (formArray.value.length) {
|
|
7602
|
+
formArray.removeAt(0);
|
|
7603
|
+
}
|
|
7604
|
+
|
|
7605
|
+
// Re-add an item for each checked box
|
|
7606
|
+
const refPointer = removeRecursiveReferences(
|
|
7607
|
+
ctx.layoutNode.dataPointer + '/-',
|
|
7608
|
+
this.dataRecursiveRefMap,
|
|
7609
|
+
this.arrayMap
|
|
7610
|
+
);
|
|
7611
|
+
for (const selectItem of selectList) {
|
|
7612
|
+
if (selectItem.value) {
|
|
7613
|
+
const newFormControl = buildFormGroup(
|
|
7614
|
+
this.templateRefLibrary[refPointer]
|
|
7615
|
+
);
|
|
7616
|
+
newFormControl.setValue(selectItem.value);
|
|
7617
|
+
formArray.push(newFormControl);
|
|
7618
|
+
}
|
|
7619
|
+
}
|
|
7620
|
+
formArray.markAsDirty();
|
|
7621
|
+
*/
|
|
7622
|
+
}
|
|
6915
7623
|
getFormControl(ctx) {
|
|
6916
7624
|
if (!ctx.layoutNode ||
|
|
6917
7625
|
!isDefined(ctx.layoutNode.dataPointer) ||
|
|
6918
7626
|
ctx.layoutNode.type === '$ref') {
|
|
6919
7627
|
return null;
|
|
6920
7628
|
}
|
|
6921
|
-
|
|
7629
|
+
const schemaPointer = ctx.layoutNode?.isITEItem ? ctx.layoutNode?.schemaPointer : null;
|
|
7630
|
+
const oneOfPointer = ctx.layoutNode?.oneOfPointer;
|
|
7631
|
+
return getControl(this.formGroup, this.getDataPointer(ctx), false, schemaPointer || oneOfPointer);
|
|
7632
|
+
}
|
|
7633
|
+
setFormControl(ctx, control) {
|
|
7634
|
+
if (!ctx || !ctx.layoutNode ||
|
|
7635
|
+
!isDefined(ctx.layoutNode.dataPointer) ||
|
|
7636
|
+
ctx.layoutNode.type === '$ref') {
|
|
7637
|
+
return null;
|
|
7638
|
+
}
|
|
7639
|
+
return setControl(this.formGroup, this.getDataPointer(ctx), control);
|
|
6922
7640
|
}
|
|
6923
7641
|
getFormControlValue(ctx) {
|
|
6924
7642
|
if (!ctx.layoutNode ||
|
|
@@ -6926,14 +7644,18 @@ class JsonSchemaFormService {
|
|
|
6926
7644
|
ctx.layoutNode.type === '$ref') {
|
|
6927
7645
|
return null;
|
|
6928
7646
|
}
|
|
6929
|
-
const
|
|
7647
|
+
const schemaPointer = ctx.layoutNode?.isITEItem ? ctx.layoutNode?.schemaPointer : null;
|
|
7648
|
+
const oneOfPointer = ctx.layoutNode?.oneOfPointer;
|
|
7649
|
+
const control = getControl(this.formGroup, this.getDataPointer(ctx), false, schemaPointer || oneOfPointer);
|
|
6930
7650
|
return control ? control.value : null;
|
|
6931
7651
|
}
|
|
6932
7652
|
getFormControlGroup(ctx) {
|
|
6933
7653
|
if (!ctx.layoutNode || !isDefined(ctx.layoutNode.dataPointer)) {
|
|
6934
7654
|
return null;
|
|
6935
7655
|
}
|
|
6936
|
-
|
|
7656
|
+
const schemaPointer = ctx.layoutNode?.isITEItem ? ctx.layoutNode?.schemaPointer : null;
|
|
7657
|
+
const oneOfPointer = ctx.layoutNode?.oneOfPointer;
|
|
7658
|
+
return getControl(this.formGroup, this.getDataPointer(ctx), true, schemaPointer || oneOfPointer);
|
|
6937
7659
|
}
|
|
6938
7660
|
getFormControlName(ctx) {
|
|
6939
7661
|
if (!ctx.layoutNode ||
|
|
@@ -7189,13 +7911,15 @@ class AddReferenceComponent {
|
|
|
7189
7911
|
}
|
|
7190
7912
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AddReferenceComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7191
7913
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AddReferenceComponent, selector: "add-reference-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
7192
|
-
<
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7198
|
-
|
|
7914
|
+
<section [class]="options?.htmlClass || ''" align="end">
|
|
7915
|
+
<button *ngIf="showAddButton"
|
|
7916
|
+
[class]="options?.fieldHtmlClass || ''" class="sortable-filter sortable-fixed"
|
|
7917
|
+
[disabled]="options?.readonly"
|
|
7918
|
+
(click)="addItem($event)">
|
|
7919
|
+
<span *ngIf="options?.icon" [class]="options?.icon"></span>
|
|
7920
|
+
<span *ngIf="options?.title" [innerHTML]="buttonText"></span>
|
|
7921
|
+
</button>
|
|
7922
|
+
</section>`, isInline: true, dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.Default }); }
|
|
7199
7923
|
}
|
|
7200
7924
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AddReferenceComponent, decorators: [{
|
|
7201
7925
|
type: Component,
|
|
@@ -7203,13 +7927,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
7203
7927
|
// tslint:disable-next-line:component-selector
|
|
7204
7928
|
selector: 'add-reference-widget',
|
|
7205
7929
|
template: `
|
|
7206
|
-
<
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7930
|
+
<section [class]="options?.htmlClass || ''" align="end">
|
|
7931
|
+
<button *ngIf="showAddButton"
|
|
7932
|
+
[class]="options?.fieldHtmlClass || ''" class="sortable-filter sortable-fixed"
|
|
7933
|
+
[disabled]="options?.readonly"
|
|
7934
|
+
(click)="addItem($event)">
|
|
7935
|
+
<span *ngIf="options?.icon" [class]="options?.icon"></span>
|
|
7936
|
+
<span *ngIf="options?.title" [innerHTML]="buttonText"></span>
|
|
7937
|
+
</button>
|
|
7938
|
+
</section>`,
|
|
7213
7939
|
changeDetection: ChangeDetectionStrategy.Default,
|
|
7214
7940
|
}]
|
|
7215
7941
|
}], ctorParameters: function () { return [{ type: JsonSchemaFormService }]; }, propDecorators: { layoutNode: [{
|
|
@@ -7238,6 +7964,9 @@ class ButtonComponent {
|
|
|
7238
7964
|
this.jsf.updateValue(this, event.target.value);
|
|
7239
7965
|
}
|
|
7240
7966
|
}
|
|
7967
|
+
ngOnDestroy() {
|
|
7968
|
+
this.jsf.updateValue(this, null);
|
|
7969
|
+
}
|
|
7241
7970
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7242
7971
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ButtonComponent, selector: "button-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
7243
7972
|
<div
|
|
@@ -7288,6 +8017,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
7288
8017
|
type: Input
|
|
7289
8018
|
}] } });
|
|
7290
8019
|
|
|
8020
|
+
///NB issue caused by sortablejs when it its destroyed
|
|
8021
|
+
//this mainly affects checkboxes coupled with conditions
|
|
8022
|
+
//-the value is rechecked
|
|
8023
|
+
//-see https://github.com/SortableJS/Sortable/issues/1052#issuecomment-369613072
|
|
7291
8024
|
class CheckboxComponent {
|
|
7292
8025
|
constructor(jsf) {
|
|
7293
8026
|
this.jsf = jsf;
|
|
@@ -7300,7 +8033,8 @@ class CheckboxComponent {
|
|
|
7300
8033
|
this.options = this.layoutNode.options || {};
|
|
7301
8034
|
this.jsf.initializeControl(this);
|
|
7302
8035
|
if (this.controlValue === null || this.controlValue === undefined) {
|
|
7303
|
-
this.controlValue =
|
|
8036
|
+
this.controlValue = false;
|
|
8037
|
+
this.jsf.updateValue(this, this.falseValue);
|
|
7304
8038
|
}
|
|
7305
8039
|
}
|
|
7306
8040
|
updateValue(event) {
|
|
@@ -7310,6 +8044,9 @@ class CheckboxComponent {
|
|
|
7310
8044
|
get isChecked() {
|
|
7311
8045
|
return this.jsf.getFormControlValue(this) === this.trueValue;
|
|
7312
8046
|
}
|
|
8047
|
+
ngOnDestroy() {
|
|
8048
|
+
this.jsf.updateValue(this, null);
|
|
8049
|
+
}
|
|
7313
8050
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CheckboxComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7314
8051
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CheckboxComponent, selector: "checkbox-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
7315
8052
|
<label
|
|
@@ -7327,7 +8064,7 @@ class CheckboxComponent {
|
|
|
7327
8064
|
type="checkbox">
|
|
7328
8065
|
<input *ngIf="!boundControl"
|
|
7329
8066
|
[attr.aria-describedby]="'control' + layoutNode?._id + 'Status'"
|
|
7330
|
-
[checked]="isChecked
|
|
8067
|
+
[checked]="isChecked"
|
|
7331
8068
|
[class]="(options?.fieldHtmlClass || '') + (isChecked ?
|
|
7332
8069
|
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
7333
8070
|
(' ' + (options?.style?.unselected || '')))"
|
|
@@ -7364,7 +8101,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
7364
8101
|
type="checkbox">
|
|
7365
8102
|
<input *ngIf="!boundControl"
|
|
7366
8103
|
[attr.aria-describedby]="'control' + layoutNode?._id + 'Status'"
|
|
7367
|
-
[checked]="isChecked
|
|
8104
|
+
[checked]="isChecked"
|
|
7368
8105
|
[class]="(options?.fieldHtmlClass || '') + (isChecked ?
|
|
7369
8106
|
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
7370
8107
|
(' ' + (options?.style?.unselected || '')))"
|
|
@@ -7416,6 +8153,13 @@ class CheckboxesComponent {
|
|
|
7416
8153
|
this.jsf.updateArrayCheckboxList(this, this.checkboxList);
|
|
7417
8154
|
}
|
|
7418
8155
|
}
|
|
8156
|
+
//TODO review this
|
|
8157
|
+
ngOnDestroy() {
|
|
8158
|
+
//this.jsf.updateValue(this, null);
|
|
8159
|
+
let nullVal = [];
|
|
8160
|
+
this.formControl.reset(nullVal);
|
|
8161
|
+
this.controlValue = null;
|
|
8162
|
+
}
|
|
7419
8163
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CheckboxesComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7420
8164
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CheckboxesComponent, selector: "checkboxes-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
7421
8165
|
<label *ngIf="options?.title"
|
|
@@ -7544,6 +8288,9 @@ class FileComponent {
|
|
|
7544
8288
|
updateValue(event) {
|
|
7545
8289
|
this.jsf.updateValue(this, event.target.value);
|
|
7546
8290
|
}
|
|
8291
|
+
ngOnDestroy() {
|
|
8292
|
+
this.jsf.updateValue(this, null);
|
|
8293
|
+
}
|
|
7547
8294
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FileComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7548
8295
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FileComponent, selector: "file-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: ``, isInline: true }); }
|
|
7549
8296
|
}
|
|
@@ -7571,6 +8318,9 @@ class HiddenComponent {
|
|
|
7571
8318
|
ngOnInit() {
|
|
7572
8319
|
this.jsf.initializeControl(this);
|
|
7573
8320
|
}
|
|
8321
|
+
ngOnDestroy() {
|
|
8322
|
+
this.jsf.updateValue(this, null);
|
|
8323
|
+
}
|
|
7574
8324
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HiddenComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7575
8325
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: HiddenComponent, selector: "hidden-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
7576
8326
|
<input *ngIf="boundControl"
|
|
@@ -7629,6 +8379,9 @@ class InputComponent {
|
|
|
7629
8379
|
updateValue(event) {
|
|
7630
8380
|
this.jsf.updateValue(this, event.target.value);
|
|
7631
8381
|
}
|
|
8382
|
+
ngOnDestroy() {
|
|
8383
|
+
this.jsf.updateValue(this, null);
|
|
8384
|
+
}
|
|
7632
8385
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: InputComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7633
8386
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: InputComponent, selector: "input-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
7634
8387
|
<div [class]="options?.htmlClass || ''" class="sortable-filter" >
|
|
@@ -7815,6 +8568,9 @@ class NumberComponent {
|
|
|
7815
8568
|
updateValue(event) {
|
|
7816
8569
|
this.jsf.updateValue(this, event.target.value);
|
|
7817
8570
|
}
|
|
8571
|
+
ngOnDestroy() {
|
|
8572
|
+
this.jsf.updateValue(this, null);
|
|
8573
|
+
}
|
|
7818
8574
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NumberComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7819
8575
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NumberComponent, selector: "number-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
7820
8576
|
<div #divElt [class]="options?.htmlClass || ''" class="sortable-filter" >
|
|
@@ -7923,6 +8679,204 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
7923
8679
|
type: Input
|
|
7924
8680
|
}] } });
|
|
7925
8681
|
|
|
8682
|
+
class SelectFrameworkComponent {
|
|
8683
|
+
constructor(jsf) {
|
|
8684
|
+
this.jsf = jsf;
|
|
8685
|
+
this.newComponent = null;
|
|
8686
|
+
}
|
|
8687
|
+
ngOnInit() {
|
|
8688
|
+
this.updateComponent();
|
|
8689
|
+
}
|
|
8690
|
+
ngOnChanges() {
|
|
8691
|
+
this.updateComponent();
|
|
8692
|
+
}
|
|
8693
|
+
updateComponent() {
|
|
8694
|
+
const widgetContainer = this.widgetContainer;
|
|
8695
|
+
if (widgetContainer && !this.newComponent && this.jsf.framework) {
|
|
8696
|
+
this.newComponent = widgetContainer.createComponent((this.jsf.framework));
|
|
8697
|
+
//TODO fix all deprecated calls and test
|
|
8698
|
+
//this.widgetContainer.createComponent<any>(this.jsf.framework)
|
|
8699
|
+
}
|
|
8700
|
+
if (this.newComponent) {
|
|
8701
|
+
for (const input of ['layoutNode', 'layoutIndex', 'dataIndex']) {
|
|
8702
|
+
this.newComponent.instance[input] = this[input];
|
|
8703
|
+
}
|
|
8704
|
+
}
|
|
8705
|
+
}
|
|
8706
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectFrameworkComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8707
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SelectFrameworkComponent, selector: "select-framework-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, viewQueries: [{ propertyName: "widgetContainer", first: true, predicate: ["widgetContainer"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `<div #widgetContainer></div>`, isInline: true }); }
|
|
8708
|
+
}
|
|
8709
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectFrameworkComponent, decorators: [{
|
|
8710
|
+
type: Component,
|
|
8711
|
+
args: [{
|
|
8712
|
+
// tslint:disable-next-line:component-selector
|
|
8713
|
+
selector: 'select-framework-widget',
|
|
8714
|
+
template: `<div #widgetContainer></div>`,
|
|
8715
|
+
}]
|
|
8716
|
+
}], ctorParameters: function () { return [{ type: JsonSchemaFormService }]; }, propDecorators: { layoutNode: [{
|
|
8717
|
+
type: Input
|
|
8718
|
+
}], layoutIndex: [{
|
|
8719
|
+
type: Input
|
|
8720
|
+
}], dataIndex: [{
|
|
8721
|
+
type: Input
|
|
8722
|
+
}], widgetContainer: [{
|
|
8723
|
+
type: ViewChild,
|
|
8724
|
+
args: ['widgetContainer', {
|
|
8725
|
+
read: ViewContainerRef,
|
|
8726
|
+
static: true
|
|
8727
|
+
}]
|
|
8728
|
+
}] } });
|
|
8729
|
+
|
|
8730
|
+
class TabsComponent {
|
|
8731
|
+
constructor(jsf) {
|
|
8732
|
+
this.jsf = jsf;
|
|
8733
|
+
this.selectedItem = 0;
|
|
8734
|
+
this.showAddTab = true;
|
|
8735
|
+
}
|
|
8736
|
+
ngOnInit() {
|
|
8737
|
+
this.options = this.layoutNode.options || {};
|
|
8738
|
+
if (this.options.selectedTab) {
|
|
8739
|
+
this.selectedItem = this.options.selectedTab;
|
|
8740
|
+
}
|
|
8741
|
+
this.itemCount = this.layoutNode.items.length - 1;
|
|
8742
|
+
this.updateControl();
|
|
8743
|
+
}
|
|
8744
|
+
select(index) {
|
|
8745
|
+
if (this.layoutNode.items[index].type === '$ref') {
|
|
8746
|
+
this.itemCount = this.layoutNode.items.length;
|
|
8747
|
+
this.jsf.addItem({
|
|
8748
|
+
layoutNode: this.layoutNode.items[index],
|
|
8749
|
+
layoutIndex: this.layoutIndex.concat(index),
|
|
8750
|
+
dataIndex: this.dataIndex.concat(index)
|
|
8751
|
+
});
|
|
8752
|
+
this.updateControl();
|
|
8753
|
+
}
|
|
8754
|
+
this.selectedItem = index;
|
|
8755
|
+
}
|
|
8756
|
+
updateControl() {
|
|
8757
|
+
const lastItem = this.layoutNode.items[this.layoutNode.items.length - 1];
|
|
8758
|
+
if (lastItem.type === '$ref' &&
|
|
8759
|
+
this.itemCount >= (lastItem.options.maxItems || 1000)) {
|
|
8760
|
+
this.showAddTab = false;
|
|
8761
|
+
}
|
|
8762
|
+
}
|
|
8763
|
+
setTabTitle(item, index) {
|
|
8764
|
+
return this.jsf.setArrayItemTitle(this, item, index);
|
|
8765
|
+
}
|
|
8766
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TabsComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8767
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TabsComponent, selector: "tabs-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
8768
|
+
<ul
|
|
8769
|
+
[class]="options?.labelHtmlClass || ''">
|
|
8770
|
+
<li *ngFor="let item of layoutNode?.items; let i = index"
|
|
8771
|
+
[class]="(options?.itemLabelHtmlClass || '') + (selectedItem === i ?
|
|
8772
|
+
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
8773
|
+
(' ' + options?.style?.unselected))"
|
|
8774
|
+
role="presentation"
|
|
8775
|
+
data-tabs>
|
|
8776
|
+
<a *ngIf="showAddTab || item.type !== '$ref'"
|
|
8777
|
+
[class]="'nav-link' + (selectedItem === i ? (' ' + options?.activeClass + ' ' + options?.style?.selected) :
|
|
8778
|
+
(' ' + options?.style?.unselected))"
|
|
8779
|
+
(click)="select(i)">
|
|
8780
|
+
<input type="radio" [value]="i" *ngIf="options?.tabMode=='oneOfMode'"
|
|
8781
|
+
name="tabSelection"
|
|
8782
|
+
[(ngModel)]="selectedItem"
|
|
8783
|
+
[class]="(options?.widget_radioClass || '')"
|
|
8784
|
+
[value]="i"
|
|
8785
|
+
(change)="select(i)"
|
|
8786
|
+
/>
|
|
8787
|
+
{{setTabTitle(item, i)}}
|
|
8788
|
+
</a>
|
|
8789
|
+
</li>
|
|
8790
|
+
</ul>
|
|
8791
|
+
|
|
8792
|
+
<div *ngFor="let layoutItem of layoutNode?.items; let i = index"
|
|
8793
|
+
[class]="(options?.htmlClass || '') + (selectedItem != i?' ngf-hidden':'') ">
|
|
8794
|
+
<!--for now the only difference between oneOfMode and the default
|
|
8795
|
+
is that oneOfMode uses the *ngIf="selectedItem === i" clause, which automatically
|
|
8796
|
+
destroys the tabs that are not rendered while default mode only hide them
|
|
8797
|
+
the upshot is that only the active tabs value will be used
|
|
8798
|
+
-->
|
|
8799
|
+
<ng-container *ngIf="options?.tabMode=='oneOfMode'">
|
|
8800
|
+
<select-framework-widget *ngIf="selectedItem === i"
|
|
8801
|
+
[class]="(options?.fieldHtmlClass || '') +
|
|
8802
|
+
' ' + (options?.activeClass || '') +
|
|
8803
|
+
' ' + (options?.style?.selected || '')"
|
|
8804
|
+
[dataIndex]="layoutNode?.dataType === 'array' ? (dataIndex || []).concat(i) : dataIndex"
|
|
8805
|
+
[layoutIndex]="(layoutIndex || []).concat(i)"
|
|
8806
|
+
[layoutNode]="layoutItem"></select-framework-widget>
|
|
8807
|
+
</ng-container>
|
|
8808
|
+
<ng-container *ngIf="options?.tabMode !='oneOfMode'">
|
|
8809
|
+
<select-framework-widget
|
|
8810
|
+
[class]="(options?.fieldHtmlClass || '') +
|
|
8811
|
+
' ' + (options?.activeClass || '') +
|
|
8812
|
+
' ' + (options?.style?.selected || '')"
|
|
8813
|
+
[dataIndex]="layoutNode?.dataType === 'array' ? (dataIndex || []).concat(i) : dataIndex"
|
|
8814
|
+
[layoutIndex]="(layoutIndex || []).concat(i)"
|
|
8815
|
+
[layoutNode]="layoutItem"></select-framework-widget>
|
|
8816
|
+
</ng-container>
|
|
8817
|
+
</div>`, isInline: true, styles: ["a{cursor:pointer}.ngf-hidden{display:none}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SelectFrameworkComponent, selector: "select-framework-widget", inputs: ["layoutNode", "layoutIndex", "dataIndex"] }] }); }
|
|
8818
|
+
}
|
|
8819
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TabsComponent, decorators: [{
|
|
8820
|
+
type: Component,
|
|
8821
|
+
args: [{ selector: 'tabs-widget', template: `
|
|
8822
|
+
<ul
|
|
8823
|
+
[class]="options?.labelHtmlClass || ''">
|
|
8824
|
+
<li *ngFor="let item of layoutNode?.items; let i = index"
|
|
8825
|
+
[class]="(options?.itemLabelHtmlClass || '') + (selectedItem === i ?
|
|
8826
|
+
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
8827
|
+
(' ' + options?.style?.unselected))"
|
|
8828
|
+
role="presentation"
|
|
8829
|
+
data-tabs>
|
|
8830
|
+
<a *ngIf="showAddTab || item.type !== '$ref'"
|
|
8831
|
+
[class]="'nav-link' + (selectedItem === i ? (' ' + options?.activeClass + ' ' + options?.style?.selected) :
|
|
8832
|
+
(' ' + options?.style?.unselected))"
|
|
8833
|
+
(click)="select(i)">
|
|
8834
|
+
<input type="radio" [value]="i" *ngIf="options?.tabMode=='oneOfMode'"
|
|
8835
|
+
name="tabSelection"
|
|
8836
|
+
[(ngModel)]="selectedItem"
|
|
8837
|
+
[class]="(options?.widget_radioClass || '')"
|
|
8838
|
+
[value]="i"
|
|
8839
|
+
(change)="select(i)"
|
|
8840
|
+
/>
|
|
8841
|
+
{{setTabTitle(item, i)}}
|
|
8842
|
+
</a>
|
|
8843
|
+
</li>
|
|
8844
|
+
</ul>
|
|
8845
|
+
|
|
8846
|
+
<div *ngFor="let layoutItem of layoutNode?.items; let i = index"
|
|
8847
|
+
[class]="(options?.htmlClass || '') + (selectedItem != i?' ngf-hidden':'') ">
|
|
8848
|
+
<!--for now the only difference between oneOfMode and the default
|
|
8849
|
+
is that oneOfMode uses the *ngIf="selectedItem === i" clause, which automatically
|
|
8850
|
+
destroys the tabs that are not rendered while default mode only hide them
|
|
8851
|
+
the upshot is that only the active tabs value will be used
|
|
8852
|
+
-->
|
|
8853
|
+
<ng-container *ngIf="options?.tabMode=='oneOfMode'">
|
|
8854
|
+
<select-framework-widget *ngIf="selectedItem === i"
|
|
8855
|
+
[class]="(options?.fieldHtmlClass || '') +
|
|
8856
|
+
' ' + (options?.activeClass || '') +
|
|
8857
|
+
' ' + (options?.style?.selected || '')"
|
|
8858
|
+
[dataIndex]="layoutNode?.dataType === 'array' ? (dataIndex || []).concat(i) : dataIndex"
|
|
8859
|
+
[layoutIndex]="(layoutIndex || []).concat(i)"
|
|
8860
|
+
[layoutNode]="layoutItem"></select-framework-widget>
|
|
8861
|
+
</ng-container>
|
|
8862
|
+
<ng-container *ngIf="options?.tabMode !='oneOfMode'">
|
|
8863
|
+
<select-framework-widget
|
|
8864
|
+
[class]="(options?.fieldHtmlClass || '') +
|
|
8865
|
+
' ' + (options?.activeClass || '') +
|
|
8866
|
+
' ' + (options?.style?.selected || '')"
|
|
8867
|
+
[dataIndex]="layoutNode?.dataType === 'array' ? (dataIndex || []).concat(i) : dataIndex"
|
|
8868
|
+
[layoutIndex]="(layoutIndex || []).concat(i)"
|
|
8869
|
+
[layoutNode]="layoutItem"></select-framework-widget>
|
|
8870
|
+
</ng-container>
|
|
8871
|
+
</div>`, standalone: false, styles: ["a{cursor:pointer}.ngf-hidden{display:none}\n"] }]
|
|
8872
|
+
}], ctorParameters: function () { return [{ type: JsonSchemaFormService }]; }, propDecorators: { layoutNode: [{
|
|
8873
|
+
type: Input
|
|
8874
|
+
}], layoutIndex: [{
|
|
8875
|
+
type: Input
|
|
8876
|
+
}], dataIndex: [{
|
|
8877
|
+
type: Input
|
|
8878
|
+
}] } });
|
|
8879
|
+
|
|
7926
8880
|
// TODO: Add this control
|
|
7927
8881
|
class OneOfComponent {
|
|
7928
8882
|
constructor(jsf) {
|
|
@@ -7932,20 +8886,101 @@ class OneOfComponent {
|
|
|
7932
8886
|
}
|
|
7933
8887
|
ngOnInit() {
|
|
7934
8888
|
this.options = this.layoutNode.options || {};
|
|
8889
|
+
this.options.tabMode = "oneOfMode";
|
|
8890
|
+
this.options.selectedTab = this.findSelectedTab();
|
|
8891
|
+
//this.options.description=this.options.description||"choose one of";
|
|
7935
8892
|
this.jsf.initializeControl(this);
|
|
7936
8893
|
}
|
|
8894
|
+
findSelectedTab() {
|
|
8895
|
+
//TODO test- this.jsf.formValues seems to be the initial data supplied to the form
|
|
8896
|
+
//while the jsf.formGroup value is derived from the actual controls
|
|
8897
|
+
//let formValue=this.jsf.getFormControlValue(this);
|
|
8898
|
+
let foundInd = -1;
|
|
8899
|
+
//seach for non null value
|
|
8900
|
+
if (this.layoutNode.items) {
|
|
8901
|
+
this.layoutNode.items.forEach((layoutItem, ind) => {
|
|
8902
|
+
let formValue = JsonPointer.get(this.jsf.formValues, layoutItem.dataPointer);
|
|
8903
|
+
if (layoutItem.oneOfPointer) {
|
|
8904
|
+
let controlKey = path2ControlKey(layoutItem.oneOfPointer);
|
|
8905
|
+
let fname = layoutItem.name;
|
|
8906
|
+
if (hasOwn(this.jsf.formGroup.controls, controlKey) &&
|
|
8907
|
+
(formValue || hasNonNullValue(this.jsf.formGroup.controls[controlKey].value))
|
|
8908
|
+
//hasOwn(formValue,fname) && hasOwn(this.jsf.formGroup.controls,controlKey)
|
|
8909
|
+
// && (formValue[fname] || this.jsf.formGroup.controls[controlKey].value)
|
|
8910
|
+
//&&isEqual(formValue[fname],this.jsf.formGroup.controls[controlKey].value)
|
|
8911
|
+
) {
|
|
8912
|
+
foundInd = ind;
|
|
8913
|
+
}
|
|
8914
|
+
//foundInd=formValue[controlKey]!=null?ind:foundInd;
|
|
8915
|
+
//if no exact match found, then search in descendant values
|
|
8916
|
+
//to see which one of item matches
|
|
8917
|
+
if (foundInd == -1) {
|
|
8918
|
+
//find all descendant oneof paths
|
|
8919
|
+
let descendantOneOfControlNames = Object.keys(this.jsf.formGroup.controls).filter(controlName => {
|
|
8920
|
+
return controlName.startsWith(controlKey);
|
|
8921
|
+
});
|
|
8922
|
+
descendantOneOfControlNames.forEach(controlName => {
|
|
8923
|
+
let parts = controlName.split('$');
|
|
8924
|
+
let fieldName = parts[parts.length - 1];
|
|
8925
|
+
let controlValue = this.jsf.formGroup.controls[controlName].value;
|
|
8926
|
+
let controlSchema = JsonPointer.get(this.jsf.schema, parts.join("/"));
|
|
8927
|
+
let schemaPointer = parts.join("/");
|
|
8928
|
+
let dPointer = schemaPointer.replace(/(anyOf|allOf|oneOf|none)\/[\d]+\//g, '')
|
|
8929
|
+
.replace(/(if|then|else|properties)\//g, '');
|
|
8930
|
+
//JsonPointer.toDataPointer(parts.join("/"),this.jsf.schema);
|
|
8931
|
+
let dVal = JsonPointer.get(this.jsf.formValues, dPointer);
|
|
8932
|
+
let compareVal = dVal; //formValue;
|
|
8933
|
+
//compare only values that are in the subschema properties
|
|
8934
|
+
if (controlSchema && controlSchema.properties) {
|
|
8935
|
+
compareVal = isObject$1(dVal) && hasOwn(dVal, fieldName) ?
|
|
8936
|
+
pick(dVal[fieldName], Object.keys(controlSchema.properties))
|
|
8937
|
+
: pick(dVal, Object.keys(controlSchema.properties));
|
|
8938
|
+
}
|
|
8939
|
+
/*
|
|
8940
|
+
if(isObject(compareVal) && hasOwn(compareVal,fieldName) &&
|
|
8941
|
+
isEqual(compareVal[fieldName],controlValue)
|
|
8942
|
+
){
|
|
8943
|
+
foundInd=ind;
|
|
8944
|
+
}else //if(formValue || controlValue){
|
|
8945
|
+
if(isEqual(compareVal,controlValue)){
|
|
8946
|
+
foundInd=ind;
|
|
8947
|
+
}
|
|
8948
|
+
*/
|
|
8949
|
+
if (isEqual$2(compareVal, controlValue)) {
|
|
8950
|
+
foundInd = ind;
|
|
8951
|
+
}
|
|
8952
|
+
});
|
|
8953
|
+
//now need to compare values
|
|
8954
|
+
}
|
|
8955
|
+
}
|
|
8956
|
+
});
|
|
8957
|
+
}
|
|
8958
|
+
return Math.max(foundInd, 0);
|
|
8959
|
+
}
|
|
7937
8960
|
updateValue(event) {
|
|
7938
8961
|
this.jsf.updateValue(this, event.target.value);
|
|
7939
8962
|
}
|
|
8963
|
+
ngOnDestroy() {
|
|
8964
|
+
//this.jsf.updateValue(this, null);
|
|
8965
|
+
}
|
|
7940
8966
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: OneOfComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7941
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: OneOfComponent, selector: "one-of-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template:
|
|
8967
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: OneOfComponent, selector: "one-of-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `<h4>{{this.options?.description}}</h4>
|
|
8968
|
+
<tabs-widget #tabs [layoutNode]="layoutNode"
|
|
8969
|
+
[layoutIndex]="layoutIndex"
|
|
8970
|
+
[dataIndex]="dataIndex" >
|
|
8971
|
+
</tabs-widget>`, isInline: true, dependencies: [{ kind: "component", type: TabsComponent, selector: "tabs-widget", inputs: ["layoutNode", "layoutIndex", "dataIndex"] }] }); }
|
|
7942
8972
|
}
|
|
7943
8973
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: OneOfComponent, decorators: [{
|
|
7944
8974
|
type: Component,
|
|
7945
8975
|
args: [{
|
|
7946
8976
|
// tslint:disable-next-line:component-selector
|
|
7947
8977
|
selector: 'one-of-widget',
|
|
7948
|
-
template:
|
|
8978
|
+
template: `<h4>{{this.options?.description}}</h4>
|
|
8979
|
+
<tabs-widget #tabs [layoutNode]="layoutNode"
|
|
8980
|
+
[layoutIndex]="layoutIndex"
|
|
8981
|
+
[dataIndex]="dataIndex" >
|
|
8982
|
+
</tabs-widget>`,
|
|
8983
|
+
standalone: false
|
|
7949
8984
|
}]
|
|
7950
8985
|
}], ctorParameters: function () { return [{ type: JsonSchemaFormService }]; }, propDecorators: { layoutNode: [{
|
|
7951
8986
|
type: Input
|
|
@@ -7975,6 +9010,9 @@ class RadiosComponent {
|
|
|
7975
9010
|
updateValue(event) {
|
|
7976
9011
|
this.jsf.updateValue(this, event.target.value);
|
|
7977
9012
|
}
|
|
9013
|
+
ngOnDestroy() {
|
|
9014
|
+
this.jsf.updateValue(this, null);
|
|
9015
|
+
}
|
|
7978
9016
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RadiosComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7979
9017
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: RadiosComponent, selector: "radios-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
7980
9018
|
<label *ngIf="options?.title"
|
|
@@ -8103,54 +9141,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
8103
9141
|
type: Input
|
|
8104
9142
|
}] } });
|
|
8105
9143
|
|
|
8106
|
-
class SelectFrameworkComponent {
|
|
8107
|
-
constructor(jsf) {
|
|
8108
|
-
this.jsf = jsf;
|
|
8109
|
-
this.newComponent = null;
|
|
8110
|
-
}
|
|
8111
|
-
ngOnInit() {
|
|
8112
|
-
this.updateComponent();
|
|
8113
|
-
}
|
|
8114
|
-
ngOnChanges() {
|
|
8115
|
-
this.updateComponent();
|
|
8116
|
-
}
|
|
8117
|
-
updateComponent() {
|
|
8118
|
-
const widgetContainer = this.widgetContainer;
|
|
8119
|
-
if (widgetContainer && !this.newComponent && this.jsf.framework) {
|
|
8120
|
-
this.newComponent = widgetContainer.createComponent((this.jsf.framework));
|
|
8121
|
-
//TODO fix all deprecated calls and test
|
|
8122
|
-
//this.widgetContainer.createComponent<any>(this.jsf.framework)
|
|
8123
|
-
}
|
|
8124
|
-
if (this.newComponent) {
|
|
8125
|
-
for (const input of ['layoutNode', 'layoutIndex', 'dataIndex']) {
|
|
8126
|
-
this.newComponent.instance[input] = this[input];
|
|
8127
|
-
}
|
|
8128
|
-
}
|
|
8129
|
-
}
|
|
8130
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectFrameworkComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8131
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SelectFrameworkComponent, selector: "select-framework-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, viewQueries: [{ propertyName: "widgetContainer", first: true, predicate: ["widgetContainer"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `<div #widgetContainer></div>`, isInline: true }); }
|
|
8132
|
-
}
|
|
8133
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectFrameworkComponent, decorators: [{
|
|
8134
|
-
type: Component,
|
|
8135
|
-
args: [{
|
|
8136
|
-
// tslint:disable-next-line:component-selector
|
|
8137
|
-
selector: 'select-framework-widget',
|
|
8138
|
-
template: `<div #widgetContainer></div>`,
|
|
8139
|
-
}]
|
|
8140
|
-
}], ctorParameters: function () { return [{ type: JsonSchemaFormService }]; }, propDecorators: { layoutNode: [{
|
|
8141
|
-
type: Input
|
|
8142
|
-
}], layoutIndex: [{
|
|
8143
|
-
type: Input
|
|
8144
|
-
}], dataIndex: [{
|
|
8145
|
-
type: Input
|
|
8146
|
-
}], widgetContainer: [{
|
|
8147
|
-
type: ViewChild,
|
|
8148
|
-
args: ['widgetContainer', {
|
|
8149
|
-
read: ViewContainerRef,
|
|
8150
|
-
static: true
|
|
8151
|
-
}]
|
|
8152
|
-
}] } });
|
|
8153
|
-
|
|
8154
9144
|
/**
|
|
8155
9145
|
* OrderableDirective
|
|
8156
9146
|
*
|
|
@@ -8303,11 +9293,74 @@ class RootComponent {
|
|
|
8303
9293
|
};
|
|
8304
9294
|
//must set moveLayout to false as nxtSortable already moves it
|
|
8305
9295
|
this.jsf.moveArrayItem(itemCtx, evt.oldIndex, evt.newIndex, false);
|
|
9296
|
+
},
|
|
9297
|
+
onMove: function (/**Event*/ evt, /**Event*/ originalEvent) {
|
|
9298
|
+
if (evt.related.classList.contains("sortable-fixed")) {
|
|
9299
|
+
//console.log(evt.related);
|
|
9300
|
+
return false;
|
|
9301
|
+
}
|
|
8306
9302
|
}
|
|
8307
9303
|
};
|
|
8308
9304
|
}
|
|
8309
9305
|
sortableInit(sortable) {
|
|
8310
9306
|
this.sortableObj = sortable;
|
|
9307
|
+
///NB issue caused by sortablejs when it its destroyed
|
|
9308
|
+
//this mainly affects checkboxes coupled with conditions
|
|
9309
|
+
//-the value is rechecked
|
|
9310
|
+
//-see https://github.com/SortableJS/Sortable/issues/1052#issuecomment-369613072
|
|
9311
|
+
/* attempt to monkey patch sortable js
|
|
9312
|
+
const originalMethod = sortable._nulling;
|
|
9313
|
+
let zone=this.zone;
|
|
9314
|
+
sortable._nulling=function() {
|
|
9315
|
+
console.log(`pluginEvent 2 ${pluginEvent}`)
|
|
9316
|
+
zone.runOutsideAngular(() => {
|
|
9317
|
+
console.log(`pluginEvent3 ${pluginEvent}`)
|
|
9318
|
+
pluginEvent('nulling', this);
|
|
9319
|
+
|
|
9320
|
+
rootEl =
|
|
9321
|
+
dragEl =
|
|
9322
|
+
parentEl =
|
|
9323
|
+
ghostEl =
|
|
9324
|
+
nextEl =
|
|
9325
|
+
cloneEl =
|
|
9326
|
+
lastDownEl =
|
|
9327
|
+
cloneHidden =
|
|
9328
|
+
|
|
9329
|
+
tapEvt =
|
|
9330
|
+
touchEvt =
|
|
9331
|
+
|
|
9332
|
+
moved =
|
|
9333
|
+
newIndex =
|
|
9334
|
+
newDraggableIndex =
|
|
9335
|
+
oldIndex =
|
|
9336
|
+
oldDraggableIndex =
|
|
9337
|
+
|
|
9338
|
+
lastTarget =
|
|
9339
|
+
lastDirection =
|
|
9340
|
+
|
|
9341
|
+
putSortable =
|
|
9342
|
+
activeGroup =
|
|
9343
|
+
Sortable.dragged =
|
|
9344
|
+
Sortable.ghost =
|
|
9345
|
+
Sortable.clone =
|
|
9346
|
+
Sortable.active = null;
|
|
9347
|
+
|
|
9348
|
+
|
|
9349
|
+
let el = this.el;
|
|
9350
|
+
savedInputChecked.forEach(function (checkEl) {
|
|
9351
|
+
if (el.contains(checkEl)) {
|
|
9352
|
+
checkEl.checked = true;
|
|
9353
|
+
}
|
|
9354
|
+
});
|
|
9355
|
+
|
|
9356
|
+
savedInputChecked.length =
|
|
9357
|
+
lastDx =
|
|
9358
|
+
lastDy = 0;
|
|
9359
|
+
|
|
9360
|
+
})
|
|
9361
|
+
|
|
9362
|
+
}.bind(sortable)
|
|
9363
|
+
*/
|
|
8311
9364
|
}
|
|
8312
9365
|
isDraggable(node) {
|
|
8313
9366
|
let result = node.arrayItem && node.type !== '$ref' &&
|
|
@@ -8319,6 +9372,12 @@ class RootComponent {
|
|
|
8319
9372
|
}
|
|
8320
9373
|
return result;
|
|
8321
9374
|
}
|
|
9375
|
+
//TODO also need to think of other types such as button which can be
|
|
9376
|
+
//created by an arbitrary layout
|
|
9377
|
+
isFixed(node) {
|
|
9378
|
+
let result = node.type == '$ref';
|
|
9379
|
+
return result;
|
|
9380
|
+
}
|
|
8322
9381
|
// Set attributes for flexbox child
|
|
8323
9382
|
// (container attributes are set in section.component)
|
|
8324
9383
|
getFlexAttribute(node, attribute) {
|
|
@@ -8358,6 +9417,7 @@ class RootComponent {
|
|
|
8358
9417
|
[style.flex-shrink]="getFlexAttribute(layoutItem, 'flex-shrink')"
|
|
8359
9418
|
[style.order]="(layoutItem.options || {}).order"
|
|
8360
9419
|
[class.sortable-filter]="!isDraggable(layoutItem)"
|
|
9420
|
+
[class.sortable-fixed]="isFixed(layoutItem)"
|
|
8361
9421
|
>
|
|
8362
9422
|
<!--NB orderable directive is not used but has been left in for now and set to false
|
|
8363
9423
|
otherwise the compiler won't recognize dataIndex and other dependent attributes
|
|
@@ -8368,6 +9428,7 @@ class RootComponent {
|
|
|
8368
9428
|
[layoutNode]="layoutItem"
|
|
8369
9429
|
[orderable]="false"
|
|
8370
9430
|
[class.sortable-filter]="!isDraggable(layoutItem)"
|
|
9431
|
+
[class.sortable-fixed]="isFixed(layoutItem)"
|
|
8371
9432
|
>
|
|
8372
9433
|
<select-framework-widget *ngIf="showWidget(layoutItem)"
|
|
8373
9434
|
[dataIndex]="layoutItem?.arrayItem ? (dataIndex || []).concat(i) : (dataIndex || [])"
|
|
@@ -8390,6 +9451,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
8390
9451
|
[style.flex-shrink]="getFlexAttribute(layoutItem, 'flex-shrink')"
|
|
8391
9452
|
[style.order]="(layoutItem.options || {}).order"
|
|
8392
9453
|
[class.sortable-filter]="!isDraggable(layoutItem)"
|
|
9454
|
+
[class.sortable-fixed]="isFixed(layoutItem)"
|
|
8393
9455
|
>
|
|
8394
9456
|
<!--NB orderable directive is not used but has been left in for now and set to false
|
|
8395
9457
|
otherwise the compiler won't recognize dataIndex and other dependent attributes
|
|
@@ -8400,6 +9462,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
8400
9462
|
[layoutNode]="layoutItem"
|
|
8401
9463
|
[orderable]="false"
|
|
8402
9464
|
[class.sortable-filter]="!isDraggable(layoutItem)"
|
|
9465
|
+
[class.sortable-fixed]="isFixed(layoutItem)"
|
|
8403
9466
|
>
|
|
8404
9467
|
<select-framework-widget *ngIf="showWidget(layoutItem)"
|
|
8405
9468
|
[dataIndex]="layoutItem?.arrayItem ? (dataIndex || []).concat(i) : (dataIndex || [])"
|
|
@@ -8621,15 +9684,46 @@ class SelectComponent {
|
|
|
8621
9684
|
this.controlDisabled = false;
|
|
8622
9685
|
this.boundControl = false;
|
|
8623
9686
|
this.selectList = [];
|
|
9687
|
+
this.selectListFlatGroup = [];
|
|
8624
9688
|
this.isArray = isArray;
|
|
8625
9689
|
}
|
|
8626
9690
|
ngOnInit() {
|
|
8627
9691
|
this.options = this.layoutNode.options || {};
|
|
8628
9692
|
this.selectList = buildTitleMap(this.options.titleMap || this.options.enumNames, this.options.enum, !!this.options.required, !!this.options.flatList);
|
|
9693
|
+
//the selectListFlatGroup array will be used to update the formArray values
|
|
9694
|
+
//while the selectList array will be bound to the form select
|
|
9695
|
+
//as either a grouped select or a flat select
|
|
9696
|
+
this.selectListFlatGroup = buildTitleMap(this.options.titleMap || this.options.enumNames, this.options.enum, !!this.options.required, true);
|
|
8629
9697
|
this.jsf.initializeControl(this);
|
|
8630
9698
|
}
|
|
9699
|
+
deselectAll() {
|
|
9700
|
+
this.selectListFlatGroup.forEach(selItem => {
|
|
9701
|
+
selItem.checked = false;
|
|
9702
|
+
});
|
|
9703
|
+
}
|
|
8631
9704
|
updateValue(event) {
|
|
8632
|
-
this.
|
|
9705
|
+
this.options.showErrors = true;
|
|
9706
|
+
if (this.options.multiple) {
|
|
9707
|
+
if (this.controlValue?.includes(null)) {
|
|
9708
|
+
this.deselectAll();
|
|
9709
|
+
//this.control.setValue([]); // Reset the form control to an empty array
|
|
9710
|
+
//this.selectList=JSON.parse(JSON.stringify(this.selectList));
|
|
9711
|
+
this.jsf.updateArrayMultiSelectList(this, []);
|
|
9712
|
+
}
|
|
9713
|
+
else {
|
|
9714
|
+
this.selectListFlatGroup.forEach(selItem => {
|
|
9715
|
+
selItem.checked = this.controlValue?.indexOf(selItem.value) >= 0 ? true : false;
|
|
9716
|
+
});
|
|
9717
|
+
this.jsf.updateArrayMultiSelectList(this, this.selectListFlatGroup);
|
|
9718
|
+
}
|
|
9719
|
+
return;
|
|
9720
|
+
}
|
|
9721
|
+
this.jsf.updateValue(this, this.controlValue);
|
|
9722
|
+
}
|
|
9723
|
+
ngOnDestroy() {
|
|
9724
|
+
let nullVal = this.options.multiple ? [null] : null;
|
|
9725
|
+
this.formControl.reset(nullVal);
|
|
9726
|
+
this.controlValue = null;
|
|
8633
9727
|
}
|
|
8634
9728
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8635
9729
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SelectComponent, selector: "select-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
@@ -8640,7 +9734,7 @@ class SelectComponent {
|
|
|
8640
9734
|
[class]="options?.labelHtmlClass || ''"
|
|
8641
9735
|
[style.display]="options?.notitle ? 'none' : ''"
|
|
8642
9736
|
[innerHTML]="options?.title"></label>
|
|
8643
|
-
<select *ngIf="boundControl"
|
|
9737
|
+
<select *ngIf="boundControl && !options?.multiple"
|
|
8644
9738
|
[formControl]="formControl"
|
|
8645
9739
|
[attr.aria-describedby]="'control' + layoutNode?._id + 'Status'"
|
|
8646
9740
|
[attr.readonly]="options?.readonly ? 'readonly' : null"
|
|
@@ -8687,7 +9781,34 @@ class SelectComponent {
|
|
|
8687
9781
|
</optgroup>
|
|
8688
9782
|
</ng-template>
|
|
8689
9783
|
</select>
|
|
8690
|
-
|
|
9784
|
+
<select *ngIf="boundControl && options?.multiple"
|
|
9785
|
+
[attr.aria-describedby]="'control' + layoutNode?._id + 'Status'"
|
|
9786
|
+
[attr.readonly]="options?.readonly ? 'readonly' : null"
|
|
9787
|
+
[attr.required]="options?.required"
|
|
9788
|
+
[class]="options?.fieldHtmlClass || ''"
|
|
9789
|
+
[disabled]="controlDisabled"
|
|
9790
|
+
[id]="'control' + layoutNode?._id"
|
|
9791
|
+
[multiple]="options?.multiple"
|
|
9792
|
+
[name]="controlName"
|
|
9793
|
+
[(ngModel)]="controlValue"
|
|
9794
|
+
(change)="updateValue($event)">
|
|
9795
|
+
<ng-template ngFor let-selectItem [ngForOf]="selectList">
|
|
9796
|
+
<option *ngIf="!isArray(selectItem?.items)"
|
|
9797
|
+
[selected]="selectItem?.value === controlValue"
|
|
9798
|
+
[value]="selectItem?.value">
|
|
9799
|
+
<span [innerHTML]="selectItem?.name"></span>
|
|
9800
|
+
</option>
|
|
9801
|
+
<optgroup *ngIf="isArray(selectItem?.items)"
|
|
9802
|
+
[label]="selectItem?.group">
|
|
9803
|
+
<option *ngFor="let subItem of selectItem.items"
|
|
9804
|
+
[attr.selected]="subItem?.value === controlValue"
|
|
9805
|
+
[value]="subItem?.value">
|
|
9806
|
+
<span [innerHTML]="subItem?.name"></span>
|
|
9807
|
+
</option>
|
|
9808
|
+
</optgroup>
|
|
9809
|
+
</ng-template>
|
|
9810
|
+
</select>
|
|
9811
|
+
</div>`, isInline: true, dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.SelectMultipleControlValueAccessor, selector: "select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
|
|
8691
9812
|
}
|
|
8692
9813
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectComponent, decorators: [{
|
|
8693
9814
|
type: Component,
|
|
@@ -8702,7 +9823,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
8702
9823
|
[class]="options?.labelHtmlClass || ''"
|
|
8703
9824
|
[style.display]="options?.notitle ? 'none' : ''"
|
|
8704
9825
|
[innerHTML]="options?.title"></label>
|
|
8705
|
-
<select *ngIf="boundControl"
|
|
9826
|
+
<select *ngIf="boundControl && !options?.multiple"
|
|
8706
9827
|
[formControl]="formControl"
|
|
8707
9828
|
[attr.aria-describedby]="'control' + layoutNode?._id + 'Status'"
|
|
8708
9829
|
[attr.readonly]="options?.readonly ? 'readonly' : null"
|
|
@@ -8749,6 +9870,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
8749
9870
|
</optgroup>
|
|
8750
9871
|
</ng-template>
|
|
8751
9872
|
</select>
|
|
9873
|
+
<select *ngIf="boundControl && options?.multiple"
|
|
9874
|
+
[attr.aria-describedby]="'control' + layoutNode?._id + 'Status'"
|
|
9875
|
+
[attr.readonly]="options?.readonly ? 'readonly' : null"
|
|
9876
|
+
[attr.required]="options?.required"
|
|
9877
|
+
[class]="options?.fieldHtmlClass || ''"
|
|
9878
|
+
[disabled]="controlDisabled"
|
|
9879
|
+
[id]="'control' + layoutNode?._id"
|
|
9880
|
+
[multiple]="options?.multiple"
|
|
9881
|
+
[name]="controlName"
|
|
9882
|
+
[(ngModel)]="controlValue"
|
|
9883
|
+
(change)="updateValue($event)">
|
|
9884
|
+
<ng-template ngFor let-selectItem [ngForOf]="selectList">
|
|
9885
|
+
<option *ngIf="!isArray(selectItem?.items)"
|
|
9886
|
+
[selected]="selectItem?.value === controlValue"
|
|
9887
|
+
[value]="selectItem?.value">
|
|
9888
|
+
<span [innerHTML]="selectItem?.name"></span>
|
|
9889
|
+
</option>
|
|
9890
|
+
<optgroup *ngIf="isArray(selectItem?.items)"
|
|
9891
|
+
[label]="selectItem?.group">
|
|
9892
|
+
<option *ngFor="let subItem of selectItem.items"
|
|
9893
|
+
[attr.selected]="subItem?.value === controlValue"
|
|
9894
|
+
[value]="subItem?.value">
|
|
9895
|
+
<span [innerHTML]="subItem?.name"></span>
|
|
9896
|
+
</option>
|
|
9897
|
+
</optgroup>
|
|
9898
|
+
</ng-template>
|
|
9899
|
+
</select>
|
|
8752
9900
|
</div>`,
|
|
8753
9901
|
}]
|
|
8754
9902
|
}], ctorParameters: function () { return [{ type: JsonSchemaFormService }]; }, propDecorators: { layoutNode: [{
|
|
@@ -8768,6 +9916,7 @@ class SubmitComponent {
|
|
|
8768
9916
|
ngOnDestroy() {
|
|
8769
9917
|
this.isValidChangesSubs?.unsubscribe();
|
|
8770
9918
|
this.isValidChangesSubs = null;
|
|
9919
|
+
this.updateValue({ target: { value: null } });
|
|
8771
9920
|
}
|
|
8772
9921
|
ngOnInit() {
|
|
8773
9922
|
this.options = this.layoutNode.options || {};
|
|
@@ -8874,109 +10023,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
8874
10023
|
type: Input
|
|
8875
10024
|
}] } });
|
|
8876
10025
|
|
|
8877
|
-
class TabsComponent {
|
|
8878
|
-
constructor(jsf) {
|
|
8879
|
-
this.jsf = jsf;
|
|
8880
|
-
this.selectedItem = 0;
|
|
8881
|
-
this.showAddTab = true;
|
|
8882
|
-
}
|
|
8883
|
-
ngOnInit() {
|
|
8884
|
-
this.options = this.layoutNode.options || {};
|
|
8885
|
-
this.itemCount = this.layoutNode.items.length - 1;
|
|
8886
|
-
this.updateControl();
|
|
8887
|
-
}
|
|
8888
|
-
select(index) {
|
|
8889
|
-
if (this.layoutNode.items[index].type === '$ref') {
|
|
8890
|
-
this.itemCount = this.layoutNode.items.length;
|
|
8891
|
-
this.jsf.addItem({
|
|
8892
|
-
layoutNode: this.layoutNode.items[index],
|
|
8893
|
-
layoutIndex: this.layoutIndex.concat(index),
|
|
8894
|
-
dataIndex: this.dataIndex.concat(index)
|
|
8895
|
-
});
|
|
8896
|
-
this.updateControl();
|
|
8897
|
-
}
|
|
8898
|
-
this.selectedItem = index;
|
|
8899
|
-
}
|
|
8900
|
-
updateControl() {
|
|
8901
|
-
const lastItem = this.layoutNode.items[this.layoutNode.items.length - 1];
|
|
8902
|
-
if (lastItem.type === '$ref' &&
|
|
8903
|
-
this.itemCount >= (lastItem.options.maxItems || 1000)) {
|
|
8904
|
-
this.showAddTab = false;
|
|
8905
|
-
}
|
|
8906
|
-
}
|
|
8907
|
-
setTabTitle(item, index) {
|
|
8908
|
-
return this.jsf.setArrayItemTitle(this, item, index);
|
|
8909
|
-
}
|
|
8910
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TabsComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8911
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TabsComponent, selector: "tabs-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
8912
|
-
<ul
|
|
8913
|
-
[class]="options?.labelHtmlClass || ''">
|
|
8914
|
-
<li *ngFor="let item of layoutNode?.items; let i = index"
|
|
8915
|
-
[class]="(options?.itemLabelHtmlClass || '') + (selectedItem === i ?
|
|
8916
|
-
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
8917
|
-
(' ' + options?.style?.unselected))"
|
|
8918
|
-
role="presentation"
|
|
8919
|
-
data-tabs>
|
|
8920
|
-
<a *ngIf="showAddTab || item.type !== '$ref'"
|
|
8921
|
-
[class]="'nav-link' + (selectedItem === i ? (' ' + options?.activeClass + ' ' + options?.style?.selected) :
|
|
8922
|
-
(' ' + options?.style?.unselected))"
|
|
8923
|
-
[innerHTML]="setTabTitle(item, i)"
|
|
8924
|
-
(click)="select(i)"></a>
|
|
8925
|
-
</li>
|
|
8926
|
-
</ul>
|
|
8927
|
-
|
|
8928
|
-
<div *ngFor="let layoutItem of layoutNode?.items; let i = index"
|
|
8929
|
-
[class]="options?.htmlClass || ''">
|
|
8930
|
-
|
|
8931
|
-
<select-framework-widget *ngIf="selectedItem === i"
|
|
8932
|
-
[class]="(options?.fieldHtmlClass || '') +
|
|
8933
|
-
' ' + (options?.activeClass || '') +
|
|
8934
|
-
' ' + (options?.style?.selected || '')"
|
|
8935
|
-
[dataIndex]="layoutNode?.dataType === 'array' ? (dataIndex || []).concat(i) : dataIndex"
|
|
8936
|
-
[layoutIndex]="(layoutIndex || []).concat(i)"
|
|
8937
|
-
[layoutNode]="layoutItem"></select-framework-widget>
|
|
8938
|
-
|
|
8939
|
-
</div>`, isInline: true, styles: ["a{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: SelectFrameworkComponent, selector: "select-framework-widget", inputs: ["layoutNode", "layoutIndex", "dataIndex"] }] }); }
|
|
8940
|
-
}
|
|
8941
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TabsComponent, decorators: [{
|
|
8942
|
-
type: Component,
|
|
8943
|
-
args: [{ selector: 'tabs-widget', template: `
|
|
8944
|
-
<ul
|
|
8945
|
-
[class]="options?.labelHtmlClass || ''">
|
|
8946
|
-
<li *ngFor="let item of layoutNode?.items; let i = index"
|
|
8947
|
-
[class]="(options?.itemLabelHtmlClass || '') + (selectedItem === i ?
|
|
8948
|
-
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
8949
|
-
(' ' + options?.style?.unselected))"
|
|
8950
|
-
role="presentation"
|
|
8951
|
-
data-tabs>
|
|
8952
|
-
<a *ngIf="showAddTab || item.type !== '$ref'"
|
|
8953
|
-
[class]="'nav-link' + (selectedItem === i ? (' ' + options?.activeClass + ' ' + options?.style?.selected) :
|
|
8954
|
-
(' ' + options?.style?.unselected))"
|
|
8955
|
-
[innerHTML]="setTabTitle(item, i)"
|
|
8956
|
-
(click)="select(i)"></a>
|
|
8957
|
-
</li>
|
|
8958
|
-
</ul>
|
|
8959
|
-
|
|
8960
|
-
<div *ngFor="let layoutItem of layoutNode?.items; let i = index"
|
|
8961
|
-
[class]="options?.htmlClass || ''">
|
|
8962
|
-
|
|
8963
|
-
<select-framework-widget *ngIf="selectedItem === i"
|
|
8964
|
-
[class]="(options?.fieldHtmlClass || '') +
|
|
8965
|
-
' ' + (options?.activeClass || '') +
|
|
8966
|
-
' ' + (options?.style?.selected || '')"
|
|
8967
|
-
[dataIndex]="layoutNode?.dataType === 'array' ? (dataIndex || []).concat(i) : dataIndex"
|
|
8968
|
-
[layoutIndex]="(layoutIndex || []).concat(i)"
|
|
8969
|
-
[layoutNode]="layoutItem"></select-framework-widget>
|
|
8970
|
-
|
|
8971
|
-
</div>`, styles: ["a{cursor:pointer}\n"] }]
|
|
8972
|
-
}], ctorParameters: function () { return [{ type: JsonSchemaFormService }]; }, propDecorators: { layoutNode: [{
|
|
8973
|
-
type: Input
|
|
8974
|
-
}], layoutIndex: [{
|
|
8975
|
-
type: Input
|
|
8976
|
-
}], dataIndex: [{
|
|
8977
|
-
type: Input
|
|
8978
|
-
}] } });
|
|
8979
|
-
|
|
8980
10026
|
class TemplateComponent {
|
|
8981
10027
|
constructor(jsf) {
|
|
8982
10028
|
this.jsf = jsf;
|
|
@@ -9034,6 +10080,9 @@ class TextareaComponent {
|
|
|
9034
10080
|
updateValue(event) {
|
|
9035
10081
|
this.jsf.updateValue(this, event.target.value);
|
|
9036
10082
|
}
|
|
10083
|
+
ngOnDestroy() {
|
|
10084
|
+
this.jsf.updateValue(this, null);
|
|
10085
|
+
}
|
|
9037
10086
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TextareaComponent, deps: [{ token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9038
10087
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TextareaComponent, selector: "textarea-widget", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, ngImport: i0, template: `
|
|
9039
10088
|
<div
|
|
@@ -9340,7 +10389,13 @@ class WidgetLibraryModule {
|
|
|
9340
10389
|
//disabled:false,
|
|
9341
10390
|
//draggable:".draggableitem",//">:not(.nonsort)",//">.draggable-item",//":not(.nonsort)",//">*",//":not(.nonsort)",//":not(.non-draggable)",
|
|
9342
10391
|
filter: ".sortable-filter",
|
|
9343
|
-
preventOnFilter: false
|
|
10392
|
+
preventOnFilter: false,
|
|
10393
|
+
onMove: function (/**Event*/ evt, /**Event*/ originalEvent) {
|
|
10394
|
+
if (evt.related.classList.contains("sortable-fixed")) {
|
|
10395
|
+
//console.log(evt.related);
|
|
10396
|
+
return false;
|
|
10397
|
+
}
|
|
10398
|
+
}
|
|
9344
10399
|
})] }); }
|
|
9345
10400
|
}
|
|
9346
10401
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: WidgetLibraryModule, decorators: [{
|
|
@@ -9351,7 +10406,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
9351
10406
|
//disabled:false,
|
|
9352
10407
|
//draggable:".draggableitem",//">:not(.nonsort)",//">.draggable-item",//":not(.nonsort)",//">*",//":not(.nonsort)",//":not(.non-draggable)",
|
|
9353
10408
|
filter: ".sortable-filter",
|
|
9354
|
-
preventOnFilter: false
|
|
10409
|
+
preventOnFilter: false,
|
|
10410
|
+
onMove: function (/**Event*/ evt, /**Event*/ originalEvent) {
|
|
10411
|
+
if (evt.related.classList.contains("sortable-fixed")) {
|
|
10412
|
+
//console.log(evt.related);
|
|
10413
|
+
return false;
|
|
10414
|
+
}
|
|
10415
|
+
}
|
|
9355
10416
|
})],
|
|
9356
10417
|
declarations: [...BASIC_WIDGETS, OrderableDirective, ElementAttributeDirective],
|
|
9357
10418
|
exports: [...BASIC_WIDGETS, OrderableDirective, ElementAttributeDirective]
|
|
@@ -9604,7 +10665,7 @@ class JsonSchemaFormComponent {
|
|
|
9604
10665
|
this.previousInputs = {
|
|
9605
10666
|
schema: null, layout: null, data: null, options: null, framework: null,
|
|
9606
10667
|
widgets: null, form: null, model: null, JSONSchema: null, UISchema: null,
|
|
9607
|
-
formData: null, loadExternalAssets: null, debug: null,
|
|
10668
|
+
formData: null, loadExternalAssets: null, debug: null, ajvOptions: null
|
|
9608
10669
|
};
|
|
9609
10670
|
// Outputs
|
|
9610
10671
|
this.onChanges = new EventEmitter(); // Live unvalidated internal form data
|
|
@@ -9810,6 +10871,7 @@ class JsonSchemaFormComponent {
|
|
|
9810
10871
|
this.jsf.data) {
|
|
9811
10872
|
// Reset all form values to defaults
|
|
9812
10873
|
this.jsf.resetAllValues();
|
|
10874
|
+
this.initializeAjv();
|
|
9813
10875
|
this.initializeOptions(); // Update options
|
|
9814
10876
|
this.initializeSchema(); // Update schema, schemaRefLibrary,
|
|
9815
10877
|
// schemaRecursiveRefMap, & dataRecursiveRefMap
|
|
@@ -9860,6 +10922,20 @@ class JsonSchemaFormComponent {
|
|
|
9860
10922
|
this.formInitialized = true;
|
|
9861
10923
|
}
|
|
9862
10924
|
}
|
|
10925
|
+
/**
|
|
10926
|
+
* 'initializeAjv' function
|
|
10927
|
+
*
|
|
10928
|
+
* Initialize ajv from 'ajvOptions'
|
|
10929
|
+
*/
|
|
10930
|
+
initializeAjv() {
|
|
10931
|
+
const form = this.form;
|
|
10932
|
+
const ajvOptions = cloneDeep(this.ajvOptions) ||
|
|
10933
|
+
(form && hasOwn(form, 'ajvOptions') && isObject(form.ajvOptions)
|
|
10934
|
+
&& cloneDeep(form.ajvOptions));
|
|
10935
|
+
if (ajvOptions) {
|
|
10936
|
+
this.ajvInstanceName = this.jsf.createAndRegisterAjvInstance(ajvOptions).name;
|
|
10937
|
+
}
|
|
10938
|
+
}
|
|
9863
10939
|
/**
|
|
9864
10940
|
* 'initializeOptions' function
|
|
9865
10941
|
*
|
|
@@ -9975,7 +11051,8 @@ class JsonSchemaFormComponent {
|
|
|
9975
11051
|
// draft 3 (JSON Form style) and draft 4 (Angular Schema Form style)
|
|
9976
11052
|
this.jsf.schema = convertSchemaToDraft6(this.jsf.schema);
|
|
9977
11053
|
// Initialize ajv and compile schema
|
|
9978
|
-
this.jsf.compileAjvSchema();
|
|
11054
|
+
//this.jsf.compileAjvSchema();
|
|
11055
|
+
//moved to initializeAjv()
|
|
9979
11056
|
// Create schemaRefLibrary, schemaRecursiveRefMap, dataRecursiveRefMap, & arrayMap
|
|
9980
11057
|
this.jsf.schema = resolveSchemaReferences(this.jsf.schema, this.jsf.schemaRefLibrary, this.jsf.schemaRecursiveRefMap, this.jsf.dataRecursiveRefMap, this.jsf.arrayMap);
|
|
9981
11058
|
if (hasOwn(this.jsf.schemaRefLibrary, '')) {
|
|
@@ -10171,7 +11248,8 @@ class JsonSchemaFormComponent {
|
|
|
10171
11248
|
}
|
|
10172
11249
|
if (!isEmpty(this.jsf.schema)) {
|
|
10173
11250
|
// If not already initialized, initialize ajv and compile schema
|
|
10174
|
-
this.jsf.compileAjvSchema();
|
|
11251
|
+
//this.jsf.compileAjvSchema();
|
|
11252
|
+
//moved to initializeAjv()
|
|
10175
11253
|
// Update all layout elements, add values, widgets, and validators,
|
|
10176
11254
|
// replace any '*' with a layout built from all schema elements,
|
|
10177
11255
|
// and update the FormGroup template with any new validators
|
|
@@ -10179,7 +11257,7 @@ class JsonSchemaFormComponent {
|
|
|
10179
11257
|
// Build the Angular FormGroup template from the schema
|
|
10180
11258
|
this.jsf.buildFormGroupTemplate(this.jsf.formValues);
|
|
10181
11259
|
// Build the real Angular FormGroup from the FormGroup template
|
|
10182
|
-
this.jsf.buildFormGroup();
|
|
11260
|
+
this.jsf.buildFormGroup(this.ajvInstanceName);
|
|
10183
11261
|
}
|
|
10184
11262
|
if (this.jsf.formGroup) {
|
|
10185
11263
|
// Reset initial form values
|
|
@@ -10230,7 +11308,7 @@ class JsonSchemaFormComponent {
|
|
|
10230
11308
|
}
|
|
10231
11309
|
}
|
|
10232
11310
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: JsonSchemaFormComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: FrameworkLibraryService }, { token: WidgetLibraryService }, { token: JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10233
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: JsonSchemaFormComponent, selector: "json-schema-form", inputs: { schema: "schema", layout: "layout", data: "data", options: "options", framework: "framework", widgets: "widgets", form: "form", model: "model", JSONSchema: "JSONSchema", UISchema: "UISchema", formData: "formData", ngModel: "ngModel", language: "language", loadExternalAssets: "loadExternalAssets", debug: "debug", theme: "theme", value: "value" }, outputs: { onChanges: "onChanges", onSubmit: "onSubmit", isValid: "isValid", validationErrors: "validationErrors", formSchema: "formSchema", formLayout: "formLayout", dataChange: "dataChange", modelChange: "modelChange", formDataChange: "formDataChange", ngModelChange: "ngModelChange" }, providers: [JsonSchemaFormService, JSON_SCHEMA_FORM_VALUE_ACCESSOR], usesOnChanges: true, ngImport: i0, template: "<form [autocomplete]=\"jsf?.formOptions?.autocomplete ? 'on' : 'off'\" class=\"json-schema-form\" (ngSubmit)=\"submitForm()\">\r\n <root-widget [layout]=\"jsf?.layout\"></root-widget>\r\n</form>\r\n<div *ngIf=\"debug || jsf?.formOptions?.debug\">\r\n Debug output:\r\n <pre>{{debugOutput}}</pre>\r\n</div>", dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: RootComponent, selector: "root-widget", inputs: ["dataIndex", "layoutIndex", "layout", "isOrderable", "isFlexItem"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
11311
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: JsonSchemaFormComponent, selector: "json-schema-form", inputs: { schema: "schema", layout: "layout", data: "data", options: "options", framework: "framework", widgets: "widgets", form: "form", model: "model", JSONSchema: "JSONSchema", UISchema: "UISchema", formData: "formData", ngModel: "ngModel", language: "language", loadExternalAssets: "loadExternalAssets", debug: "debug", theme: "theme", ajvOptions: "ajvOptions", value: "value" }, outputs: { onChanges: "onChanges", onSubmit: "onSubmit", isValid: "isValid", validationErrors: "validationErrors", formSchema: "formSchema", formLayout: "formLayout", dataChange: "dataChange", modelChange: "modelChange", formDataChange: "formDataChange", ngModelChange: "ngModelChange" }, providers: [JsonSchemaFormService, JSON_SCHEMA_FORM_VALUE_ACCESSOR], usesOnChanges: true, ngImport: i0, template: "<form [autocomplete]=\"jsf?.formOptions?.autocomplete ? 'on' : 'off'\" class=\"json-schema-form\" (ngSubmit)=\"submitForm()\">\r\n <root-widget [layout]=\"jsf?.layout\"></root-widget>\r\n</form>\r\n<div *ngIf=\"debug || jsf?.formOptions?.debug\">\r\n Debug output:\r\n <pre>{{debugOutput}}</pre>\r\n</div>", dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: RootComponent, selector: "root-widget", inputs: ["dataIndex", "layoutIndex", "layout", "isOrderable", "isFlexItem"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
10234
11312
|
}
|
|
10235
11313
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: JsonSchemaFormComponent, decorators: [{
|
|
10236
11314
|
type: Component,
|
|
@@ -10267,6 +11345,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
10267
11345
|
type: Input
|
|
10268
11346
|
}], theme: [{
|
|
10269
11347
|
type: Input
|
|
11348
|
+
}], ajvOptions: [{
|
|
11349
|
+
type: Input
|
|
10270
11350
|
}], value: [{
|
|
10271
11351
|
type: Input
|
|
10272
11352
|
}], onChanges: [{
|
|
@@ -10318,5 +11398,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
10318
11398
|
* Generated bundle index. Do not edit.
|
|
10319
11399
|
*/
|
|
10320
11400
|
|
|
10321
|
-
export { AddReferenceComponent, BASIC_WIDGETS, ButtonComponent, CheckboxComponent, CheckboxesComponent, ElementAttributeDirective, FileComponent, Framework, FrameworkLibraryService, HiddenComponent, InputComponent, JsonPointer, JsonSchemaFormComponent, JsonSchemaFormModule, JsonSchemaFormService, JsonValidators, MessageComponent, NoneComponent, NumberComponent, OneOfComponent, OrderableDirective, RadiosComponent, RootComponent, SectionComponent, SelectComponent, SelectFrameworkComponent, SelectWidgetComponent, SubmitComponent, TabComponent, TabsComponent, TemplateComponent, TextareaComponent, WidgetLibraryModule, WidgetLibraryService, _executeAsyncValidators, _executeValidators, _mergeErrors, _mergeObjects, _toPromise, addClasses, buildFormGroup, buildFormGroupTemplate, buildLayout, buildLayoutFromSchema, buildSchemaFromData, buildSchemaFromLayout, buildTitleMap, checkInlineType, combineAllOf, commonItems, convertSchemaToDraft6, copy, deValidationMessages, enValidationMessages, esValidationMessages, fixRequiredArrayProperties, fixTitle, forEach, forEachCopy, formatFormData, frValidationMessages, getControl, getControlValidators, getFromSchema, getInputType, getLayoutNode, getSubSchema, getTitleMapFromOneOf, getType, hasOwn, hasValue, inArray, isArray, isBoolean, isDate, isDefined, isEmpty, isFunction, isInputRequired, isInteger, isMap, isNumber, isObject, isObservable, isPrimitive, isPromise, isSet, isString, isType, itValidationMessages, mapLayout, mergeFilteredObject, mergeSchemas, ptValidationMessages, removeRecursiveReferences, resolveSchemaReferences, setRequiredFields, toJavaScriptType, toObservable, toSchemaType, toTitleCase, uniqueItems, updateInputOptions, xor, zhValidationMessages };
|
|
11401
|
+
export { AddReferenceComponent, BASIC_WIDGETS, ButtonComponent, CheckboxComponent, CheckboxesComponent, ElementAttributeDirective, FileComponent, Framework, FrameworkLibraryService, HiddenComponent, InputComponent, JsonPointer, JsonSchemaFormComponent, JsonSchemaFormModule, JsonSchemaFormService, JsonValidators, MessageComponent, NoneComponent, NumberComponent, OneOfComponent, OrderableDirective, RadiosComponent, RootComponent, SectionComponent, SelectComponent, SelectFrameworkComponent, SelectWidgetComponent, SubmitComponent, TabComponent, TabsComponent, TemplateComponent, TextareaComponent, WidgetLibraryModule, WidgetLibraryService, _executeAsyncValidators, _executeValidators, _mergeErrors, _mergeObjects, _toPromise, addClasses, buildFormGroup, buildFormGroupTemplate, buildLayout, buildLayoutFromSchema, buildSchemaFromData, buildSchemaFromLayout, buildTitleMap, checkInlineType, combineAllOf, commonItems, convertSchemaToDraft6, copy, deValidationMessages, enValidationMessages, esValidationMessages, fixRequiredArrayProperties, fixTitle, forEach, forEachCopy, formatFormData, frValidationMessages, getControl, getControlValidators, getFromSchema, getInputType, getLayoutNode, getSubSchema, getTitleMapFromOneOf, getType, hasNonNullValue, hasOwn, hasValue, inArray, isArray, isBoolean, isDate, isDefined, isEmpty, isFunction, isInputRequired, isInteger, isMap, isNumber, isObject, isObservable, isPrimitive, isPromise, isSet, isString, isType, itValidationMessages, mapLayout, mergeFilteredObject, mergeSchemas, path2ControlKey, ptValidationMessages, removeRecursiveReferences, resolveSchemaReferences, setControl, setRequiredFields, toJavaScriptType, toObservable, toSchemaType, toTitleCase, uniqueItems, updateInputOptions, xor, zhValidationMessages };
|
|
10322
11402
|
//# sourceMappingURL=ng-formworks-core.mjs.map
|