Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
34f4522
Update README.md
rismehta Jan 31, 2025
89a3c10
Update VERSIONS.md
rismehta Jan 31, 2025
5f9dd91
Fixing cross origin issues (#1518)
rismehta Feb 3, 2025
5c87630
Merge pull request #1519 from adobe/dev-to-master-3-Feb-2025
rismehta Feb 3, 2025
72ff6a8
@releng [maven-scm] :prepare release core-forms-components-reactor-3.…
barshat7 Feb 3, 2025
8cb5013
@releng [maven-scm] :prepare for next development iteration
barshat7 Feb 3, 2025
07135c6
Disabling old core component build since core component is part of cl…
rismehta Feb 3, 2025
242931b
Merge pull request #1521 from adobe/dev-to-master-3Feb-2025-2
rismehta Feb 3, 2025
e1dd78b
@releng [maven-scm] :prepare release core-forms-components-reactor-3.…
barshat7 Feb 3, 2025
293fe57
@releng [maven-scm] :prepare for next development iteration
barshat7 Feb 3, 2025
1834548
Update README.md
rismehta Feb 4, 2025
cac07df
Update VERSIONS.md
rismehta Feb 4, 2025
115d14f
Update README.md
rismehta Feb 5, 2025
e8c2461
Fixing chrome driver (#1523)
rismehta Feb 5, 2025
80e41c7
Issue with long description text and introduce data-name attribute in…
pavi41 Feb 5, 2025
77709de
Merge branch 'master' into DevToMaster6Feb2025
Feb 6, 2025
5b083e6
Merge pull request #1524 from adobe/DevToMaster6Feb2025
rismehta Feb 6, 2025
6907ddf
@releng [maven-scm] :prepare release core-forms-components-reactor-3.…
Feb 6, 2025
51f1dff
@releng [maven-scm] :prepare for next development iteration
Feb 6, 2025
7ebdc56
Update VERSIONS.md and README.md to include version 3.0.92
Feb 6, 2025
2f76964
Update README.md
rismehta Feb 6, 2025
2b52028
Update VERSIONS.md
rismehta Feb 6, 2025
cd7b71d
Fixing readme.md script (#1525)
rismehta Feb 10, 2025
be68afd
@releng updating af-custom-function to 1.0.14 (#1529)
rismehta Feb 19, 2025
f5bdc05
Fixing sling output mappings in aemform embed component (#1530)
rismehta Feb 24, 2025
b20dcba
fix: Tabs list in desktop (#1526)
rajatofficial Feb 24, 2025
2cf1b6a
Merge branch 'dev' into devMaster24Feb
rismehta Feb 24, 2025
08e5f4a
Merge pull request #1531 from adobe/devMaster24Feb
rismehta Feb 24, 2025
a8c269d
@releng [maven-scm] :prepare release core-forms-components-reactor-3.…
rismehta Feb 24, 2025
733f19b
@releng [maven-scm] :prepare for next development iteration
rismehta Feb 24, 2025
129ea28
Update VERSIONS.md and README.md to include version 3.0.94
Feb 24, 2025
67815a2
Update README.md
rismehta Feb 24, 2025
0e467d3
FORMS-16007 : rest endpoint url validation, to not allow relative url…
s1mahanty Feb 27, 2025
9b1eb2a
FORMS-18986 XFA to AF (#1532)
rismehta Feb 28, 2025
f6ea65d
Merge branch 'dev' into devToMaster28Feb
rismehta Feb 28, 2025
ac5f275
Merge pull request #1533 from adobe/devToMaster28Feb
rismehta Feb 28, 2025
ab44357
@releng [maven-scm] :prepare release core-forms-components-reactor-3.…
rismehta Feb 28, 2025
a670a67
@releng [maven-scm] :prepare for next development iteration
rismehta Feb 28, 2025
eea08eb
Update VERSIONS.md and README.md to include version 3.0.96
Feb 28, 2025
d72110a
Update VERSIONS.md
rismehta Mar 1, 2025
8ca1bb0
Update README.md
rismehta Mar 1, 2025
d95f8cf
Updating read me
rismehta Mar 3, 2025
86a85db
Merge branch 'master' into master6504March
rismehta Mar 4, 2025
fe5c315
Revert "FORMS-18986 XFA to AF (#1532)"
rismehta Mar 4, 2025
c8321e4
Test case correction
Mar 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -463,4 +463,4 @@ workflows:
branches:
ignore: /.*/
tags:
only: /^core-forms-components-reactor-\d+\.\d+\.\d+$/
only: /^core-forms-components-reactor-\d+\.\d+\.\d+$/
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ See [AEM Sites Core Components](https://docs.adobe.com/content/help/en/experienc
- [Text Input](ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/textinput/v1/textinput)
- [Number Input](ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/numberinput/v1/numberinput)
- [Date Picker](ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker)
- [File Attachment](ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v1/fileinput)
- [File Attachment](ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v3/fileinput)
- [Dropdown List](ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/dropdown/v1/dropdown)
- [Checkbox Group](ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkboxgroup/v1/checkboxgroup)
- [Radio Button Group](ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/radiobutton/v1/radiobutton)
Expand All @@ -53,6 +53,12 @@ See [AEM Sites Core Components](https://docs.adobe.com/content/help/en/experienc
- [Turnstile](ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/turnstile/v1/turnstile)


### XFA-based Form

- [XFA Page](ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/xfa-page/v1/xfa-page)

To create XFA-based core component forms, you need to use the XFA Page component. This component serves as the foundation for rendering XFA forms.

## System Requirements

The latest version of the AEM Forms Core Components, require the below minimum system requirements:
Expand Down
1 change: 0 additions & 1 deletion VERSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,3 @@ See below for a full list of minimum system requirements for historical versions
| 1.1.16 | 2.21.2 | 6.5.17+ | 8, 11 | 3.3.9+ |
| 1.1.12 | 2.21.2 | 6.5.16+ | 8, 11 | 3.3.9+ |


Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,12 @@ public boolean isFormSelected() {

@Override
public String getThankyouPage() {
if (request != null && StringUtils.isNotBlank(thankyouPage)) {
ResourceResolver resourceResolver = request.getResourceResolver();
if (resourceResolver != null) {
thankyouPage = StringUtils.replace(resourceResolver.map(thankyouPage), "_jcr_content", "jcr:content");
}
}
return GuideUtils.getRedirectUrl(thankyouPage, null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ class AEMFormImplTest {
private static final String GRID_LANG = ROOT_PAGE_LANG + "/jcr:content/root/responsivegrid";
private static final String FORM_1 = "/aemform-1";
private static final String FORM_2 = "/aemform-2";
private static final String FORM_WITH_SLINGMAPPINGS = "/aemformv2_slingmappings";
private static final String PATH_FORM_1 = GRID + FORM_1;
private static final String PATH_FORM_2 = GRID + FORM_2;
private static final String PATH_FORM_SLINGMAPPINGS = GRID + FORM_WITH_SLINGMAPPINGS;
private static final String PATH_FORM_LANG = GRID_LANG + FORM_1;

private final AemContext context = FormsCoreComponentTestContext.newAemContext();
Expand Down Expand Up @@ -294,6 +296,16 @@ void testJSONExport() throws Exception {
Utils.testJSONExport(aemform, Utils.getTestExporterJSONPath(BASE, PATH_FORM_1));
}

@Test
void testGetThankYouPageWithResourceResolver() {
// Get form under test using test resource that has _jcr_content in thankyou page path
AEMForm aemForm = getAEMFormUnderTest(PATH_FORM_SLINGMAPPINGS);

// Test the method - verify _jcr_content replacement
String result = aemForm.getThankyouPage();
assertEquals("/content/jcr:content/thank/page.html", result);
}

private AEMForm getAEMFormUnderTest(String resourcePath) {
context.currentResource(resourcePath);
MockSlingHttpServletRequest request = context.request();
Expand Down
6 changes: 6 additions & 0 deletions bundles/core/src/test/resources/aemform/test-content.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@
"useiframe" : "true",
"usePageLocale" : "true",
"enableFocusOnFirstField" : true
},
"aemformv2_slingmappings" : {
"jcr:primaryType": "nt:unstructured",
"jcr:title": "",
"sling:resourceType": "core/fd/components/aemform/v1/aemform",
"thankyouPage": "/content/_jcr_content/thank/page"
}
}
}
Expand Down
1 change: 0 additions & 1 deletion it/apps/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
<parent>
<groupId>com.adobe.aem</groupId>
<artifactId>core-forms-components-parent</artifactId>

<version>1.1.67-SNAPSHOT</version>
<relativePath>../../parent/pom.xml</relativePath>
</parent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,15 +378,18 @@
if(restEndPointSource.length == 0 || isPostUrlSelected){
Utils.showComponent(restEndPointUrlTextBox, 'div');
Utils.hideComponent(restEndpointConfigPath, 'div');
restEndPointUrlTextBox?.setAttribute("data-rest-endpoint-url-validation", "");
} else {
Utils.showComponent(restEndpointConfigPath, 'div');
Utils.hideComponent(restEndPointUrlTextBox, 'div');
restEndPointUrlTextBox?.removeAttribute("data-rest-endpoint-url-validation");
}
} else {
Utils.hideComponent(restEndPointSource, 'div');
Utils.hideComponent(restEndPointUrlTextBox, 'div');
Utils.hideComponent(restEndpointConfigPath, 'div');
restEndPointSource.parent('div').parent('div').hide();
restEndPointUrlTextBox?.removeAttribute("data-rest-endpoint-url-validation");
}
}

Expand Down Expand Up @@ -421,6 +424,7 @@
$(document).off('change' + REST_ENDPOINT).on('change' + REST_ENDPOINT, restCheckBox, function(){
showPostUrlTextField(dialog);
});
registerRestEndpointUrlValidator();
}
}

Expand Down Expand Up @@ -489,6 +493,22 @@
}
});

function registerRestEndpointUrlValidator() {
$(window).adaptTo("foundation-registry").register("foundation.validation.validator", {
selector: "[data-rest-endpoint-url-validation]",
validate: (el) => {
const url = el.value;
// Regex to validate absolute URLs starting with http:// or https:// only
const absoluteUrlPattern = /^https?:\/\/.+$/i;
if (!absoluteUrlPattern.test(url)) {
return Granite.I18n.getMessage(
"Please enter the absolute path of the REST endpoint."
);
}
}
});
}

Utils.initializeEditDialog(EDIT_DIALOG_FORM)(handleAsyncSubmissionAndThankYouOption, handleSubmitAction,
registerSubmitActionSubDialogClientLibs, registerRestEndPointDialogClientlibs, registerFDMDialogClientlibs, registerEmailDialogClientlibs, initialiseDataModel, registerAutoSaveDialogAction);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,5 @@ Applying `data-cmp-custom-functions-module-url` attribute to the div to point to
This Url should whitelist the AEM author/publish domain in the Cross Origin Resource Sharing (CORS) configuration.

Applying `data-cmp-auto-save` attribute to the `cmp-adaptiveform-container` block to control the auto-save functionality. If the attribute's value is set to true, auto-save will be enabled for the form; otherwise, it will not be triggered. This attribute will be set to true in published mode if enableAutoSave is enabled.

Applying `data-cmp-hamburger-menu-enabled` attribute to the `cmp-adaptiveform-container` block to control the hamburger meu. If the attribute's value is set to true, hamburger menu will be enabled in the mobile view.
Original file line number Diff line number Diff line change
Expand Up @@ -334,27 +334,6 @@ if (typeof window.HamburgerMenu === 'undefined') {
return ul;
}

#hideIndividualComponentsNavigation() {
// hide all the horizontal tabs list
const tabsLists = document.getElementsByClassName('cmp-tabs__tablist');
Array.from(tabsLists).forEach(tabsList => {
tabsList.style.display = 'none';
});

// hide all the vertical tabs list
const verticalTabsLists = document.getElementsByClassName('cmp-verticaltabs__tablist');
Array.from(verticalTabsLists).forEach(tabsList => {
tabsList.style.display = 'none';
});
// hide all the wizard tabs list
const wizardTabsLists = document.getElementsByClassName('cmp-adaptiveform-wizard__tabList');
const wizardTabsNavButton = document.querySelector('.cmp-adaptiveform-wizard__containerNav');
if(wizardTabsNavButton) wizardTabsNavButton.style.display = 'none';
Array.from(wizardTabsLists).forEach(tabsList => {
tabsList.style.display = 'none';
});
}

// Function to find the currently active li
#findActiveLi() {
return document.querySelector(HamburgerMenu.selectors.active).parentElement;
Expand Down Expand Up @@ -492,8 +471,6 @@ if (typeof window.HamburgerMenu === 'undefined') {

this.#attachHamburgerEventListeners(hamburgerIcon, menu);
this.#attachOutsideClickHandler(hamburgerIcon, menu);

this.#hideIndividualComponentsNavigation();
this.#attachMenuEventListeners(menu);
this.#styleSubmenuItems(menu);
parentContainer.innerHTML='';
Expand Down Expand Up @@ -566,6 +543,7 @@ if (typeof window.HamburgerMenu === 'undefined') {

init() {
if(this.formContainer?.getModel()?.properties?.['fd:isHamburgerMenuEnabled']) {
document.querySelector('.cmp-adaptiveform-container')?.setAttribute('data-cmp-hamburger-menu-enabled', 'true');
const panels = this.#getAllPanels();
this.#renderHamburgerItems(panels);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
data-cmp-context-path="${request.contextPath}"
data-cmp-page-lang="${container.containingPageLang}"
data-cmp-path="${resource.path}"
data-cmp-hamburger-menu-enabled="${container.isHamburgerMenuEnabled ? 'true' : 'false'}"
class="cmp-adaptiveform-container cmp-container ${wcmmode.edit ? 'cmp-adaptiveform-container--edit' : ''}"
data-cmp-custom-functions-module-url="${configurationProvider.customFunctionModuleUrl}"
dir="${container.languageDirection}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,9 @@
}

#syncWidgetName() {
const name = this.getModel()?.name;
this.widget.forEach(widget => {
widget.setAttribute("name", this.id + "_name");
widget.setAttribute("name", `${this.id}_${name}`);
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
data-cmp-enabled="${radioButton.enabled ? 'true' : 'false'}"
data-cmp-required="${radioButton.required ? 'true': 'false'}"
data-cmp-readonly="${radioButton.readOnly ? 'true' : 'false'}"
data-name="${radioButton.name}"
id="${radiobutton.id}"
data-cmp-data-layer="${radioButton.data.json}"
data-cmp-adaptiveformcontainer-path="${formstructparser.formContainerPath}"
Expand Down
14 changes: 7 additions & 7 deletions ui.frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ui.frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@
"dependencies": {
"@aemforms/af-core": "^0.22.114",
"@aemforms/af-formatters": "^0.22.114",
"@aemforms/af-custom-functions": "1.0.13"
"@aemforms/af-custom-functions": "1.0.14"
}
}
11 changes: 9 additions & 2 deletions ui.frontend/src/GuideBridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,16 @@ class GuideBridge {
let customEvent = document.createEvent("CustomEvent");
customEvent.initCustomEvent(Constants.GUIDE_BRIDGE_INITIALIZE_START, true, true, {"guideBridge": this});
window.dispatchEvent(customEvent);
// Safely handle cross-origin parent window communication
if (window !== window.parent) {
window.parent.document.getElementById(window.name);
window.parent.dispatchEvent(customEvent);
try {
// Try to access parent window
window.parent.document.getElementById(window.name);
window.parent.dispatchEvent(customEvent);
} catch (e) {
// Silently handle cross-origin security errors
console.debug('Cross-origin access to parent window blocked');
}
}
let self = this;
function onFormContainerInitialised(e) {
Expand Down
9 changes: 5 additions & 4 deletions ui.frontend/src/view/FormFieldBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -636,17 +636,18 @@ class FormFieldBase extends FormField {
}

// Find the existing <p> element
let pElement = descriptionElement.querySelector('p');
let pElements = descriptionElement.querySelectorAll('p');

if (!pElement) {
if (!pElements) {
// If no <p> tag exists, create one and set it as the content
pElement = document.createElement('p');
pElements = document.createElement('p');
descriptionElement.innerHTML = ''; // Clear existing content
descriptionElement.appendChild(pElement);
}

// Update the <p> element's content with sanitized content
pElement.innerHTML = sanitizedDescriptionText;
pElements.length === 1 ? (pElements[0].innerHTML = sanitizedDescriptionText) : null;

} else {
// If no description was set during authoring
this.#addDescriptionInRuntime(sanitizedDescriptionText);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ describe("Form Runtime with Hamburger Menu", () => {
cy.get(selectors.hamburgerMenuWidget.hamburgerMenu).should("be.visible");
})

it(`Test data-cmp-hamburger-menu-enabled attribute when hamburger menu is enabled`, () => {
cy.viewport('iphone-x');
cy.get('form')
.should('have.attr', 'data-cmp-hamburger-menu-enabled', 'true');
})

it(`Test hamburger menu should render exact number of items`, () => {
cy.viewport('iphone-x');
cy.get(selectors.hamburgerMenuTopContainer.hamburgerMenuIcon).click();
Expand Down
20 changes: 18 additions & 2 deletions ui.tests/test-module/specs/formcontainer.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,16 @@ describe('Page/Form Authoring', function () {
cy.get("coral-numberinput[name='./fd:autoSaveInterval']").should("exist");
}


const checkValidatorFunctioning = function(formContainerEditPathSelector) {
cy.openEditableToolbar(sitesSelectors.overlays.overlay.component + formContainerEditPathSelector);
cy.invokeEditableAction("[data-action='CONFIGURE']");
cy.get('.cmp-adaptiveform-container__editdialog').contains('Submission').click({force:true});
cy.get("[name='./restEndpointPostUrl']").scrollIntoView().clear({force: true}).type("invalid-url", {force: true});
cy.get('.coral-Form-errorlabel').should('contain.text', "Please enter the absolute path of the REST endpoint.");
cy.get("[name='./restEndpointPostUrl']").clear({force: true}).type("http://localhost:4502/some/endpoint", {force: true});
cy.get('.coral-Form-errorlabel').should('not.exist');
cy.get('.cq-dialog-submit').click();
};

const checkAndSaveSubmitAction = function(formContainerEditPathSelector) {
// click configure action on adaptive form container component
Expand All @@ -102,8 +111,8 @@ describe('Page/Form Authoring', function () {
// cy.get("[name='./restEndpointConfigPath']").should("exist").should("not.be.visible");
// }
cy.get("[name='./restEndpointPostUrl']").should("exist").type("http://localhost:4502/some/endpoint");

//save the configuration
cy.get("[name='./restEndpointPostUrl']").scrollIntoView().should("exist").clear().type("http://localhost:4502/some/endpoint");
cy.get('.cq-dialog-submit').click();
};

Expand Down Expand Up @@ -240,6 +249,9 @@ describe('Page/Form Authoring', function () {
}
});

it('check validator functioning for REST endpoint URL', function() {
checkValidatorFunctioning(formContainerEditPathSelector);
});
});

// commenting once we support adaptive form container in sites editor, uncomment this test
Expand Down Expand Up @@ -293,6 +305,10 @@ describe('Page/Form Authoring', function () {
checkEditDialog(formContainerEditPathSelector);
cy.get(sitesSelectors.confirmDialog.actions.first).click();
})

it('check validator functioning for REST endpoint URL', function() {
checkValidatorFunctioning(formContainerEditPathSelector);
});
});

context("Render Forms in Disabled mode", function () {
Expand Down
6 changes: 3 additions & 3 deletions ui.tests/test-module/specs/prefill/customprefill.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ const sitesSelectors = require('../../libs/commons/sitesSelectors'),
describe('Custom Prefill Test', function () {
const pagePath = "content/forms/af/core-components-it/samples/prefill/basic.html";
const nameTextBox = "input[name='name']",
dobDropdown = "input[name='dob']",
genderRadioButton = "input[name='radiobutton-c8c660bac8_name']",
jobDropdown = "select[name='job']";
dobDropdown = "input[name='dob']",
jobDropdown = "select[name='job']";
let genderRadioButton = "input[name='radiobutton-c8c660bac8_gender']";
let formContainer = null;

beforeEach(() => {
Expand Down
Loading
Loading