@dmitryvim/form-builder 0.5.0 → 0.5.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/dist/browser/formbuilder.min.js +117 -126
- package/dist/browser/{formbuilder.v0.5.0.min.js → formbuilder.v0.5.2.min.js} +117 -126
- package/dist/cjs/index.cjs +117 -232
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +116 -229
- package/dist/esm/index.js.map +1 -1
- package/dist/form-builder.js +117 -126
- package/dist/types/components/file/render-edit.d.ts +0 -4
- package/dist/types/types/config.d.ts +6 -3
- package/dist/types/utils/helpers.d.ts +8 -0
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -307,6 +307,15 @@ function getElementLookupKey(element, state) {
|
|
|
307
307
|
function pathJoin(base, key) {
|
|
308
308
|
return base ? `${base}.${key}` : key;
|
|
309
309
|
}
|
|
310
|
+
function findDirectContainerRows(scopeRoot, containerPath) {
|
|
311
|
+
if (!containerPath) return [];
|
|
312
|
+
const all = scopeRoot.querySelectorAll("[data-container-item]");
|
|
313
|
+
return Array.from(all).filter((el) => {
|
|
314
|
+
const attr = el.getAttribute("data-container-item") || "";
|
|
315
|
+
if (!attr.startsWith(`${containerPath}[`)) return false;
|
|
316
|
+
return /^\[\d+\]$/.test(attr.slice(containerPath.length));
|
|
317
|
+
});
|
|
318
|
+
}
|
|
310
319
|
function clear(node) {
|
|
311
320
|
while (node.firstChild) node.removeChild(node.firstChild);
|
|
312
321
|
}
|
|
@@ -457,6 +466,19 @@ function ensureThemingHooks(doc) {
|
|
|
457
466
|
color: var(--fb-error-color);
|
|
458
467
|
background-color: var(--fb-background-hover-color);
|
|
459
468
|
}
|
|
469
|
+
.fb-item-remove:disabled {
|
|
470
|
+
opacity: 0.35;
|
|
471
|
+
cursor: not-allowed;
|
|
472
|
+
}
|
|
473
|
+
/* Cards carrying a row-level remove button reserve a right-hand lane for it
|
|
474
|
+
(24px button + inset + gap) so it never sits on top of the first field's
|
|
475
|
+
control. A class rather than an inline style, so host CSS can override the
|
|
476
|
+
gutter without !important; the compound selector keeps it ahead of the
|
|
477
|
+
card's own p-2 utility regardless of stylesheet order. Its own token, not
|
|
478
|
+
--fb-slide-card-padding, which is slides-only and always resolves. */
|
|
479
|
+
.containerItem.fb-row-removable {
|
|
480
|
+
padding-right: var(--fb-row-remove-gutter, 40px);
|
|
481
|
+
}
|
|
460
482
|
/* Prefill-suggestion pills rendered by createPrefillHints. Outline pill at rest,
|
|
461
483
|
soft-fill on hover, solid-fill when selected. All colors flow from the active
|
|
462
484
|
theme \u2014 consumers don't need to ship their own CSS. */
|
|
@@ -3091,34 +3113,12 @@ function ensureFileStyles() {
|
|
|
3091
3113
|
padding: 6px;
|
|
3092
3114
|
}
|
|
3093
3115
|
|
|
3094
|
-
/* \u2500\u2500\u2500
|
|
3095
|
-
.fb-
|
|
3116
|
+
/* \u2500\u2500\u2500 Clear-all row below multi grid \u2500\u2500\u2500 */
|
|
3117
|
+
.fb-clear-all-row {
|
|
3096
3118
|
margin-top: 10px;
|
|
3097
3119
|
display: flex;
|
|
3098
3120
|
align-items: center;
|
|
3099
|
-
justify-content:
|
|
3100
|
-
gap: 8px;
|
|
3101
|
-
flex-wrap: wrap;
|
|
3102
|
-
}
|
|
3103
|
-
.fb-meta-text {
|
|
3104
|
-
font-size: 12px;
|
|
3105
|
-
color: #94a3b8;
|
|
3106
|
-
display: flex;
|
|
3107
|
-
align-items: center;
|
|
3108
|
-
gap: 8px;
|
|
3109
|
-
flex-wrap: wrap;
|
|
3110
|
-
}
|
|
3111
|
-
.fb-meta-dot {
|
|
3112
|
-
width: 4px;
|
|
3113
|
-
height: 4px;
|
|
3114
|
-
border-radius: 50%;
|
|
3115
|
-
background: #cbd5e1;
|
|
3116
|
-
flex-shrink: 0;
|
|
3117
|
-
}
|
|
3118
|
-
.fb-meta-mono {
|
|
3119
|
-
font-family: ui-monospace, 'JetBrains Mono', monospace;
|
|
3120
|
-
font-size: 11px;
|
|
3121
|
-
letter-spacing: -0.02em;
|
|
3121
|
+
justify-content: flex-end;
|
|
3122
3122
|
}
|
|
3123
3123
|
.fb-clear-all-btn {
|
|
3124
3124
|
font-size: 12px;
|
|
@@ -4938,66 +4938,39 @@ function buildPlaceholderTile(isDragOver = false) {
|
|
|
4938
4938
|
div.className = `fb-multi-placeholder fb-checker${isDragOver ? " fb-drag-over" : ""}`;
|
|
4939
4939
|
return div;
|
|
4940
4940
|
}
|
|
4941
|
-
function
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
fmtSpan.className = "fb-meta-mono";
|
|
4958
|
-
fmtSpan.textContent = exts.map((e) => e.toUpperCase()).join(", ");
|
|
4959
|
-
metaText.appendChild(fmtSpan);
|
|
4960
|
-
metaText.appendChild(buildMetaDot());
|
|
4961
|
-
}
|
|
4962
|
-
const countSpan = document.createElement("span");
|
|
4963
|
-
if (maxCount < Infinity) {
|
|
4964
|
-
countSpan.textContent = t("fileCountWithMax", state, {
|
|
4965
|
-
count: ridCount,
|
|
4966
|
-
max: maxCount
|
|
4967
|
-
});
|
|
4968
|
-
} else {
|
|
4969
|
-
const countKey = ridCount === 1 ? "fileCountSingle" : "fileCountPlural";
|
|
4970
|
-
countSpan.textContent = t(countKey, state, { count: ridCount });
|
|
4971
|
-
}
|
|
4972
|
-
metaText.appendChild(countSpan);
|
|
4973
|
-
line.appendChild(metaText);
|
|
4974
|
-
if (canClearAll && ridCount > 1) {
|
|
4975
|
-
const clearBtn = document.createElement("button");
|
|
4976
|
-
clearBtn.type = "button";
|
|
4977
|
-
clearBtn.className = "fb-clear-all-btn";
|
|
4978
|
-
clearBtn.textContent = t("clearAll", state);
|
|
4979
|
-
clearBtn.onclick = (e) => {
|
|
4980
|
-
e.stopPropagation();
|
|
4981
|
-
if (window.confirm(t("clearAll", state) + "?")) {
|
|
4982
|
-
onClearAll();
|
|
4983
|
-
}
|
|
4984
|
-
};
|
|
4985
|
-
line.appendChild(clearBtn);
|
|
4986
|
-
}
|
|
4987
|
-
return line;
|
|
4988
|
-
}
|
|
4989
|
-
function buildMetaDot() {
|
|
4990
|
-
const dot = document.createElement("span");
|
|
4991
|
-
dot.className = "fb-meta-dot";
|
|
4992
|
-
return dot;
|
|
4941
|
+
function buildClearAllRow(state, ridCount, onClearAll) {
|
|
4942
|
+
if (ridCount <= 1) return null;
|
|
4943
|
+
const row = document.createElement("div");
|
|
4944
|
+
row.className = "fb-clear-all-row";
|
|
4945
|
+
const clearBtn = document.createElement("button");
|
|
4946
|
+
clearBtn.type = "button";
|
|
4947
|
+
clearBtn.className = "fb-clear-all-btn";
|
|
4948
|
+
clearBtn.textContent = t("clearAll", state);
|
|
4949
|
+
clearBtn.onclick = (e) => {
|
|
4950
|
+
e.stopPropagation();
|
|
4951
|
+
if (window.confirm(t("clearAll", state) + "?")) {
|
|
4952
|
+
onClearAll();
|
|
4953
|
+
}
|
|
4954
|
+
};
|
|
4955
|
+
row.appendChild(clearBtn);
|
|
4956
|
+
return row;
|
|
4993
4957
|
}
|
|
4994
4958
|
var gridResizeObservers = /* @__PURE__ */ new WeakMap();
|
|
4959
|
+
var gridMeasureFrames = /* @__PURE__ */ new WeakMap();
|
|
4960
|
+
function cancelPendingMeasure(container) {
|
|
4961
|
+
const frame = gridMeasureFrames.get(container);
|
|
4962
|
+
if (frame !== void 0) {
|
|
4963
|
+
cancelAnimationFrame(frame);
|
|
4964
|
+
gridMeasureFrames.delete(container);
|
|
4965
|
+
}
|
|
4966
|
+
}
|
|
4995
4967
|
function disposePlaceholdersForUpload(container) {
|
|
4996
4968
|
const observer = gridResizeObservers.get(container);
|
|
4997
4969
|
if (observer) {
|
|
4998
4970
|
observer.disconnect();
|
|
4999
4971
|
gridResizeObservers.delete(container);
|
|
5000
4972
|
}
|
|
4973
|
+
cancelPendingMeasure(container);
|
|
5001
4974
|
container.querySelectorAll(".fb-multi-placeholder").forEach((p) => p.remove());
|
|
5002
4975
|
}
|
|
5003
4976
|
function renderResourcePills(opts) {
|
|
@@ -5010,7 +4983,6 @@ function renderResourcePills(opts) {
|
|
|
5010
4983
|
maxCount,
|
|
5011
4984
|
isReadonly = false,
|
|
5012
4985
|
onLibraryPick,
|
|
5013
|
-
element,
|
|
5014
4986
|
onClearAll,
|
|
5015
4987
|
openPicker: openPickerProp
|
|
5016
4988
|
} = opts;
|
|
@@ -5024,6 +4996,7 @@ function renderResourcePills(opts) {
|
|
|
5024
4996
|
previousObserver.disconnect();
|
|
5025
4997
|
gridResizeObservers.delete(container);
|
|
5026
4998
|
}
|
|
4999
|
+
cancelPendingMeasure(container);
|
|
5027
5000
|
while (container.firstChild) container.removeChild(container.firstChild);
|
|
5028
5001
|
const ridList = rids != null ? rids : [];
|
|
5029
5002
|
const effectiveMax = maxCount != null ? maxCount : Infinity;
|
|
@@ -5125,7 +5098,7 @@ function renderResourcePills(opts) {
|
|
|
5125
5098
|
if (effectiveMax === Infinity || effectiveMax > occupied) {
|
|
5126
5099
|
grid.appendChild(buildPlaceholderTile());
|
|
5127
5100
|
}
|
|
5128
|
-
requestAnimationFrame(adjustPlaceholders);
|
|
5101
|
+
gridMeasureFrames.set(container, requestAnimationFrame(adjustPlaceholders));
|
|
5129
5102
|
if (typeof ResizeObserver !== "undefined") {
|
|
5130
5103
|
const ro = new ResizeObserver(() => adjustPlaceholders());
|
|
5131
5104
|
ro.observe(grid);
|
|
@@ -5156,17 +5129,9 @@ function renderResourcePills(opts) {
|
|
|
5156
5129
|
}
|
|
5157
5130
|
}
|
|
5158
5131
|
});
|
|
5159
|
-
if (
|
|
5160
|
-
const
|
|
5161
|
-
|
|
5162
|
-
element,
|
|
5163
|
-
ridList.length,
|
|
5164
|
-
effectiveMax,
|
|
5165
|
-
Boolean(onClearAll),
|
|
5166
|
-
onClearAll != null ? onClearAll : (() => {
|
|
5167
|
-
})
|
|
5168
|
-
);
|
|
5169
|
-
container.appendChild(metaLine);
|
|
5132
|
+
if (onClearAll) {
|
|
5133
|
+
const row = buildClearAllRow(state, ridList.length, onClearAll);
|
|
5134
|
+
if (row) container.appendChild(row);
|
|
5170
5135
|
}
|
|
5171
5136
|
}
|
|
5172
5137
|
function renderFileElementEdit(element, ctx, wrapper, pathKey) {
|
|
@@ -5395,7 +5360,6 @@ function setupMultiFileEditMode(element, ctx, wrapper, pathKey, maxFiles) {
|
|
|
5395
5360
|
maxCount: maxFiles < Infinity ? maxFiles : void 0,
|
|
5396
5361
|
isReadonly: currentlyReadonly,
|
|
5397
5362
|
onLibraryPick: currentlyReadonly ? null : onLibraryPick,
|
|
5398
|
-
element,
|
|
5399
5363
|
onClearAll: currentlyReadonly ? void 0 : () => {
|
|
5400
5364
|
var _a2, _b2;
|
|
5401
5365
|
for (const rid of initialFiles) {
|
|
@@ -6933,17 +6897,13 @@ function mountRemoveButton(item, onRemove, state) {
|
|
|
6933
6897
|
`;
|
|
6934
6898
|
rem.innerHTML = BIN_ICON_SVG;
|
|
6935
6899
|
rem.onclick = onRemove;
|
|
6936
|
-
const labelRow = item.querySelector("[data-fb-label-row]");
|
|
6937
|
-
if (labelRow) {
|
|
6938
|
-
rem.style.marginLeft = "auto";
|
|
6939
|
-
labelRow.appendChild(rem);
|
|
6940
|
-
return;
|
|
6941
|
-
}
|
|
6942
6900
|
rem.style.position = "absolute";
|
|
6943
|
-
rem.style.top = "8px";
|
|
6944
|
-
rem.style.right = "8px";
|
|
6901
|
+
rem.style.top = "var(--fb-row-remove-inset, 8px)";
|
|
6902
|
+
rem.style.right = "var(--fb-row-remove-inset, 8px)";
|
|
6903
|
+
rem.style.zIndex = "1";
|
|
6945
6904
|
item.style.position = "relative";
|
|
6946
|
-
item.
|
|
6905
|
+
item.classList.add("fb-row-removable");
|
|
6906
|
+
item.insertBefore(rem, item.firstChild);
|
|
6947
6907
|
}
|
|
6948
6908
|
function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
|
|
6949
6909
|
var _a, _b, _c, _d;
|
|
@@ -6969,24 +6929,29 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
|
|
|
6969
6929
|
const max = (_b = element.maxCount) != null ? _b : Infinity;
|
|
6970
6930
|
const pre = Array.isArray((_c = ctx.prefill) == null ? void 0 : _c[element.key]) ? ctx.prefill[element.key] : null;
|
|
6971
6931
|
const childDefaults = extractChildDefaults(element.elements);
|
|
6972
|
-
|
|
6973
|
-
const
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6932
|
+
let nextRowIndex = 0;
|
|
6933
|
+
const takeRowIndex = () => nextRowIndex++;
|
|
6934
|
+
const directRows = () => Array.from(itemsWrap.children).filter(
|
|
6935
|
+
(el) => el.classList.contains("containerItem")
|
|
6936
|
+
);
|
|
6937
|
+
const countItems = () => directRows().length;
|
|
6938
|
+
const handleRemoveItem = (item) => {
|
|
6939
|
+
if (countItems() <= min) return;
|
|
6940
|
+
item.remove();
|
|
6941
|
+
updateAddButton();
|
|
6942
|
+
};
|
|
6943
|
+
const createContainerItem = (idx, rowPrefill, formData) => {
|
|
6977
6944
|
const subCtx = {
|
|
6978
|
-
state
|
|
6945
|
+
state,
|
|
6979
6946
|
instance: ctx.instance,
|
|
6980
6947
|
path: pathJoin(ctx.path, `${element.key}[${idx}]`),
|
|
6981
|
-
prefill: childDefaults,
|
|
6982
|
-
|
|
6983
|
-
formData: currentFormData,
|
|
6984
|
-
// Current root data from DOM for enableIf
|
|
6948
|
+
prefill: mergeWithDefaults(rowPrefill != null ? rowPrefill : {}, childDefaults),
|
|
6949
|
+
formData,
|
|
6985
6950
|
inheritedReadonly: childInheritedReadonly
|
|
6986
6951
|
};
|
|
6987
6952
|
const item = document.createElement("div");
|
|
6988
6953
|
item.className = "containerItem border border-gray-300 rounded-lg p-2 bg-white";
|
|
6989
|
-
item.setAttribute("data-container-item",
|
|
6954
|
+
item.setAttribute("data-container-item", subCtx.path);
|
|
6990
6955
|
if (isSlides) {
|
|
6991
6956
|
item.setAttribute("data-fb-slide-card", "");
|
|
6992
6957
|
}
|
|
@@ -6995,13 +6960,11 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
|
|
|
6995
6960
|
isSlides ? void 0 : element.columns
|
|
6996
6961
|
);
|
|
6997
6962
|
element.elements.forEach((child) => {
|
|
6998
|
-
var _a2;
|
|
6963
|
+
var _a2, _b2;
|
|
6999
6964
|
if (child.type !== "markdown" && (child.hidden || child.type === "hidden")) {
|
|
6965
|
+
const hiddenValue = (_b2 = (_a2 = rowPrefill == null ? void 0 : rowPrefill[child.key]) != null ? _a2 : "default" in child ? child.default : null) != null ? _b2 : null;
|
|
7000
6966
|
childWrapper.appendChild(
|
|
7001
|
-
createHiddenInput(
|
|
7002
|
-
pathJoin(subCtx.path, child.key),
|
|
7003
|
-
(_a2 = "default" in child ? child.default : null) != null ? _a2 : null
|
|
7004
|
-
)
|
|
6967
|
+
createHiddenInput(pathJoin(subCtx.path, child.key), hiddenValue)
|
|
7005
6968
|
);
|
|
7006
6969
|
} else {
|
|
7007
6970
|
childWrapper.appendChild(renderElement(child, subCtx));
|
|
@@ -7011,6 +6974,17 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
|
|
|
7011
6974
|
if (!containerIsReadonly) {
|
|
7012
6975
|
mountRemoveButton(item, () => handleRemoveItem(item), state);
|
|
7013
6976
|
}
|
|
6977
|
+
return item;
|
|
6978
|
+
};
|
|
6979
|
+
const handleAddItem = () => {
|
|
6980
|
+
if (countItems() >= max) return;
|
|
6981
|
+
const item = createContainerItem(
|
|
6982
|
+
takeRowIndex(),
|
|
6983
|
+
null,
|
|
6984
|
+
// Current root data read back from the DOM, so enableIf sees what the
|
|
6985
|
+
// user has actually typed rather than the original prefill.
|
|
6986
|
+
state.formRoot ? extractRootFormData(state.formRoot) : {}
|
|
6987
|
+
);
|
|
7014
6988
|
if (slideAddTile && slideAddTile.parentElement === itemsWrap) {
|
|
7015
6989
|
itemsWrap.insertBefore(item, slideAddTile);
|
|
7016
6990
|
} else {
|
|
@@ -7023,112 +6997,44 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
|
|
|
7023
6997
|
let pillAddUpdate = null;
|
|
7024
6998
|
const syncSlideTileSize = () => {
|
|
7025
6999
|
if (!slideAddTile) return;
|
|
7026
|
-
const firstSlide =
|
|
7027
|
-
":scope > .containerItem"
|
|
7028
|
-
);
|
|
7000
|
+
const firstSlide = directRows()[0];
|
|
7029
7001
|
if (firstSlide && firstSlide.offsetHeight > 0) {
|
|
7030
7002
|
slideAddTile.style.minHeight = `${firstSlide.offsetHeight}px`;
|
|
7031
7003
|
}
|
|
7032
7004
|
};
|
|
7005
|
+
const syncRemoveButtons = () => {
|
|
7006
|
+
const atFloor = countItems() <= min;
|
|
7007
|
+
directRows().forEach((row) => {
|
|
7008
|
+
const btn = Array.from(row.children).find(
|
|
7009
|
+
(el) => el.classList.contains("fb-item-remove")
|
|
7010
|
+
);
|
|
7011
|
+
if (btn) btn.disabled = atFloor;
|
|
7012
|
+
});
|
|
7013
|
+
};
|
|
7033
7014
|
const updateAddButton = () => {
|
|
7034
7015
|
const currentCount = countItems();
|
|
7035
7016
|
if (slideAddUpdate) slideAddUpdate(currentCount, max);
|
|
7036
7017
|
if (pillAddUpdate) pillAddUpdate(currentCount, max);
|
|
7037
7018
|
if (slideAddTile) syncSlideTileSize();
|
|
7019
|
+
syncRemoveButtons();
|
|
7038
7020
|
};
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
updateAddButton();
|
|
7042
|
-
};
|
|
7043
|
-
if (pre && Array.isArray(pre)) {
|
|
7044
|
-
pre.forEach((prefillObj, idx) => {
|
|
7021
|
+
if (pre) {
|
|
7022
|
+
pre.forEach((prefillObj) => {
|
|
7045
7023
|
var _a2;
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
// Merged prefill with defaults for enableIf
|
|
7053
|
-
formData: (_a2 = ctx.formData) != null ? _a2 : ctx.prefill,
|
|
7054
|
-
// Complete root data for enableIf
|
|
7055
|
-
inheritedReadonly: childInheritedReadonly
|
|
7056
|
-
};
|
|
7057
|
-
const item = document.createElement("div");
|
|
7058
|
-
item.className = "containerItem border border-gray-300 rounded-lg p-2 bg-white";
|
|
7059
|
-
item.setAttribute("data-container-item", `${element.key}[${idx}]`);
|
|
7060
|
-
if (isSlides) {
|
|
7061
|
-
item.setAttribute("data-fb-slide-card", "");
|
|
7062
|
-
}
|
|
7063
|
-
const childWrapper = document.createElement("div");
|
|
7064
|
-
childWrapper.className = getChildWrapperClass(
|
|
7065
|
-
isSlides ? void 0 : element.columns
|
|
7024
|
+
itemsWrap.appendChild(
|
|
7025
|
+
createContainerItem(
|
|
7026
|
+
takeRowIndex(),
|
|
7027
|
+
prefillObj != null ? prefillObj : {},
|
|
7028
|
+
(_a2 = ctx.formData) != null ? _a2 : ctx.prefill
|
|
7029
|
+
)
|
|
7066
7030
|
);
|
|
7067
|
-
element.elements.forEach((child) => {
|
|
7068
|
-
var _a3, _b2;
|
|
7069
|
-
if (child.type !== "markdown" && (child.hidden || child.type === "hidden")) {
|
|
7070
|
-
const prefillVal = (_b2 = (_a3 = prefillObj == null ? void 0 : prefillObj[child.key]) != null ? _a3 : "default" in child ? child.default : null) != null ? _b2 : null;
|
|
7071
|
-
childWrapper.appendChild(
|
|
7072
|
-
createHiddenInput(pathJoin(subCtx.path, child.key), prefillVal)
|
|
7073
|
-
);
|
|
7074
|
-
} else {
|
|
7075
|
-
childWrapper.appendChild(renderElement(child, subCtx));
|
|
7076
|
-
}
|
|
7077
|
-
});
|
|
7078
|
-
item.appendChild(childWrapper);
|
|
7079
|
-
if (!containerIsReadonly) {
|
|
7080
|
-
mountRemoveButton(item, () => handleRemoveItem(item), ctx.state);
|
|
7081
|
-
}
|
|
7082
|
-
itemsWrap.appendChild(item);
|
|
7083
7031
|
});
|
|
7084
7032
|
}
|
|
7085
7033
|
if (!containerIsReadonly) {
|
|
7086
7034
|
while (countItems() < min) {
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
state: ctx.state,
|
|
7090
|
-
instance: ctx.instance,
|
|
7091
|
-
path: pathJoin(ctx.path, `${element.key}[${idx}]`),
|
|
7092
|
-
prefill: childDefaults,
|
|
7093
|
-
// Defaults for enableIf evaluation
|
|
7094
|
-
formData: (_d = ctx.formData) != null ? _d : ctx.prefill,
|
|
7095
|
-
// Complete root data for enableIf
|
|
7096
|
-
inheritedReadonly: childInheritedReadonly
|
|
7097
|
-
};
|
|
7098
|
-
const item = document.createElement("div");
|
|
7099
|
-
item.className = "containerItem border border-gray-300 rounded-lg p-2 bg-white";
|
|
7100
|
-
item.setAttribute("data-container-item", `${element.key}[${idx}]`);
|
|
7101
|
-
if (isSlides) {
|
|
7102
|
-
item.setAttribute("data-fb-slide-card", "");
|
|
7103
|
-
}
|
|
7104
|
-
const childWrapper = document.createElement("div");
|
|
7105
|
-
childWrapper.className = getChildWrapperClass(
|
|
7106
|
-
isSlides ? void 0 : element.columns
|
|
7107
|
-
);
|
|
7108
|
-
element.elements.forEach((child) => {
|
|
7109
|
-
var _a2;
|
|
7110
|
-
if (child.type !== "markdown" && (child.hidden || child.type === "hidden")) {
|
|
7111
|
-
childWrapper.appendChild(
|
|
7112
|
-
createHiddenInput(
|
|
7113
|
-
pathJoin(subCtx.path, child.key),
|
|
7114
|
-
(_a2 = "default" in child ? child.default : null) != null ? _a2 : null
|
|
7115
|
-
)
|
|
7116
|
-
);
|
|
7117
|
-
} else {
|
|
7118
|
-
childWrapper.appendChild(renderElement(child, subCtx));
|
|
7119
|
-
}
|
|
7120
|
-
});
|
|
7121
|
-
item.appendChild(childWrapper);
|
|
7122
|
-
mountRemoveButton(
|
|
7123
|
-
item,
|
|
7124
|
-
() => {
|
|
7125
|
-
if (countItems() > min) {
|
|
7126
|
-
handleRemoveItem(item);
|
|
7127
|
-
}
|
|
7128
|
-
},
|
|
7129
|
-
ctx.state
|
|
7035
|
+
itemsWrap.appendChild(
|
|
7036
|
+
createContainerItem(takeRowIndex(), null, (_d = ctx.formData) != null ? _d : ctx.prefill)
|
|
7130
7037
|
);
|
|
7131
|
-
itemsWrap.appendChild(item);
|
|
7132
7038
|
}
|
|
7133
7039
|
}
|
|
7134
7040
|
containerWrap.appendChild(itemsWrap);
|
|
@@ -7196,15 +7102,7 @@ function validateContainerElement(element, key, context) {
|
|
|
7196
7102
|
};
|
|
7197
7103
|
if ("multiple" in element && element.multiple) {
|
|
7198
7104
|
const items = [];
|
|
7199
|
-
const
|
|
7200
|
-
"[data-container-item]"
|
|
7201
|
-
);
|
|
7202
|
-
const containerWrappers = Array.from(allContainerWrappers).filter((el) => {
|
|
7203
|
-
const attr = el.getAttribute("data-container-item") || "";
|
|
7204
|
-
if (!attr.startsWith(`${key}[`)) return false;
|
|
7205
|
-
const suffix = attr.slice(key.length);
|
|
7206
|
-
return /^\[\d+\]$/.test(suffix);
|
|
7207
|
-
});
|
|
7105
|
+
const containerWrappers = findDirectContainerRows(scopeRoot, key);
|
|
7208
7106
|
containerWrappers.forEach((itemContainer) => {
|
|
7209
7107
|
const itemData = {};
|
|
7210
7108
|
const containerAttr = itemContainer.getAttribute("data-container-item") || "";
|
|
@@ -7330,9 +7228,7 @@ function updateContainerField(element, fieldPath, value, context) {
|
|
|
7330
7228
|
});
|
|
7331
7229
|
}
|
|
7332
7230
|
});
|
|
7333
|
-
const existingContainers = scopeRoot
|
|
7334
|
-
`[data-container-item^="${fieldPath}["]`
|
|
7335
|
-
);
|
|
7231
|
+
const existingContainers = findDirectContainerRows(scopeRoot, fieldPath);
|
|
7336
7232
|
if (value.length !== existingContainers.length) {
|
|
7337
7233
|
console.warn(
|
|
7338
7234
|
`updateContainerField: Multiple container field "${fieldPath}" item count mismatch. Consider re-rendering for add/remove.`
|
|
@@ -10929,9 +10825,6 @@ var defaultConfig = {
|
|
|
10929
10825
|
hintRequired: "Required",
|
|
10930
10826
|
hintOptional: "Optional",
|
|
10931
10827
|
hintPattern: "Format: {pattern}",
|
|
10932
|
-
fileCountSingle: "{count} file",
|
|
10933
|
-
fileCountPlural: "{count} files",
|
|
10934
|
-
fileCountWithMax: "{count} / {max} files",
|
|
10935
10828
|
fileCountRange: "({min}-{max})",
|
|
10936
10829
|
uploadingFile: "Uploading\u2026",
|
|
10937
10830
|
filesCounter: "{count}/{max}",
|
|
@@ -11005,9 +10898,6 @@ var defaultConfig = {
|
|
|
11005
10898
|
hintRequired: "\u041E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0435",
|
|
11006
10899
|
hintOptional: "\u041D\u0435\u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0435",
|
|
11007
10900
|
hintPattern: "\u0424\u043E\u0440\u043C\u0430\u0442: {pattern}",
|
|
11008
|
-
fileCountSingle: "{count} \u0444\u0430\u0439\u043B",
|
|
11009
|
-
fileCountPlural: "{count} \u0444\u0430\u0439\u043B\u043E\u0432",
|
|
11010
|
-
fileCountWithMax: "{count} / {max} \u0444\u0430\u0439\u043B\u043E\u0432",
|
|
11011
10901
|
fileCountRange: "({min}-{max})",
|
|
11012
10902
|
uploadingFile: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430\u2026",
|
|
11013
10903
|
filesCounter: "{count}/{max}",
|
|
@@ -12180,17 +12070,12 @@ var FormBuilderInstance = class {
|
|
|
12180
12070
|
}
|
|
12181
12071
|
}
|
|
12182
12072
|
if ((element.type === "container" || element.type === "group") && "elements" in element && element.elements) {
|
|
12183
|
-
const containerData = element.key ? formData
|
|
12073
|
+
const containerData = element.key ? getValueByPath(formData, fullPath) : void 0;
|
|
12184
12074
|
if (Array.isArray(containerData)) {
|
|
12185
|
-
const
|
|
12186
|
-
|
|
12075
|
+
const directItems = findDirectContainerRows(
|
|
12076
|
+
this.state.formRoot,
|
|
12077
|
+
fullPath
|
|
12187
12078
|
);
|
|
12188
|
-
const directItems = fullPath ? Array.from(containerItems).filter((el) => {
|
|
12189
|
-
const attr = el.getAttribute("data-container-item") || "";
|
|
12190
|
-
if (!attr.startsWith(`${fullPath}[`)) return false;
|
|
12191
|
-
const suffix = attr.slice(fullPath.length);
|
|
12192
|
-
return /^\[\d+\]$/.test(suffix);
|
|
12193
|
-
}) : [];
|
|
12194
12079
|
directItems.forEach((el) => {
|
|
12195
12080
|
const attr = el.getAttribute("data-container-item") || "";
|
|
12196
12081
|
checkElements(element.elements, attr);
|