+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/.content.xml
new file mode 100644
index 0000000000..295eb8dcaa
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/.content.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/editor/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/editor/.content.xml
new file mode 100644
index 0000000000..8432f275ce
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/editor/.content.xml
@@ -0,0 +1,5 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/editor/js.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/editor/js.txt
new file mode 100644
index 0000000000..b052954804
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/editor/js.txt
@@ -0,0 +1,2 @@
+#base=js
+adobesignblock.js
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/editor/js/adobesignblock.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/editor/js/adobesignblock.js
new file mode 100644
index 0000000000..d85f27e347
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/editor/js/adobesignblock.js
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright 2024 Adobe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+(function($) {
+ "use strict";
+
+ const Utils = window.CQ.FormsCoreComponents.Utils.v1,
+ EDIT_DIALOG = ".cmp-adaptiveform-adobesignblock__editdialog";
+
+ Utils.initializeEditDialog(EDIT_DIALOG)();
+})(jQuery);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/site/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/site/.content.xml
new file mode 100644
index 0000000000..1f39269f89
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/adobesignblock/v1/adobesignblock/clientlibs/site/.content.xml
@@ -0,0 +1,4 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/_cq_dialog/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/_cq_dialog/.content.xml
index 0f41726075..fdb3c4e35b 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/_cq_dialog/.content.xml
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/_cq_dialog/.content.xml
@@ -18,7 +18,7 @@
jcr:primaryType="nt:unstructured"
jcr:title="Adaptive Form Container"
sling:resourceType="cq/gui/components/authoring/dialog"
- extraClientlibs="[core.forms.components.container.v1.editor]"
+ extraClientlibs="[core.forms.components.container.v1.editor,core.forms.components.container.v2.editor]"
helpPath="https://www.adobe.com/go/aem_af_cmp_container_v2"
trackingFeature="core-components:adaptiveform-container:v2">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ label {
+ /* Hide the "Title" label in collapsed view; visible when fields expand */
+ display: none;
+}
+
+.cmp-signer-title-row > input,
+.cmp-signer-title-row > coral-textfield {
+ flex: 1;
+ min-width: 0;
+}
+
+/* Push the toggle button to the right, matching foundation's pencil alignment */
+.cmp-signer-toggle-btn {
+ flex-shrink: 0;
+ margin-left: auto;
+}
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editor/js/editDialog.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editor/js/editDialog.js
index 2991e6074f..49101f7ac5 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editor/js/editDialog.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editor/js/editDialog.js
@@ -13,7 +13,232 @@
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
-(function($, channel, Coral) {
+(function($, Granite, channel, Coral) {
"use strict";
-})(jQuery, jQuery(document), Coral);
\ No newline at end of file
+ var EDIT_DIALOG_FORM = ".cmp-adaptiveform-formcontainer__editdialog",
+ ADOBE_SIGN_CHECKBOX = "coral-checkbox[name='./_useSignedPdf']",
+ ADOBE_SIGN_FIELDS = ".cmp-adobesign-fields",
+ SIGNERS_MULTIFIELD = "coral-multifield[name='./signerInfo/signers']",
+ SIGNER_TITLE_INPUT = "input[name='./signerTitle']",
+ DEFAULT_SIGNER = "Signer One",
+
+ Utils = window.CQ.FormsCoreComponents.Utils.v1;
+
+ /**
+ * Reads the current value from a Coral 3 coral-select. The component
+ * exposes the selection through selectedItem; .value alone is not reliable
+ * when the dialog loads or after programmatic updates (same pattern as other
+ * core component edit dialogs, e.g. dropdown, checkbox).
+ */
+ function getCoralSelectValue(selectEl) {
+ if (!selectEl) {
+ return "";
+ }
+ if (selectEl.selectedItem && selectEl.selectedItem.value !== undefined &&
+ selectEl.selectedItem.value !== null) {
+ return String(selectEl.selectedItem.value);
+ }
+ return selectEl.value ? String(selectEl.value) : "";
+ }
+
+ function onCoralSelectChange($select, handler) {
+ if (!$select.length) {
+ return;
+ }
+ var el = $select[0];
+ Coral.commons.ready(el, function() {
+ handler();
+ });
+ $select.off("change.cmpSigner coral-select:change.cmpSigner");
+ $select.on("change.cmpSigner coral-select:change.cmpSigner", handler);
+ }
+
+ // ---------------------------------------------------------------------------
+ // Conditionals within a single expanded signer item
+ // ---------------------------------------------------------------------------
+
+ function applySignerConditionals($item) {
+ if ($item.data("cmp-signer-conditionals-bound")) {
+ var refresh = $item.data("cmp-signer-conditionals-refresh");
+ if (typeof refresh === "function") {
+ refresh();
+ }
+ return;
+ }
+ $item.data("cmp-signer-conditionals-bound", true);
+
+ // --- Email source toggle ---
+ var $emailTypeSelect = $item.find("coral-select[name='./signerEmailType']");
+ var $emailRef = $item.find(".cmp-signer-email-ref");
+ var $emailInput = $item.find(".cmp-signer-email-input");
+
+ function toggleEmail() {
+ var val = getCoralSelectValue($emailTypeSelect[0]) || "fromForm";
+ // fromForm → show ref selector; typed → show text input; userProfile → hide both
+ $emailRef.toggle(val === "fromForm");
+ $emailInput.toggle(val === "typed");
+ }
+ onCoralSelectChange($emailTypeSelect, toggleEmail);
+
+ // --- Auth method toggle (phone block + typed-only inputs) ---
+ var $authSelect = $item.find("coral-select[name='./authenticationMethod']");
+ var $phoneAuthBlock = $item.find(".cmp-signer-phone-auth-fields");
+ var $countryTyped = $item.find(".cmp-signer-country-typed");
+ var $phoneTyped = $item.find(".cmp-signer-phone-typed");
+ var $countrySource = $item.find("coral-select[name='./countryCodeSource']");
+ var $phoneSource = $item.find("coral-select[name='./phoneSource']");
+
+ function togglePhone() {
+ var auth = getCoralSelectValue($authSelect[0]) || "NONE";
+ var showPhone = auth === "PHONE";
+ if ($phoneAuthBlock.length) {
+ $phoneAuthBlock.toggle(showPhone);
+ } else {
+ // Legacy dialog markup (per-field wrapperClass only)
+ $item.find(".cmp-signer-phone-field").toggle(showPhone);
+ }
+ if (showPhone) {
+ applyCountryTyped();
+ applyPhoneTyped();
+ } else {
+ $countryTyped.hide();
+ $phoneTyped.hide();
+ }
+ }
+
+ function applyCountryTyped() {
+ var auth = getCoralSelectValue($authSelect[0]) || "NONE";
+ if (auth !== "PHONE") {
+ return;
+ }
+ var src = getCoralSelectValue($countrySource[0]) || "form";
+ $countryTyped.toggle(src === "typed");
+ }
+
+ function applyPhoneTyped() {
+ var auth = getCoralSelectValue($authSelect[0]) || "NONE";
+ if (auth !== "PHONE") {
+ return;
+ }
+ var src = getCoralSelectValue($phoneSource[0]) || "form";
+ $phoneTyped.toggle(src === "typed");
+ }
+
+ function refreshSignerConditionals() {
+ toggleEmail();
+ togglePhone();
+ }
+ $item.data("cmp-signer-conditionals-refresh", refreshSignerConditionals);
+
+ onCoralSelectChange($authSelect, togglePhone);
+ onCoralSelectChange($countrySource, function() {
+ applyCountryTyped();
+ });
+ onCoralSelectChange($phoneSource, function() {
+ applyPhoneTyped();
+ });
+
+ refreshSignerConditionals();
+ }
+
+ // ---------------------------------------------------------------------------
+ // Signer rows — compact "title + edit icon" collapsed view inside the
+ // coral-multifield, matching the foundation form's signer table appearance.
+ // ---------------------------------------------------------------------------
+
+ function transformSignerItem($item, startExpanded) {
+ Coral.commons.ready($item[0], function() {
+ var $content = $item.find("coral-multifield-item-content");
+ if (!$content.length) $content = $item;
+
+ var $wrappers = $content.children();
+ if ($wrappers.length < 2) {
+ // Collapse UI expects title row + detail rows; composite items often render
+ // as a single wrapper — still wire email/auth visibility.
+ applySignerConditionals($item);
+ return;
+ }
+
+ if ($item.data("cmp-signer-decorated")) return;
+ $item.data("cmp-signer-decorated", true);
+
+ var $titleWrapper = $wrappers.first();
+ var $detailWrappers = $wrappers.slice(1);
+
+ var $toggle = $('');
+
+ var expanded = !!startExpanded;
+
+ function applyState() {
+ $detailWrappers.toggle(expanded);
+ $toggle.find("coral-icon").attr("icon", expanded ? "chevronUp" : "edit");
+ if (expanded) {
+ applySignerConditionals($item);
+ }
+ }
+
+ $toggle.on("click", function(e) {
+ e.stopPropagation();
+ expanded = !expanded;
+ applyState();
+ });
+
+ $titleWrapper.addClass("cmp-signer-title-row");
+ $titleWrapper.append($toggle);
+
+ applyState();
+ });
+ }
+
+ function initSignerRows(dialog) {
+ var multifield = dialog.find(SIGNERS_MULTIFIELD)[0];
+ if (!multifield) return;
+
+ Coral.commons.ready(multifield, function() {
+ var $multifield = $(multifield);
+
+ if (multifield.items.length === 0) {
+ var item = multifield.items.add({});
+ Coral.commons.ready(item, function() {
+ var titleInput = item.querySelector(SIGNER_TITLE_INPUT);
+ if (titleInput) titleInput.value = DEFAULT_SIGNER;
+ transformSignerItem($(item), false);
+ });
+ } else {
+ $multifield.find("coral-multifield-item").each(function() {
+ transformSignerItem($(this), false);
+ });
+ }
+
+ // Items added via "Add Signer" start expanded so author can fill them in
+ $multifield.on("coral-multifield:itemadded", function(e) {
+ transformSignerItem($(e.detail.item), true);
+ });
+ });
+ }
+
+ // ---------------------------------------------------------------------------
+ // Adobe Sign tab — show / hide all fields except the checkbox
+ // ---------------------------------------------------------------------------
+
+ function initAdobeSign(dialog) {
+ var $checkbox = dialog.find(ADOBE_SIGN_CHECKBOX);
+ var $fields = dialog.find(ADOBE_SIGN_FIELDS);
+
+ function toggleFields() {
+ $fields.toggle($checkbox.length > 0 && $checkbox[0].checked);
+ }
+
+ toggleFields();
+ $checkbox.on("change", toggleFields);
+
+ initSignerRows(dialog);
+ }
+
+ Utils.initializeEditDialog(EDIT_DIALOG_FORM)(initAdobeSign);
+
+})(jQuery, Granite, jQuery(document), Coral);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/.content.xml
index a669a393cf..5bc1892ac0 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/.content.xml
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/.content.xml
@@ -1,4 +1,5 @@
+ categories="[core.forms.components.container.editor.hook.v2,cq.authoring.editor.hook]"
+ dependencies="[guides.touchAuthoringCommon]"/>
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/componentutils.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/componentutils.js
index 7350a1cd49..088d0377d1 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/componentutils.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editorhook/js/componentutils.js
@@ -82,7 +82,13 @@
}
}
- comData["sling:resourceType"] = config.resourceType;
+ const resourceType = window.CQ.FormsCoreComponents.editorhooks.toCoreSigningResourceType
+ ? window.CQ.FormsCoreComponents.editorhooks.toCoreSigningResourceType(config.resourceType)
+ : config.resourceType;
+ comData["sling:resourceType"] = resourceType;
+ if (window.CQ.FormsCoreComponents.editorhooks.remapSigningContentPayload) {
+ window.CQ.FormsCoreComponents.editorhooks.remapSigningContentPayload(comData);
+ }
updatedProps = {...comData, ...updatedProps};
this.setParam(":content", JSON.stringify(updatedProps)); // write component properties
}
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/.content.xml
new file mode 100644
index 0000000000..e868fd238f
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/.content.xml
@@ -0,0 +1,23 @@
+
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/.content.xml
new file mode 100644
index 0000000000..491392d539
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/.content.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/.content.xml
new file mode 100644
index 0000000000..8790abd717
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/.content.xml
@@ -0,0 +1,24 @@
+
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/_cq_dialog/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/_cq_dialog/.content.xml
new file mode 100644
index 0000000000..e9a8c2621e
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/_cq_dialog/.content.xml
@@ -0,0 +1,176 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/_cq_template.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/_cq_template.xml
new file mode 100644
index 0000000000..45edf9ec5f
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/_cq_template.xml
@@ -0,0 +1,9 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/.content.xml
new file mode 100644
index 0000000000..e97a72c7e1
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/.content.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/editor/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/editor/.content.xml
new file mode 100644
index 0000000000..b4e403e0c3
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/editor/.content.xml
@@ -0,0 +1,5 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/editor/js.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/editor/js.txt
new file mode 100644
index 0000000000..57f9775ff8
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/editor/js.txt
@@ -0,0 +1,2 @@
+#base=js
+signaturestep.js
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/editor/js/signaturestep.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/editor/js/signaturestep.js
new file mode 100644
index 0000000000..ad0dcfecfe
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/editor/js/signaturestep.js
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright 2024 Adobe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+(function($) {
+ "use strict";
+
+ const Utils = window.CQ.FormsCoreComponents.Utils.v1,
+ EDIT_DIALOG = ".cmp-adaptiveform-signaturestep__editdialog";
+
+ Utils.initializeEditDialog(EDIT_DIALOG)();
+})(jQuery);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/.content.xml
new file mode 100644
index 0000000000..e8b435d7fe
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/.content.xml
@@ -0,0 +1,6 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/css.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/css.txt
new file mode 100644
index 0000000000..2edfd10bde
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/css.txt
@@ -0,0 +1,2 @@
+#base=css
+signaturestepview.css
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/css/signaturestepview.css b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/css/signaturestepview.css
new file mode 100644
index 0000000000..0ed4c0a5f5
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/css/signaturestepview.css
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2024 Adobe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+.cmp-adaptiveform-signaturestep {
+ display: block;
+ position: relative;
+ box-sizing: border-box;
+ overflow: auto;
+ max-width: 100%;
+}
+
+.cmp-adaptiveform-signaturestep__header {
+}
+
+.cmp-adaptiveform-signaturestep__title {
+ display: block;
+}
+
+.cmp-adaptiveform-signaturestep__body {
+ width: 100%;
+ overflow: auto;
+ box-sizing: border-box;
+}
+
+.cmp-adaptiveform-signaturestep__template-message {
+ overflow: auto;
+ box-sizing: border-box;
+}
+
+/* iframe: inline style controls show/hide */
+.cmp-adaptiveform-signaturestep__iframe {
+ width: 100%;
+ border: none;
+}
+
+.cmp-adaptiveform-signaturestep__error {
+}
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/js.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/js.txt
new file mode 100644
index 0000000000..256c4d98f7
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/js.txt
@@ -0,0 +1,2 @@
+#base=js
+signaturestepview.js
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/js/signaturestepview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/js/signaturestepview.js
new file mode 100644
index 0000000000..5ced397730
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/js/signaturestepview.js
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright 2024 Adobe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+(function () {
+ "use strict";
+
+ class SignatureStep extends FormView.FormFieldBase {
+
+ static NS = FormView.Constants.NS;
+ static IS = "adaptiveFormSignatureStep";
+ static bemBlock = 'cmp-adaptiveform-signaturestep';
+ static selectors = {
+ self: `[data-${this.NS}-is="${this.IS}"]`,
+ header: `.${this.bemBlock}__header`,
+ body: `.${this.bemBlock}__body`,
+ iframe: `.${this.bemBlock}__iframe`,
+ templateMessage: `.${this.bemBlock}__template-message`,
+ errorDiv: `.${this.bemBlock}__error`,
+ };
+
+ // Target version that indicates multi-user Adobe Sign agreement flow
+ static ADOBE_SIGN_MULTI_USER_VERSION = "1.1";
+
+ constructor(params) {
+ super(params);
+ this._messageHandler = this.#onIframeMessage.bind(this);
+ }
+
+ getClass() { return SignatureStep.IS; }
+
+ getWidget() { return null; }
+ getLabel() { return null; }
+ getErrorDiv() { return null; }
+ getTooltipDiv() { return null; }
+ getQuestionMarkDiv() { return null; }
+
+ setModel(model) {
+ super.setModel(model);
+ }
+
+ // Called when the component visibility changes.
+ // Initialize the signing flow when the step first becomes visible.
+ updateVisible(visible, payload) {
+ super.updateVisible(visible, payload);
+ if (visible && !this._signingInitialized) {
+ this._signingInitialized = true;
+ this.#initializeSigning();
+ }
+ }
+
+ // Determine the signing flow from model properties and begin it.
+ #initializeSigning() {
+ const props = this.getModel().properties;
+ const signingService = props["fd:signingService"];
+ const targetVersion = props["fd:targetVersion"];
+ const cloudServiceConfig = props["fd:cloudServiceConfig"] || "";
+
+ if (signingService === "echosign" && targetVersion === SignatureStep.ADOBE_SIGN_MULTI_USER_VERSION) {
+ // Modern multi-user Adobe Sign flow: submit as agreement to get signing URL
+ this.#initAgreementFlow(cloudServiceConfig);
+ }
+ // Scribble and legacy echosign flows are handled by the AF Runtime submit pipeline.
+ }
+
+ // Post the form as an agreement to obtain the Adobe Sign signing URL,
+ // then load that URL inside the iframe.
+ #initAgreementFlow(cloudServiceConfig) {
+ const formContainer = this.formContainer;
+ const action = formContainer.getModel().action;
+
+ if (!action) {
+ this.#showError("Form action URL is not configured.");
+ return;
+ }
+
+ const body = new URLSearchParams({
+ submissionSelector: 'agreement',
+ cloudService: cloudServiceConfig
+ });
+
+ fetch(action, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ body: body.toString()
+ })
+ .then(response => {
+ if (!response.ok) {
+ throw new Error(`Server returned ${response.status}`);
+ }
+ return response.json();
+ })
+ .then(data => {
+ if (data && data.signingURL) {
+ this.#loadSigningIframe(data.signingURL);
+ } else {
+ this.#showError("Failed to retrieve signing URL from Adobe Sign.");
+ }
+ })
+ .catch(err => {
+ this.#showError("Adobe Sign initialization failed: " + err.message);
+ });
+ }
+
+ // Show the Adobe Sign iframe with the given signing URL and register
+ // the cross-origin message listener for the ESIGN completion event.
+ #loadSigningIframe(signingURL) {
+ const iframe = this.element.querySelector(SignatureStep.selectors.iframe);
+ const templateMsg = this.element.querySelector(SignatureStep.selectors.templateMessage);
+
+ if (templateMsg) templateMsg.style.display = 'none';
+ if (iframe) {
+ iframe.style.display = 'block';
+ iframe.src = signingURL;
+ }
+
+ // Listen for the ESIGN message posted by the Adobe Sign iframe on completion.
+ window.addEventListener('message', this._messageHandler, false);
+ }
+
+ // Handle postMessage events from the Adobe Sign iframe.
+ // Adobe Sign sends { type: 'ESIGN' } when the user completes signing.
+ #onIframeMessage(event) {
+ try {
+ const data = typeof event.data === 'string' ? JSON.parse(event.data) : event.data;
+ if (data && data.type === 'ESIGN') {
+ window.removeEventListener('message', this._messageHandler, false);
+ this.#onSigningComplete();
+ }
+ } catch (e) {
+ // Ignore messages from other origins that are not JSON
+ }
+ }
+
+ // Signing is complete — navigate to the next step in the wizard.
+ #onSigningComplete() {
+ try {
+ const formModel = this.formContainer.getModel();
+ if (formModel && typeof formModel.setFocus === 'function') {
+ formModel.setFocus(null);
+ }
+ } catch (e) {
+ // Guard — do not crash if navigation is unavailable
+ }
+ }
+
+ #showError(message) {
+ const errorDiv = this.element.querySelector(SignatureStep.selectors.errorDiv);
+ const templateMsg = this.element.querySelector(SignatureStep.selectors.templateMessage);
+ if (templateMsg) templateMsg.style.display = 'none';
+ if (errorDiv) {
+ errorDiv.textContent = message;
+ errorDiv.style.display = 'block';
+ }
+ }
+ }
+
+ FormView.Utils.setupField(({ element, formContainer }) => {
+ return new SignatureStep({ element, formContainer });
+ }, SignatureStep.selectors.self);
+
+})();
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/signaturestep.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/signaturestep.html
new file mode 100644
index 0000000000..594b26150d
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/signaturestep.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+ ${signaturestep.label.value @ context='text'}
+
+
+
+
+
+
${signaturestep.displayMsg @ context='text'}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/signaturestep.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/signaturestep.js
new file mode 100644
index 0000000000..fda21489fa
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/signaturestep.js
@@ -0,0 +1,34 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2024 Adobe
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+use(function () {
+
+ var clientlibsArr = ['core.forms.components.base.v1.editor'];
+ var labelPath = 'core/fd/components/af-commons/v1/fieldTemplates/label.html';
+ var shortDescriptionPath = "core/fd/components/af-commons/v1/fieldTemplates/shortDescription.html";
+ var longDescriptionPath = "core/fd/components/af-commons/v1/fieldTemplates/longDescription.html";
+ var questionMarkPath = "core/fd/components/af-commons/v1/fieldTemplates/questionMark.html";
+ var errorMessagePath = "core/fd/components/af-commons/v1/fieldTemplates/errorMessage.html";
+
+ return {
+ labelPath: labelPath,
+ shortDescriptionPath: shortDescriptionPath,
+ longDescriptionPath: longDescriptionPath,
+ questionMarkPath: questionMarkPath,
+ errorMessagePath: errorMessagePath,
+ clientlibs: clientlibsArr
+ };
+});
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/.content.xml
new file mode 100644
index 0000000000..051d207217
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/.content.xml
@@ -0,0 +1,23 @@
+
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/.content.xml
new file mode 100644
index 0000000000..491392d539
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/.content.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/.content.xml
new file mode 100644
index 0000000000..d5258c369b
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/.content.xml
@@ -0,0 +1,24 @@
+
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/_cq_dialog/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/_cq_dialog/.content.xml
new file mode 100644
index 0000000000..2e033bf36e
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/_cq_dialog/.content.xml
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/_cq_template.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/_cq_template.xml
new file mode 100644
index 0000000000..154b3b58d4
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/_cq_template.xml
@@ -0,0 +1,7 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/.content.xml
new file mode 100644
index 0000000000..e97a72c7e1
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/.content.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/editor/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/editor/.content.xml
new file mode 100644
index 0000000000..256728161e
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/editor/.content.xml
@@ -0,0 +1,5 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/editor/js.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/editor/js.txt
new file mode 100644
index 0000000000..13a9ead296
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/editor/js.txt
@@ -0,0 +1,2 @@
+#base=js
+summarystep.js
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/editor/js/summarystep.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/editor/js/summarystep.js
new file mode 100644
index 0000000000..8821ff57aa
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/editor/js/summarystep.js
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright 2024 Adobe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+(function($) {
+ "use strict";
+
+ const Utils = window.CQ.FormsCoreComponents.Utils.v1,
+ EDIT_DIALOG = ".cmp-adaptiveform-summarystep__editdialog";
+
+ Utils.initializeEditDialog(EDIT_DIALOG)();
+})(jQuery);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/.content.xml
new file mode 100644
index 0000000000..581b2945f5
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/.content.xml
@@ -0,0 +1,6 @@
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/css.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/css.txt
new file mode 100644
index 0000000000..c6c2164a46
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/css.txt
@@ -0,0 +1,2 @@
+#base=css
+summarystepview.css
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/css/summarystepview.css b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/css/summarystepview.css
new file mode 100644
index 0000000000..b19f573f1a
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/css/summarystepview.css
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2024 Adobe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+.cmp-adaptiveform-summarystep {
+ display: block;
+ position: relative;
+ box-sizing: border-box;
+ overflow: auto;
+ max-width: 100%;
+}
+
+.cmp-adaptiveform-summarystep__title {
+ display: block;
+}
+
+.cmp-adaptiveform-summarystep__content {
+ overflow: auto;
+ box-sizing: border-box;
+}
+
+.cmp-adaptiveform-summarystep__message {
+}
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/js.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/js.txt
new file mode 100644
index 0000000000..d0a91c6649
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/js.txt
@@ -0,0 +1,2 @@
+#base=js
+summarystepview.js
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/js/summarystepview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/js/summarystepview.js
new file mode 100644
index 0000000000..848768b0dd
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/js/summarystepview.js
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright 2024 Adobe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+(function () {
+ "use strict";
+
+ class SummaryStep extends FormView.FormFieldBase {
+
+ static NS = FormView.Constants.NS;
+ static IS = "adaptiveFormSummaryStep";
+ static bemBlock = 'cmp-adaptiveform-summarystep';
+ static selectors = {
+ self: `[data-${this.NS}-is="${this.IS}"]`,
+ message: `.${this.bemBlock}__message`,
+ };
+
+ constructor(params) {
+ super(params);
+ }
+
+ getClass() { return SummaryStep.IS; }
+
+ getWidget() { return null; }
+ getLabel() { return null; }
+ getErrorDiv() { return null; }
+ getTooltipDiv() { return null; }
+ getQuestionMarkDiv() { return null; }
+
+ setModel(model) {
+ super.setModel(model);
+ // Sanitize any anchor links in the displayed message to same-origin only.
+ // This mirrors foundation summary.js behaviour (SummaryDataUpdated handler).
+ this.#sanitizeMessageLinks();
+
+ // If autoSubmit is configured, trigger form submission immediately.
+ if (model.properties["fd:autoSubmit"] === true) {
+ this.#autoSubmitForm();
+ }
+ }
+
+ // Restrict all anchor hrefs in the message div to same-origin URLs.
+ #sanitizeMessageLinks() {
+ const messageEl = this.element.querySelector(SummaryStep.selectors.message);
+ if (!messageEl) return;
+ const origin = window.location.origin;
+ messageEl.querySelectorAll('a[href]').forEach(anchor => {
+ const href = anchor.getAttribute('href');
+ if (href && !href.startsWith(origin) && !href.startsWith('/') && !href.startsWith('#')) {
+ anchor.removeAttribute('href');
+ }
+ });
+ }
+
+ // Dispatch a submit action through the AF Runtime model.
+ #autoSubmitForm() {
+ try {
+ const formModel = this.formContainer.getModel();
+ if (formModel && typeof formModel.dispatch === 'function') {
+ formModel.dispatch({ type: FormView.Constants.SUBMIT_EVENT || 'submit' });
+ }
+ } catch (e) {
+ // Guard — do not crash the component if dispatch is unavailable
+ }
+ }
+ }
+
+ FormView.Utils.setupField(({ element, formContainer }) => {
+ return new SummaryStep({ element, formContainer });
+ }, SummaryStep.selectors.self);
+
+})();
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/summarystep.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/summarystep.html
new file mode 100644
index 0000000000..14185552c3
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/summarystep.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
${summarystep.label.value @ context='text'}
+
+
+
${summarystep.displayMsg @ context='html'}
+
+
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/summarystep.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/summarystep.js
new file mode 100644
index 0000000000..fda21489fa
--- /dev/null
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/summarystep.js
@@ -0,0 +1,34 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2024 Adobe
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+use(function () {
+
+ var clientlibsArr = ['core.forms.components.base.v1.editor'];
+ var labelPath = 'core/fd/components/af-commons/v1/fieldTemplates/label.html';
+ var shortDescriptionPath = "core/fd/components/af-commons/v1/fieldTemplates/shortDescription.html";
+ var longDescriptionPath = "core/fd/components/af-commons/v1/fieldTemplates/longDescription.html";
+ var questionMarkPath = "core/fd/components/af-commons/v1/fieldTemplates/questionMark.html";
+ var errorMessagePath = "core/fd/components/af-commons/v1/fieldTemplates/errorMessage.html";
+
+ return {
+ labelPath: labelPath,
+ shortDescriptionPath: shortDescriptionPath,
+ longDescriptionPath: longDescriptionPath,
+ questionMarkPath: questionMarkPath,
+ errorMessagePath: errorMessagePath,
+ clientlibs: clientlibsArr
+ };
+});
diff --git a/ui.tests/test-module/specs/signaturestep/signaturestep.runtime.spec.js b/ui.tests/test-module/specs/signaturestep/signaturestep.runtime.spec.js
new file mode 100644
index 0000000000..3d7f2051b9
--- /dev/null
+++ b/ui.tests/test-module/specs/signaturestep/signaturestep.runtime.spec.js
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright 2024 Adobe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+describe("Form with Signature Step component", () => {
+
+ const pagePath = "content/forms/af/core-components-it/samples/signaturestep/basic.html";
+ const bemBlock = 'cmp-adaptiveform-signaturestep';
+ const IS = "adaptiveFormSignatureStep";
+ let formContainer = null;
+
+ beforeEach(() => {
+ cy.previewForm(pagePath).then(p => {
+ formContainer = p;
+ });
+ });
+
+ const tabSelector = 'ol li';
+ const tab1 = () => cy.get(tabSelector).eq(0);
+ const tab2 = () => cy.get(tabSelector).eq(1);
+
+ it("should initialize form container", () => {
+ expect(formContainer, "formcontainer is initialized").to.not.be.null;
+ });
+
+ it("should render the signature step in the second tab", () => {
+ tab2().click();
+ tab2().should('have.class', 'cmp-tabs__tab--active');
+ cy.get(`[data-cmp-is="${IS}"]`).should('exist').and('be.visible');
+ });
+
+ it("should have correct BEM block and data attributes on the signature step", () => {
+ tab2().click();
+ cy.get(`[data-cmp-is="${IS}"]`)
+ .should('have.attr', 'data-cmp-is', IS)
+ .and('have.attr', 'data-cmp-visible', 'true');
+ cy.get(`.${bemBlock}`).should('exist');
+ });
+
+ it("should show the template loading message while signing is not initialized", () => {
+ tab2().click();
+ // The template message is visible before a signing URL is loaded.
+ // In test environments without a real Adobe Sign cloud config, the
+ // fetch will fail and the template message remains visible (or the
+ // error div is shown instead).
+ cy.get(`.${bemBlock}__template-message, .${bemBlock}__error`).should('exist');
+ });
+
+ it("should have the iframe hidden until a signing URL is obtained", () => {
+ tab2().click();
+ cy.get(`.${bemBlock}__iframe`).should('not.have.attr', 'src')
+ .or('have.css', 'display', 'none');
+ });
+
+ it("should not show the signature step on the first tab", () => {
+ tab1().click();
+ cy.get(`[data-cmp-is="${IS}"]`).should('not.be.visible');
+ });
+});
diff --git a/ui.tests/test-module/specs/summarystep/summarystep.runtime.spec.js b/ui.tests/test-module/specs/summarystep/summarystep.runtime.spec.js
new file mode 100644
index 0000000000..76c2c69699
--- /dev/null
+++ b/ui.tests/test-module/specs/summarystep/summarystep.runtime.spec.js
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2024 Adobe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+describe("Form with Summary Step component", () => {
+
+ const pagePath = "content/forms/af/core-components-it/samples/summarystep/basic.html";
+ const bemBlock = 'cmp-adaptiveform-summarystep';
+ const IS = "adaptiveFormSummaryStep";
+ let formContainer = null;
+
+ beforeEach(() => {
+ cy.previewForm(pagePath).then(p => {
+ formContainer = p;
+ });
+ });
+
+ const tabSelector = 'ol li';
+ const tab1 = () => cy.get(tabSelector).eq(0);
+ const tab2 = () => cy.get(tabSelector).eq(1);
+
+ it("should initialize form container", () => {
+ expect(formContainer, "formcontainer is initialized").to.not.be.null;
+ });
+
+ it("should render the summary step in the second tab", () => {
+ tab2().click();
+ tab2().should('have.class', 'cmp-tabs__tab--active');
+ cy.get(`[data-cmp-is="${IS}"]`).should('exist').and('be.visible');
+ });
+
+ it("should have correct BEM block and data attributes on the summary step", () => {
+ tab2().click();
+ cy.get(`[data-cmp-is="${IS}"]`)
+ .should('have.attr', 'data-cmp-is', IS)
+ .and('have.attr', 'data-cmp-visible', 'true');
+ cy.get(`.${bemBlock}`).should('exist');
+ cy.get(`.${bemBlock}__content`).should('exist');
+ });
+
+ it("should display the configured displayMsg in the message area", () => {
+ tab2().click();
+ cy.get(`.${bemBlock}__message`)
+ .should('exist')
+ .and('not.be.empty');
+ cy.get(`.${bemBlock}__message`).invoke('text').then(text => {
+ expect(text.trim()).to.include('Thank you');
+ });
+ });
+
+ it("should not show the summary step on the first tab", () => {
+ tab1().click();
+ cy.get(`[data-cmp-is="${IS}"]`).should('not.be.visible');
+ });
+});