@unvired/turboforms-embed-sdk 2.0.61 → 2.0.62

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.
@@ -7168,14 +7168,15 @@
7168
7168
  min-width: 50px !important;
7169
7169
  }
7170
7170
 
7171
- /* 7b. Hide inner component labels and control-label--hidden inside DataGrid table body cells */
7172
- .tf-embed-sdk .formio-component-datagrid table tbody td label:not(.form-check-label):not(.custom-control-label),
7173
- .tf-embed-sdk .formio-component-datagrid table tbody td .col-form-label,
7174
- .tf-embed-sdk .formio-component-datagrid table tbody td .control-label--hidden,
7175
- .tf-embed-sdk .formio-component-datagrid table tbody td [ref="label"],
7176
- .tf-embed-sdk .formio-component-datagrid .formio-component-label-hidden label:not(.form-check-label):not(.custom-control-label),
7177
- .tf-embed-sdk .formio-component-datagrid .formio-component-label-hidden .col-form-label,
7178
- .tf-embed-sdk .formio-component-datagrid .formio-component-label-hidden .control-label--hidden {
7171
+ /* 7b. Hide component labels ONLY for direct children of DataGrid table body cells (where thead header displays the column title) */
7172
+ .tf-embed-sdk .formio-component-datagrid table.datagrid-table > tbody > tr > td > .formio-component > label:not(.form-check-label):not(.custom-control-label),
7173
+ .tf-embed-sdk .formio-component-datagrid table.datagrid-table > tbody > tr > td > .formio-component > .col-form-label,
7174
+ .tf-embed-sdk .formio-component-datagrid table.datagrid-table > tbody > tr > td > .formio-component > [ref="label"],
7175
+ .tf-embed-sdk .formio-component-datagrid table.datagrid-table > tbody > tr > td > .formio-component > .control-label--hidden,
7176
+ .tf-embed-sdk .formio-component-datagrid table.datagrid-table > tbody > tr > td > .formio-form-group > label:not(.form-check-label):not(.custom-control-label),
7177
+ .tf-embed-sdk .formio-component-datagrid table.datagrid-table > tbody > tr > td > .formio-form-group > .col-form-label,
7178
+ .tf-embed-sdk .formio-component-datagrid table.datagrid-table > tbody > tr > td > .formio-form-group > [ref="label"],
7179
+ .tf-embed-sdk .formio-component-datagrid table.datagrid-table > tbody > tr > td > .formio-form-group > .control-label--hidden {
7179
7180
  display: none !important;
7180
7181
  margin: 0 !important;
7181
7182
  padding: 0 !important;
@@ -7187,9 +7188,15 @@
7187
7188
  visibility: hidden !important;
7188
7189
  }
7189
7190
 
7190
- /* Remove component vertical margins inside DataGrid cells for tight layout */
7191
- .tf-embed-sdk .formio-component-datagrid table tbody td .formio-form-group,
7192
- .tf-embed-sdk .formio-component-datagrid table tbody td .formio-component {
7191
+ /* For explicitly hidden labels (hideLabel: true), hide the label element */
7192
+ .tf-embed-sdk .formio-component-label-hidden > label.control-label--hidden,
7193
+ .tf-embed-sdk .formio-component-label-hidden > .control-label--hidden {
7194
+ display: none !important;
7195
+ }
7196
+
7197
+ /* Reset direct component vertical margins inside DataGrid cells for tight layout */
7198
+ .tf-embed-sdk .formio-component-datagrid table.datagrid-table > tbody > tr > td > .formio-form-group,
7199
+ .tf-embed-sdk .formio-component-datagrid table.datagrid-table > tbody > tr > td > .formio-component {
7193
7200
  margin-top: 0 !important;
7194
7201
  margin-bottom: 0 !important;
7195
7202
  }
@@ -39426,18 +39433,38 @@ function getValueFromData(data, path) {
39426
39433
  return current;
39427
39434
  }
39428
39435
 
39436
+ /**
39437
+ * Helper to check if a component instance has an empty value.
39438
+ */
39429
39439
  /**
39430
39440
  * Helper to check if a component instance has an empty value.
39431
39441
  */
39432
39442
  function isComponentEmpty(inst) {
39433
39443
  if (!inst) return true;
39434
- const val = inst.getValue ? inst.getValue() : inst.dataValue;
39444
+ let val = inst.getValue ? inst.getValue() : inst.dataValue;
39445
+
39446
+ if (val === undefined || val === null || val === "") return true;
39447
+
39448
+ if (Array.isArray(val)) {
39449
+ if (val.length === 0) return true;
39450
+ const hasValidItem = val.some(item => {
39451
+ if (item === undefined || item === null || item === "") return false;
39452
+ if (typeof item === "object" && Object.keys(item).length === 0) return false;
39453
+ return true;
39454
+ });
39455
+ if (!hasValidItem) return true;
39456
+ }
39457
+
39458
+ if (typeof val === "object" && !Array.isArray(val)) {
39459
+ if (Object.keys(val).length === 0) return true;
39460
+ const hasValidVal = Object.values(val).some(v => v !== undefined && v !== null && v !== "" && v !== false);
39461
+ if (!hasValidVal) return true;
39462
+ }
39463
+
39435
39464
  if (inst.isEmpty) {
39436
39465
  return inst.isEmpty(val);
39437
39466
  }
39438
- if (val === undefined || val === null || val === "") return true;
39439
- if (Array.isArray(val) && val.length === 0) return true;
39440
- if (typeof val === "object" && !Array.isArray(val) && Object.keys(val).length === 0) return true;
39467
+
39441
39468
  return false;
39442
39469
  }
39443
39470
 
@@ -39490,10 +39517,44 @@ function clearComponentErrorUI(inst) {
39490
39517
  inst.setCustomValidity("");
39491
39518
  }
39492
39519
  inst.element.classList.remove("has-error", "formio-error-wrapper", "is-invalid");
39493
- inst.element.querySelectorAll(".is-invalid").forEach((el) => el.classList.remove("is-invalid"));
39494
- inst.element.querySelectorAll(".formio-errors, .invalid-feedback").forEach((el) => {
39495
- el.innerHTML = "";
39496
- el.style.display = "none";
39520
+
39521
+ // Only remove .is-invalid from direct choice or input elements belonging to this component
39522
+ const choices = inst.element.querySelectorAll(".choices__inner, .ui.selection.dropdown, .is-invalid");
39523
+ choices.forEach((el) => {
39524
+ if (el.closest(".formio-component") === inst.element) {
39525
+ el.classList.remove("is-invalid");
39526
+ }
39527
+ });
39528
+
39529
+ // Clear error message container ONLY if it belongs directly to inst.element (not a child component)
39530
+ const errorLabels = inst.element.querySelectorAll(".formio-errors, .invalid-feedback, [ref='messageContainer']");
39531
+ errorLabels.forEach((errorLabel) => {
39532
+ if (errorLabel.closest(".formio-component") === inst.element) {
39533
+ errorLabel.innerHTML = "";
39534
+ errorLabel.style.display = "none";
39535
+ }
39536
+ });
39537
+ }
39538
+
39539
+ /**
39540
+ * Scans all component instances in the form and clears error UI for any component that has been filled.
39541
+ */
39542
+ function clearResolvedErrors(form) {
39543
+ if (!form || typeof form.everyComponent !== "function") return;
39544
+ form.everyComponent((inst) => {
39545
+ if (!inst || !inst.element) return;
39546
+ const compType = inst.component?.type || inst.type;
39547
+ const isContainerType = ["datagrid", "editgrid", "container", "panel", "columns", "fieldset", "well", "tabs", "form"].includes(compType);
39548
+ if (isContainerType) return;
39549
+
39550
+ // Check if this component currently displays error styling
39551
+ const hasErrorClass = inst.element.classList.contains("has-error") || inst.element.classList.contains("formio-error-wrapper");
39552
+ const hasVisibleError = Array.from(inst.element.querySelectorAll(".formio-errors, .invalid-feedback"))
39553
+ .some(el => el.style.display !== "none" && el.innerHTML.trim() !== "" && el.closest(".formio-component") === inst.element);
39554
+
39555
+ if ((hasErrorClass || hasVisibleError) && !isComponentEmpty(inst)) {
39556
+ clearComponentErrorUI(inst);
39557
+ }
39497
39558
  });
39498
39559
  }
39499
39560
 
@@ -39504,13 +39565,17 @@ function showComponentErrorUI(inst, err) {
39504
39565
  if (!inst || !inst.element) return;
39505
39566
  inst.element.classList.add("has-error", "formio-error-wrapper");
39506
39567
  const choices = inst.element.querySelector(".choices__inner, .ui.selection.dropdown");
39507
- if (choices) choices.classList.add("is-invalid");
39568
+ if (choices && choices.closest(".formio-component") === inst.element) {
39569
+ choices.classList.add("is-invalid");
39570
+ }
39508
39571
 
39509
39572
  const msg = err.message || (err.context?.component?.label ? `${err.context.component.label} is required` : `${inst.component?.label || inst.key} is required`);
39510
39573
  const compId = inst.id || inst.component?.id || inst.key;
39511
39574
  const innerErrorId = `e-${compId}-${inst.key}`;
39512
39575
 
39513
- let errorLabel = inst.element.querySelector(".formio-errors, [ref='messageContainer']");
39576
+ let errorLabel = Array.from(inst.element.querySelectorAll(".formio-errors, [ref='messageContainer']"))
39577
+ .find(el => el.closest(".formio-component") === inst.element);
39578
+
39514
39579
  if (!errorLabel) {
39515
39580
  errorLabel = document.createElement("div");
39516
39581
  errorLabel.setAttribute("ref", "messageContainer");
@@ -39536,13 +39601,8 @@ function setupOnChange(privateExternal, permission) {
39536
39601
  document.activeElement.blur();
39537
39602
  }
39538
39603
 
39539
- // Immediately clear error UI for any component that has been filled
39540
- if (event?.changed?.instance) {
39541
- const inst = event.changed.instance;
39542
- if (!isComponentEmpty(inst)) {
39543
- clearComponentErrorUI(inst);
39544
- }
39545
- }
39604
+ // Immediately clear error UI for any filled component across the form (including DataGrid rows)
39605
+ clearResolvedErrors(formObj);
39546
39606
 
39547
39607
  // Clear existing timeout
39548
39608
  if (changeTimeout) {
@@ -41582,7 +41642,7 @@ initThemeHook();
41582
41642
  </div>
41583
41643
 
41584
41644
  <div id="sticky-footer">
41585
- <div class="build-version">SDK v2.0.61</div>
41645
+ <div class="build-version">SDK v2.0.62</div>
41586
41646
 
41587
41647
  <button class="footer-btn footer-btn-secondary" id="prevBtn" style="display:none" onclick="FormOnPrevious()">
41588
41648
  <i class="bi bi-chevron-left"></i> Previous