@dmitryvim/form-builder 0.5.2 → 0.5.3
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/dist/browser/formbuilder.min.js +101 -101
- package/dist/browser/{formbuilder.v0.5.2.min.js → formbuilder.v0.5.3.min.js} +101 -101
- package/dist/cjs/index.cjs +193 -98
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +188 -95
- package/dist/esm/index.js.map +1 -1
- package/dist/form-builder.js +101 -101
- package/dist/types/components/container.d.ts +1 -0
- package/dist/types/types/config.d.ts +2 -0
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -15,6 +15,71 @@ function t(key, state, params) {
|
|
|
15
15
|
return text;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
// src/utils/helpers.ts
|
|
19
|
+
function isElementReadonly(element, state, ctx) {
|
|
20
|
+
return element.readonly === true || state.config.readonly === true || ctx?.inheritedReadonly === true;
|
|
21
|
+
}
|
|
22
|
+
function isPlainObject(obj) {
|
|
23
|
+
return obj && typeof obj === "object" && obj.constructor === Object;
|
|
24
|
+
}
|
|
25
|
+
function escapeHtml(text) {
|
|
26
|
+
const div = document.createElement("div");
|
|
27
|
+
div.textContent = text;
|
|
28
|
+
return div.innerHTML;
|
|
29
|
+
}
|
|
30
|
+
function getElementLookupKey(element, state) {
|
|
31
|
+
if (element.key) {
|
|
32
|
+
return element.key;
|
|
33
|
+
}
|
|
34
|
+
const cached = state.syntheticElementIds.get(element);
|
|
35
|
+
if (cached !== void 0) {
|
|
36
|
+
return cached;
|
|
37
|
+
}
|
|
38
|
+
const id = `fb-synthetic-${state.syntheticElementIdCounter++}`;
|
|
39
|
+
state.syntheticElementIds.set(element, id);
|
|
40
|
+
return id;
|
|
41
|
+
}
|
|
42
|
+
function pathJoin(base, key) {
|
|
43
|
+
return base ? `${base}.${key}` : key;
|
|
44
|
+
}
|
|
45
|
+
function findDirectContainerRows(scopeRoot, containerPath) {
|
|
46
|
+
if (!containerPath) return [];
|
|
47
|
+
const all = scopeRoot.querySelectorAll("[data-container-item]");
|
|
48
|
+
return Array.from(all).filter((el) => {
|
|
49
|
+
const attr = el.getAttribute("data-container-item") || "";
|
|
50
|
+
if (!attr.startsWith(`${containerPath}[`)) return false;
|
|
51
|
+
return /^\[\d+\]$/.test(attr.slice(containerPath.length));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function clear(node) {
|
|
55
|
+
while (node.firstChild) node.removeChild(node.firstChild);
|
|
56
|
+
}
|
|
57
|
+
function formatFileSize(bytes) {
|
|
58
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
59
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
60
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
61
|
+
}
|
|
62
|
+
function serializeHiddenValue(value) {
|
|
63
|
+
if (value === null || value === void 0) return "";
|
|
64
|
+
return typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
65
|
+
}
|
|
66
|
+
function deserializeHiddenValue(raw) {
|
|
67
|
+
if (raw === "") return null;
|
|
68
|
+
try {
|
|
69
|
+
return JSON.parse(raw);
|
|
70
|
+
} catch {
|
|
71
|
+
return raw;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function createHiddenInput(name, value) {
|
|
75
|
+
const input = document.createElement("input");
|
|
76
|
+
input.type = "hidden";
|
|
77
|
+
input.name = name;
|
|
78
|
+
input.setAttribute("data-hidden-field", "true");
|
|
79
|
+
input.value = serializeHiddenValue(value);
|
|
80
|
+
return input;
|
|
81
|
+
}
|
|
82
|
+
|
|
18
83
|
// src/utils/validation.ts
|
|
19
84
|
function addLengthHint(element, parts, state) {
|
|
20
85
|
if (element.minLength != null || element.maxLength != null) {
|
|
@@ -184,6 +249,64 @@ function validateSchema(schema) {
|
|
|
184
249
|
}
|
|
185
250
|
}
|
|
186
251
|
}
|
|
252
|
+
function validateCountBounds(element, elementPath, errors2) {
|
|
253
|
+
const el = element;
|
|
254
|
+
if (el.type === "group") {
|
|
255
|
+
if (!isPlainObject(el.repeat)) return;
|
|
256
|
+
checkBounds(
|
|
257
|
+
elementPath,
|
|
258
|
+
el.repeat?.min,
|
|
259
|
+
el.repeat?.max,
|
|
260
|
+
"repeat.min",
|
|
261
|
+
"repeat.max",
|
|
262
|
+
el.required === true,
|
|
263
|
+
errors2
|
|
264
|
+
);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const isMultiple = el.multiple === true || el.type === "files";
|
|
268
|
+
if (!isMultiple) return;
|
|
269
|
+
checkBounds(
|
|
270
|
+
elementPath,
|
|
271
|
+
el.minCount,
|
|
272
|
+
el.maxCount,
|
|
273
|
+
"minCount",
|
|
274
|
+
"maxCount",
|
|
275
|
+
el.required === true,
|
|
276
|
+
errors2
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
function checkBounds(elementPath, minCount, maxCount, minName, maxName, requiredImpliesFloor, errors2) {
|
|
280
|
+
for (const [name, bound] of [
|
|
281
|
+
[minName, minCount],
|
|
282
|
+
[maxName, maxCount]
|
|
283
|
+
]) {
|
|
284
|
+
if (bound !== void 0 && typeof bound !== "number") {
|
|
285
|
+
errors2.push(
|
|
286
|
+
`${elementPath}: ${name} must be a number (got ${typeof bound})`
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const min = typeof minCount === "number" ? minCount : void 0;
|
|
291
|
+
const max = typeof maxCount === "number" ? maxCount : void 0;
|
|
292
|
+
if (max !== void 0 && (max < 0 || Number.isNaN(max))) {
|
|
293
|
+
errors2.push(
|
|
294
|
+
`${elementPath}: ${maxName} must be a non-negative number or Infinity (got ${max})`
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
if (min !== void 0 && (min < 0 || !Number.isFinite(min))) {
|
|
298
|
+
errors2.push(
|
|
299
|
+
`${elementPath}: ${minName} must be a finite non-negative number (got ${min})`
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
const effectiveMin = min ?? (requiredImpliesFloor ? 1 : void 0);
|
|
303
|
+
if (effectiveMin !== void 0 && max !== void 0 && effectiveMin > max) {
|
|
304
|
+
const shown = min !== void 0 ? `${minName} (${min})` : `required: true (implies ${minName} 1)`;
|
|
305
|
+
errors2.push(
|
|
306
|
+
`${elementPath}: ${shown} cannot be greater than ${maxName} (${max})`
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
187
310
|
function validateElements(elements, path) {
|
|
188
311
|
elements.forEach((element, index) => {
|
|
189
312
|
const elementPath = `${path}[${index}]`;
|
|
@@ -193,6 +316,7 @@ function validateSchema(schema) {
|
|
|
193
316
|
if (!element.key && element.type !== "markdown") {
|
|
194
317
|
errors.push(`${elementPath}: missing key`);
|
|
195
318
|
}
|
|
319
|
+
validateCountBounds(element, elementPath, errors);
|
|
196
320
|
if (element.type === "markdown") {
|
|
197
321
|
const content = element.content;
|
|
198
322
|
if (typeof content !== "string") {
|
|
@@ -273,71 +397,6 @@ function validateSchema(schema) {
|
|
|
273
397
|
return errors;
|
|
274
398
|
}
|
|
275
399
|
|
|
276
|
-
// src/utils/helpers.ts
|
|
277
|
-
function isElementReadonly(element, state, ctx) {
|
|
278
|
-
return element.readonly === true || state.config.readonly === true || ctx?.inheritedReadonly === true;
|
|
279
|
-
}
|
|
280
|
-
function isPlainObject(obj) {
|
|
281
|
-
return obj && typeof obj === "object" && obj.constructor === Object;
|
|
282
|
-
}
|
|
283
|
-
function escapeHtml(text) {
|
|
284
|
-
const div = document.createElement("div");
|
|
285
|
-
div.textContent = text;
|
|
286
|
-
return div.innerHTML;
|
|
287
|
-
}
|
|
288
|
-
function getElementLookupKey(element, state) {
|
|
289
|
-
if (element.key) {
|
|
290
|
-
return element.key;
|
|
291
|
-
}
|
|
292
|
-
const cached = state.syntheticElementIds.get(element);
|
|
293
|
-
if (cached !== void 0) {
|
|
294
|
-
return cached;
|
|
295
|
-
}
|
|
296
|
-
const id = `fb-synthetic-${state.syntheticElementIdCounter++}`;
|
|
297
|
-
state.syntheticElementIds.set(element, id);
|
|
298
|
-
return id;
|
|
299
|
-
}
|
|
300
|
-
function pathJoin(base, key) {
|
|
301
|
-
return base ? `${base}.${key}` : key;
|
|
302
|
-
}
|
|
303
|
-
function findDirectContainerRows(scopeRoot, containerPath) {
|
|
304
|
-
if (!containerPath) return [];
|
|
305
|
-
const all = scopeRoot.querySelectorAll("[data-container-item]");
|
|
306
|
-
return Array.from(all).filter((el) => {
|
|
307
|
-
const attr = el.getAttribute("data-container-item") || "";
|
|
308
|
-
if (!attr.startsWith(`${containerPath}[`)) return false;
|
|
309
|
-
return /^\[\d+\]$/.test(attr.slice(containerPath.length));
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
function clear(node) {
|
|
313
|
-
while (node.firstChild) node.removeChild(node.firstChild);
|
|
314
|
-
}
|
|
315
|
-
function formatFileSize(bytes) {
|
|
316
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
317
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
318
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
319
|
-
}
|
|
320
|
-
function serializeHiddenValue(value) {
|
|
321
|
-
if (value === null || value === void 0) return "";
|
|
322
|
-
return typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
323
|
-
}
|
|
324
|
-
function deserializeHiddenValue(raw) {
|
|
325
|
-
if (raw === "") return null;
|
|
326
|
-
try {
|
|
327
|
-
return JSON.parse(raw);
|
|
328
|
-
} catch {
|
|
329
|
-
return raw;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
function createHiddenInput(name, value) {
|
|
333
|
-
const input = document.createElement("input");
|
|
334
|
-
input.type = "hidden";
|
|
335
|
-
input.name = name;
|
|
336
|
-
input.setAttribute("data-hidden-field", "true");
|
|
337
|
-
input.value = serializeHiddenValue(value);
|
|
338
|
-
return input;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
400
|
// src/utils/enable-conditions.ts
|
|
342
401
|
function getValueByPath(data, path) {
|
|
343
402
|
if (!data || typeof data !== "object") {
|
|
@@ -6772,11 +6831,14 @@ function getChildWrapperClass(columns) {
|
|
|
6772
6831
|
const cols = columns || 1;
|
|
6773
6832
|
return cols === 1 ? "fb-row" : `grid grid-cols-${cols} gap-2`;
|
|
6774
6833
|
}
|
|
6775
|
-
function mountRemoveButton(item, onRemove, state) {
|
|
6834
|
+
function mountRemoveButton(item, onRemove, state, containerLabel) {
|
|
6776
6835
|
const rem = document.createElement("button");
|
|
6777
6836
|
rem.type = "button";
|
|
6778
6837
|
rem.className = "fb-item-remove";
|
|
6779
|
-
rem.setAttribute(
|
|
6838
|
+
rem.setAttribute(
|
|
6839
|
+
"aria-label",
|
|
6840
|
+
containerLabel ? t("removeRowFrom", state, { label: containerLabel }) : t("removeRow", state)
|
|
6841
|
+
);
|
|
6780
6842
|
rem.style.cssText = `
|
|
6781
6843
|
width: 24px;
|
|
6782
6844
|
height: 24px;
|
|
@@ -6864,7 +6926,12 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
|
|
|
6864
6926
|
});
|
|
6865
6927
|
item.appendChild(childWrapper);
|
|
6866
6928
|
if (!containerIsReadonly) {
|
|
6867
|
-
mountRemoveButton(
|
|
6929
|
+
mountRemoveButton(
|
|
6930
|
+
item,
|
|
6931
|
+
() => handleRemoveItem(item),
|
|
6932
|
+
state,
|
|
6933
|
+
element.label
|
|
6934
|
+
);
|
|
6868
6935
|
}
|
|
6869
6936
|
return item;
|
|
6870
6937
|
};
|
|
@@ -7027,7 +7094,7 @@ function validateContainerElement(element, key, context) {
|
|
|
7027
7094
|
);
|
|
7028
7095
|
if (childResult.spread && childResult.value !== null && typeof childResult.value === "object") {
|
|
7029
7096
|
Object.assign(itemData, childResult.value);
|
|
7030
|
-
} else {
|
|
7097
|
+
} else if (!childResult.skip && child.key) {
|
|
7031
7098
|
itemData[child.key] = childResult.value;
|
|
7032
7099
|
}
|
|
7033
7100
|
});
|
|
@@ -7068,7 +7135,7 @@ function validateContainerElement(element, key, context) {
|
|
|
7068
7135
|
);
|
|
7069
7136
|
if (childResult.spread && childResult.value !== null && typeof childResult.value === "object") {
|
|
7070
7137
|
Object.assign(containerData, childResult.value);
|
|
7071
|
-
} else {
|
|
7138
|
+
} else if (!childResult.skip && child.key) {
|
|
7072
7139
|
containerData[child.key] = childResult.value;
|
|
7073
7140
|
}
|
|
7074
7141
|
}
|
|
@@ -7088,11 +7155,13 @@ function updateContainerField(element, fieldPath, value, context) {
|
|
|
7088
7155
|
);
|
|
7089
7156
|
return;
|
|
7090
7157
|
}
|
|
7158
|
+
const rows = findDirectContainerRows(scopeRoot, fieldPath);
|
|
7091
7159
|
value.forEach((itemValue, index) => {
|
|
7092
|
-
|
|
7160
|
+
const rowPath = rows[index]?.getAttribute("data-container-item");
|
|
7161
|
+
if (isPlainObject(itemValue) && rowPath) {
|
|
7093
7162
|
element.elements.forEach((childElement) => {
|
|
7094
7163
|
if (childElement.type === "markdown" || !childElement.key) return;
|
|
7095
|
-
const childPath = `${
|
|
7164
|
+
const childPath = `${rowPath}.${childElement.key}`;
|
|
7096
7165
|
if (childElement.type === "richinput" && childElement.flatOutput) {
|
|
7097
7166
|
const richChild = childElement;
|
|
7098
7167
|
const textKey = richChild.textKey ?? "text";
|
|
@@ -7115,10 +7184,9 @@ function updateContainerField(element, fieldPath, value, context) {
|
|
|
7115
7184
|
});
|
|
7116
7185
|
}
|
|
7117
7186
|
});
|
|
7118
|
-
|
|
7119
|
-
if (value.length !== existingContainers.length) {
|
|
7187
|
+
if (value.length !== rows.length) {
|
|
7120
7188
|
console.warn(
|
|
7121
|
-
`updateContainerField: Multiple container field "${fieldPath}"
|
|
7189
|
+
`updateContainerField: Multiple container field "${fieldPath}" received ${value.length} items for ${rows.length} rendered rows. Rows are not added or removed here \u2014 re-render for add/remove.`
|
|
7122
7190
|
);
|
|
7123
7191
|
}
|
|
7124
7192
|
} else {
|
|
@@ -10610,6 +10678,8 @@ var defaultConfig = {
|
|
|
10610
10678
|
en: {
|
|
10611
10679
|
// UI texts
|
|
10612
10680
|
removeElement: "Remove",
|
|
10681
|
+
removeRow: "Remove row",
|
|
10682
|
+
removeRowFrom: "Remove row from {label}",
|
|
10613
10683
|
clickDragText: "Click or drag file",
|
|
10614
10684
|
clickDragTextMultiple: "Click or drag files",
|
|
10615
10685
|
noFileSelected: "No file selected",
|
|
@@ -10683,6 +10753,8 @@ var defaultConfig = {
|
|
|
10683
10753
|
ru: {
|
|
10684
10754
|
// UI texts
|
|
10685
10755
|
removeElement: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C",
|
|
10756
|
+
removeRow: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0442\u0440\u043E\u043A\u0443",
|
|
10757
|
+
removeRowFrom: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0442\u0440\u043E\u043A\u0443 \u0438\u0437 \xAB{label}\xBB",
|
|
10686
10758
|
clickDragText: "\u041D\u0430\u0436\u043C\u0438\u0442\u0435 \u0438\u043B\u0438 \u043F\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0444\u0430\u0439\u043B",
|
|
10687
10759
|
clickDragTextMultiple: "\u041D\u0430\u0436\u043C\u0438\u0442\u0435 \u0438\u043B\u0438 \u043F\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0444\u0430\u0439\u043B\u044B",
|
|
10688
10760
|
noFileSelected: "\u0424\u0430\u0439\u043B \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D",
|
|
@@ -11072,6 +11144,18 @@ var exampleThemes = {
|
|
|
11072
11144
|
};
|
|
11073
11145
|
|
|
11074
11146
|
// src/instance/FormBuilderInstance.ts
|
|
11147
|
+
function findOwnField(scope, lookupKey, ownBoundary) {
|
|
11148
|
+
const matches = scope.querySelectorAll(
|
|
11149
|
+
`[data-field-key="${lookupKey}"]`
|
|
11150
|
+
);
|
|
11151
|
+
for (const el of Array.from(matches)) {
|
|
11152
|
+
const boundary = el.closest(
|
|
11153
|
+
"[data-container-item], [data-container]"
|
|
11154
|
+
);
|
|
11155
|
+
if (boundary === ownBoundary) return el;
|
|
11156
|
+
}
|
|
11157
|
+
return null;
|
|
11158
|
+
}
|
|
11075
11159
|
var FormBuilderInstance = class {
|
|
11076
11160
|
constructor(config) {
|
|
11077
11161
|
this.instanceId = generateInstanceId();
|
|
@@ -11794,28 +11878,28 @@ var FormBuilderInstance = class {
|
|
|
11794
11878
|
const formRoot = this.state.formRoot;
|
|
11795
11879
|
const lookupKey = getElementLookupKey(element, this.state);
|
|
11796
11880
|
if (!currentPath) {
|
|
11797
|
-
return formRoot
|
|
11881
|
+
return findOwnField(formRoot, lookupKey, null);
|
|
11798
11882
|
}
|
|
11799
11883
|
const pathMatch = currentPath.match(/^(.+)\[(\d+)\]$/);
|
|
11800
11884
|
if (pathMatch) {
|
|
11801
11885
|
const containerEl2 = formRoot.querySelector(
|
|
11802
11886
|
`[data-container-item="${pathMatch[1]}[${pathMatch[2]}]"]`
|
|
11803
11887
|
);
|
|
11804
|
-
return containerEl2 ? containerEl2
|
|
11888
|
+
return containerEl2 ? findOwnField(containerEl2, lookupKey, containerEl2) : null;
|
|
11805
11889
|
}
|
|
11806
11890
|
const containerEl = formRoot.querySelector(
|
|
11807
11891
|
`[data-container="${currentPath}"]`
|
|
11808
11892
|
);
|
|
11809
|
-
return containerEl ? containerEl
|
|
11893
|
+
return containerEl ? findOwnField(containerEl, lookupKey, containerEl) : null;
|
|
11810
11894
|
}
|
|
11811
11895
|
/**
|
|
11812
11896
|
* Apply enableIf show/hide logic to a single field wrapper.
|
|
11813
11897
|
* Extracted to reduce cyclomatic complexity of checkElements.
|
|
11814
11898
|
*/
|
|
11815
|
-
applyEnableIfVisibility(element, wrapper,
|
|
11899
|
+
applyEnableIfVisibility(element, wrapper, domPath, dataPath, fullDomPath, formData) {
|
|
11816
11900
|
try {
|
|
11817
11901
|
const scope = element.enableIf.scope ?? "relative";
|
|
11818
|
-
const containerData = scope === "relative" &&
|
|
11902
|
+
const containerData = scope === "relative" && dataPath ? getValueByPath(formData, dataPath) : void 0;
|
|
11819
11903
|
const shouldEnable = evaluateEnableCondition(
|
|
11820
11904
|
element.enableIf,
|
|
11821
11905
|
formData,
|
|
@@ -11823,10 +11907,12 @@ var FormBuilderInstance = class {
|
|
|
11823
11907
|
);
|
|
11824
11908
|
const isCurrentlyDisabled = wrapper.getAttribute("data-conditionally-disabled") === "true";
|
|
11825
11909
|
if (shouldEnable && isCurrentlyDisabled) {
|
|
11826
|
-
const containerPrefill =
|
|
11910
|
+
const containerPrefill = dataPath ? getValueByPath(formData, dataPath) : formData;
|
|
11827
11911
|
const prefillContext = containerPrefill && typeof containerPrefill === "object" ? containerPrefill : {};
|
|
11828
11912
|
const newWrapper = renderElement2(element, {
|
|
11829
|
-
path:
|
|
11913
|
+
// DOM path: the re-rendered control's `name` must match the row it
|
|
11914
|
+
// lives in, not the row's position in the extracted array.
|
|
11915
|
+
path: domPath,
|
|
11830
11916
|
prefill: prefillContext,
|
|
11831
11917
|
formData,
|
|
11832
11918
|
state: this.state,
|
|
@@ -11846,7 +11932,7 @@ var FormBuilderInstance = class {
|
|
|
11846
11932
|
}
|
|
11847
11933
|
} catch (error) {
|
|
11848
11934
|
console.error(
|
|
11849
|
-
`Error re-evaluating enableIf for field "${element.key ?? "<no key>"}" at path "${
|
|
11935
|
+
`Error re-evaluating enableIf for field "${element.key ?? "<no key>"}" at path "${fullDomPath}":`,
|
|
11850
11936
|
error
|
|
11851
11937
|
);
|
|
11852
11938
|
}
|
|
@@ -11858,39 +11944,46 @@ var FormBuilderInstance = class {
|
|
|
11858
11944
|
reevaluateConditionalFields() {
|
|
11859
11945
|
if (!this.state.schema || !this.state.formRoot) return;
|
|
11860
11946
|
const formData = this.validateForm(true).data;
|
|
11861
|
-
const checkElements = (elements,
|
|
11947
|
+
const checkElements = (elements, domPath, dataPath) => {
|
|
11862
11948
|
elements.forEach((element) => {
|
|
11863
|
-
const
|
|
11949
|
+
const key = element.key ?? "";
|
|
11950
|
+
const fullDomPath = domPath ? `${domPath}.${key}` : key;
|
|
11951
|
+
const fullDataPath = dataPath ? `${dataPath}.${key}` : key;
|
|
11864
11952
|
if (element.enableIf) {
|
|
11865
|
-
const fieldWrapper = this.findFieldWrapper(element,
|
|
11953
|
+
const fieldWrapper = this.findFieldWrapper(element, domPath);
|
|
11866
11954
|
if (fieldWrapper) {
|
|
11867
11955
|
this.applyEnableIfVisibility(
|
|
11868
11956
|
element,
|
|
11869
11957
|
fieldWrapper,
|
|
11870
|
-
|
|
11871
|
-
|
|
11958
|
+
domPath,
|
|
11959
|
+
dataPath,
|
|
11960
|
+
fullDomPath,
|
|
11872
11961
|
formData
|
|
11873
11962
|
);
|
|
11874
11963
|
}
|
|
11875
11964
|
}
|
|
11876
11965
|
if ((element.type === "container" || element.type === "group") && "elements" in element && element.elements) {
|
|
11877
|
-
const containerData = element.key ? getValueByPath(formData,
|
|
11966
|
+
const containerData = element.key ? getValueByPath(formData, fullDataPath) : void 0;
|
|
11878
11967
|
if (Array.isArray(containerData)) {
|
|
11879
11968
|
const directItems = findDirectContainerRows(
|
|
11880
11969
|
this.state.formRoot,
|
|
11881
|
-
|
|
11970
|
+
fullDomPath
|
|
11882
11971
|
);
|
|
11883
|
-
directItems.forEach((el) => {
|
|
11884
|
-
const
|
|
11885
|
-
checkElements(
|
|
11972
|
+
directItems.forEach((el, rowIndex) => {
|
|
11973
|
+
const marker = el.getAttribute("data-container-item") || "";
|
|
11974
|
+
checkElements(
|
|
11975
|
+
element.elements,
|
|
11976
|
+
marker,
|
|
11977
|
+
`${fullDataPath}[${rowIndex}]`
|
|
11978
|
+
);
|
|
11886
11979
|
});
|
|
11887
11980
|
} else {
|
|
11888
|
-
checkElements(element.elements,
|
|
11981
|
+
checkElements(element.elements, fullDomPath, fullDataPath);
|
|
11889
11982
|
}
|
|
11890
11983
|
}
|
|
11891
11984
|
});
|
|
11892
11985
|
};
|
|
11893
|
-
checkElements(this.state.schema.elements, "");
|
|
11986
|
+
checkElements(this.state.schema.elements, "", "");
|
|
11894
11987
|
}
|
|
11895
11988
|
/**
|
|
11896
11989
|
* Destroy instance and clean up resources
|