Article summary

Summary

Discusses how to create an AEM 6 adaptive form and post the data to a custom service defined within an OSGi bundle.

A special thank you to Varun Dua, an Experience Manager Computer Scientist for helping with this development article.    

Digital Marketing Solution(s) Adobe Experience Manager (Adobe CQ)
Audience
Developer (intermediate)
Required Skills
JavaScript, Java, OSGi, Maven
Tested On Adobe Experience Manager 6

Note:

You can download an AEM package that contains code and the OSGi bundle that are used in this article. Download the package and deploy using package manager. The purpose of this code is to show the community these concepts in action. That is, it's to illustrate how to post an adaptive form data to an AEM custom service. This community code is for teaching purposes only and not meant to go into production as is.

You can view the application by using the following URL: http://localhost:4502/cf#/content/forms/af/Customer.html (assuming you deploy on author). 

Download

Introduction

You can create an Adobe Experience Manager (AEM) 6 form and submit the data to a custom AEM service. The custom service can process the data to meet your business requirements. For example, you can store the data in a database or send the data within an email message. However, to keep this article simple, the custom AEM service writes the posted data to the AEM log file.

An AEM 6 form can be consumed in a mobile device or a web browser running on a desktop. For example, consider a mobile user filling out the following AEM 6 form on an IPad device.
 

Form

When an end user fills out the AEM form and clicks the Submit button, the data is submitted to an AEM 6 service defined in an OSGi bundle, as shown in the following illustation.

HandleMobile2

This development article walks you through how to create an AEM 6 form and submit the data to an AEM service. The OSGi bundle is created by using an Adobe Maven Archetype project. 

Author an AEM adaptive customer form 

The first step is to author an adaptive AEM 6 form that contains the following four text fields:

  • First name - specifies the first name
  • Last name - specifies the last name
  • City - specifies the city
  • Address - specifies the address

To create an AEM form, you use the AEM interface, drag-and-drop functionality, standard form text components. When you create a new or edit an existing adaptive form, you use the following UI elements:

  • Content finder
  • Adaptive form page
  • Sidekick
Untitled

 

To create an adaptive form with the four fields specified in this section, perform these steps:

  1. Access AEM forms Author instance at http://[server]:[port]/<custom-context-if-any>.
  2. Enter your credentials on the AEM login page. On the left panel, click the Forms link.
    For a default installation, the login is admin and the password is admin.
  3. Click and select Create adaptive form.
  4. The available templates are displayed. Click a template to select it and click Next.
  5. Enter a name, title, and description for the form, and click Create. Name the form Customer.
  6. Click Open or Done to open the newly created form in a new tab. The form displays the contents available in the template and also displays the Sidekick to customize the newly created form according to the needs. Drag four text fields onto your form named First, Last, City and Address.
  7. After an adaptive form is created, it is listed in the folder alongside other forms and assets. Hover the pointer on the form thumbnail, and click to open the form in editing mode.

Note:

For more information about AEM 6 adaptive forms, see Introduction to authoring adaptive forms.

Create a custom submit action for the customer form

The second step is to create a custom submit action for the customer form. To create a custom submit action, you setup nodes and properties within the AEM repository. In addition, you define a JSP file named post.POST.jsp. When the user fills out the form and clicks the submit button, form data is posted to the post..POST.jsp. This JSP captures the submitted data and passes the data to a custom service defined within an OSGi bundle.

1. Log in to CRXDE Lite at http://{server}:{port}/crx/de/index.jsp. Create a node with the property sling:Folder with the name invoke_service in the /apps/custom_submit_action folder. Create the custom_submit_action folder if it does not exist.

app

2. Make the Action available in Adaptive Form Edit Dialog. Add the following properties in the invoke_service node:

  • guideComponentType of type String and value fd/af/components/guidesubmittype
  • guideDataModel of type String and value xfa,xsd,basic
  • jcr:description of type String and value Invoke Service (this is the value that shows up in the GUI)

 

3. Open the Customer Adaptive Form and open the Edit Dialog of Adaptive Form Container by clicking on the Edit button next to Start of Adaptive Form. The new action will be visible in the Submit actions Tab. Select Invoke Service.

Dialog2

4. Add post.POST.jsp file in your action by adding this JSP file to /apps/custom_submit_action/invoke_service/. When data is submitted from the Customer adaptive form, it is posted to this JSP file. Add the following code to this JSP file.

<%@include file="/libs/fd/af/components/guidesglobal.jsp" %>
<%@include file="/libs/foundation/global.jsp"%>
<%@page import="com.day.cq.wcm.foundation.forms.FormsHelper,
     		org.apache.sling.api.resource.ResourceUtil,
     		org.apache.sling.api.resource.ValueMap" %>
<%@taglib prefix="sling" 
                uri="http://sling.apache.org/taglibs/sling/1.0" %>
<%@taglib prefix="cq" 
                uri="http://www.day.com/taglibs/cq/1.0" 
%>
<cq:defineObjects/>
<sling:defineObjects/>
<%

	String First = request.getParameter("First");
	String Last = request.getParameter("Last");
	String City = request.getParameter("City");
	String Address = request.getParameter("Address");

	com.adobe.cq.HandleForm hf = sling.getService(com.adobe.cq.HandleForm.class);
	hf.injestFormData(First,Last,City, Address);


%>

This code captures the posted form fields that are submitted from the Customer adaptive form. It then creates an instance of com.adobe.cq.HandleForm object. Finally it invokes the HandleForm object's injestFormData method and passes the following values. This custom service is created in the remaining steps of this article.  

Note:

Ensure that the JSP file is named post.POST.jsp. If you do not use the lower and upper case, then the form will not successfully post data to this file.

Setup Maven in your development environment

You can use Maven to build an OSGi bundle that uses the JCR API and is deployed to Experience Manager. Maven manages required JAR files that a Java project needs in its class path. Instead of searching the Internet trying to find and download third-party JAR files to include in your project’s class path, Maven manages these dependencies for you.

You can download Maven 3 from the following URL:

http://maven.apache.org/download.html

After you download and extract Maven, create an environment variable named M3_HOME. Assign the Maven install location to this environment variable. For example:

C:\Programs\Apache\apache-maven-3.0.4

Set up a system environment variable to reference Maven. To test whether you properly setup Maven, enter the following Maven command into a command prompt:

%M3_HOME%\bin\mvn -version

This command provides Maven and Java install details and resembles the following message:

Java home: C:\Programs\Java64-6\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"

 

Note:

For more information about setting up Maven and the Home variable, see: Maven in 5 Minutes.

Next, copy the Maven configuration file named settings.xml from [install location]\apache-maven-3.0.4\conf\ to your user profile. For example, C:\Users\scottm\.m2\.

You have to configure your settings.xml file to use Adobe’s public repository. For information, see Adobe Public Maven Repository at http://repo.adobe.com/.

Create an Experience Manager archetype project 

You can create an Experience Manager archetype project by using the Maven archetype plugin. In this example, assume that the working directory is C:\AdobeCQ.  

plugin1

 

To create an Experience Manager archetype project, perform these steps::

1. Open the command prompt and go to your working directory (for example, C:\AdobeCQ).

2. Run the following Maven command:

mvn archetype:generate -DarchetypeRepository=https://repo.adobe.com/nexus/content/groups/public/ -DarchetypeGroupId=com.day.jcr.vault -DarchetypeArtifactId=multimodule-content-package-archetype -DarchetypeVersion=1.0.2 -DgroupId=com.adobe.cq -DartifactId=form -Dversion=1.0-SNAPSHOT -Dpackage=com.adobe.cq -DappsFolderName=myproject -DartifactName="My Project" -DcqVersion="5.6.1" -DpackageGroup="My Company"

3. When prompted for additional information, specify Y.

4. Once done, you will see a message like:
[[INFO] Total time: 14:46.131s
[INFO] Finished at: Wed Mar 27 13:38:58 EDT 2013
[INFO] Final Memory: 10M/184M

5. Change the command prompt to the generated project. For example: C:\AdobeCQ\form. Run the following Maven command:
mvn eclipse:eclipse

After you run this command, you can import the project into Eclipse as discussed in the next section.

Add Java files to the Maven project using Eclipse 

To make it easier to work with the Maven generated project, import it into the Eclipse development environment, as shown in the following illustration. 

project

Note:

Do not worry about the errors reported in Eclipse. It does not read the POM file where the APIs are resolved. You build the bundle with Maven. Eclipse is used to edit the Java files and the POM file. Delete the FormCustomer-content project from the Eclipse IDE. Work in the FormCustomer-bundle project and make sure that you work in the com.adobe.cq package.

The next step is to add the following Java files to the com.adobe.cq package:

  • A Java interface named HandleForm.
  • A Java class named HandleFormImp that implements the HandleForm interface.

HandleForm interface

The following code represents the HandleForm. This interface contains a method signature named injestFormData. The implementation logic for this method is located in the HandleFormImp class.  

package com.adobe.cq;

public interface HandleForm {
	
	public void injestFormData(String First, String Last, String City, String Address); 

}

HandleFormImpl class

The HandleFormImp class uses the following Apache Felix SCR annotations to create the OSGi component:

  • @Component – defines the class as a component
  • @Service - defines the service interface that is provided by the component

In this use case, the values that are submitted from the Customer adaptive form are written to the AEM log file. The following Java code represents the HandleFormImpl class.

package com.adobe.cq;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
    
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;

//This is a component so it can provide or consume services
@Component
   
@Service
public class HandleFormImpl implements HandleForm {
	
	/** Default log. */
	protected final Logger log = LoggerFactory.getLogger(this.getClass());

	@Override
	public void injestFormData(String First, String Last, String City,
			String Address) {
		
		//Simply write out the values that are posted from the AEM form to the AEM log file
		log.info("Data posted from an AEM adaptive form - First: "+First +" Last: "+Last +" City: "+City +" Address "+Address) ;
	}

}

Note:

Once you have the submitted form values in the OSGi service, you can perform additional business logic to meet your business requirements. For example, you can use a DataSourcePool to store the data into a relational database. For information, see Injecting a DataSourcePool Service into an Adobe Experience Manager OSGi bundle.

Modify the Maven POM file 

Modify the POM files to successfully build the OSGi bundle. In the POM file located at C:\AdobeCQ\FormCustomer\bundle, add the following dependencies.

  • org.apache.felix.scr
  • org.apache.felix.scr.annotations
  • org.apache.sling

The following XML represents this POM file.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
    <modelVersion>4.0.0</modelVersion>
    <!-- ====================================================================== -->
    <!-- P A R E N T P R O J E C T D E S C R I P T I O N -->
    <!-- ====================================================================== -->
    <parent>
        <groupId>com.adobe.cq</groupId>
        <artifactId>form</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <!-- ====================================================================== -->
    <!-- P R O J E C T D E S C R I P T I O N -->
    <!-- ====================================================================== -->

    <artifactId>form-bundle</artifactId>
    <packaging>bundle</packaging>
    <name>My Project Bundle</name>

      <dependencies>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.compendium</artifactId>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.apache.felix.scr.annotations</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>

    <!-- ====================================================================== -->
    <!-- B U I L D D E F I N I T I O N -->
    <!-- ====================================================================== -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-scr-plugin</artifactId>
                <executions>
                    <execution>
                        <id>generate-scr-descriptor</id>
                        <goals>
                            <goal>scr</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>com.adobe.cq.form-bundle</Bundle-SymbolicName>
                    </instructions>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.sling</groupId>
                <artifactId>maven-sling-plugin</artifactId>
                <configuration>
                    <slingUrl>http://${crx.host}:${crx.port}/apps/myproject/install</slingUrl>
                    <usePut>true</usePut>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                 <configuration>
                    <excludePackageNames>
                        *.impl
                    </excludePackageNames>
                 </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Build the OSGi bundle using Maven

To build the OSGi component by using Maven, perform these steps:

  1. Open the command prompt and go to the C:\AdobeCQ\form folder.
  2. Run the following maven command: mvn clean install.
  3. The OSGi component can be found in the following folder: C:\AdobeCQ\form\bundle\target. The file name of the OSGi component is form-bundle-1.jar.

Deploy the bundle to Experience Manager

Once you deploy the OSGi bundle, you are able post data from the Customer adaptive form to the OSGi service. After you deploy the OSGi bundle, you will be able to see it in the Apache Felix Web Console.  

OSGi

Deploy the new OSGi bundle by performing these steps:

  1. Login to Apache Felix Web Console at http://server:port/system/console/bundles (default admin user = admin with password= admin).
  2. Click the Bundles tab, sort the bundle list by Id, and note the Id of the last bundle.
  3. Click the Install/Update button.
  4. Browse to the bundle JAR file you just built using Maven. (C:\AdobeCQ\form\bundle\target).
  5. Click Install.
  6. Click the Refresh Packages button.
  7. Check the bundle with the highest Id.
  8. Click Active.
  9. Your new bundle should now be listed with the status Active.
  10. If the status is not Active, check the CQ error.log for exceptions. 

Submit the form data

The final step is to preview the Customer adaptive form. Open the Customer form in the AEM Form view:

http://localhost:4502/aem/forms.html/content/dam/formsanddocuments

Click the Preview icon located at the bottom of the AEM sidekick. Fill out the Customer Fields and click the Submit button.

FilledForm


Once you click the Submit button, the data is posted to the post.POST.jsp file. By default, you will see a submit confirmation page. The post.POST.jsp invokes the HandleForm service by invoking its injestFormData method. This service logs the posted values to the AEM log file. You will see the following log message in the AEM log file with the data posted from the adaptive form.

10.06.2014 12:50:44.734 *INFO* [0:0:0:0:0:0:0:1 [1402419044731] POST /content/forms/af/Customer/jcr:content/guideContainer.af.submit.jsp HTTP/1.1] com.adobe.cq.HandleFormImpl Data posted from an AEM adaptive form - First: TOM Last: `Blue City: New York Address No Where Dr

See Also

Congratulations, you have just created an AEM adaptive form that can post data to an OSGi service. Please refer to the AEM community page for other articles that discuss how to build AEM services/applications.

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License  Twitter™ and Facebook posts are not covered under the terms of Creative Commons.

Legal Notices   |   Online Privacy Policy