Article summary

Summary

Discusses how to create an AEM 6.3 adaptive form and post the data to a custom service defined within an OSGi bundle. The custom service uses the Java Mail API to send an email message that contains the submitted form data.

This article uses DS Annotations to create the custom workflow step as opposed to Felix SRC annotations. 

A special thank you to Ratna Kumar Kotla, a member of the AEM community, for testing this article and ensuring it works. 

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

Note:

This article uses the Java mail API to send email, including specifying the SMTP server and user. This replaces the user of configuring AEM to use email. For information about how to configure AEM to use email, see Configuring the Mail Service.

Introduction

You can create an Adobe Experience Manager (AEM) 6.3 form and submit the data to a custom AEM service. The custom service uses the Java MAIL API to send an email message that contains the submitted form values. Although an Adaptive Form does contain an email submission action, by creating a custom service, you can fully control the submitted data by using Java logic prior to emailing the form data. For example, you can look up a value in a database and perform business logic on the data prior to sending the data in an email message.

The following form represents the form that is created in this article. 

AdaptiveForm63
An AEM 6.3 form

When an end user fills out the AEM form and clicks the Submit button, the data is submitted to a custom service defined within an OSGi bundle. The service uses Java Mail API to send an email message. For information, see Package javax.mail

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

Author an AEM adaptive customer form

To create an adaptive form, perform these steps:

1. Log in to the AEM author instance and navigate to Adobe Experience Manager > Forms > Forms & Documents. The default URL is http://localhost:4502/aem/forms.html/content/dam/formsanddocuments.

2. Click Create and select Adaptive Form. An option to select a template appears. Click the Blank template to select it and click Next.

3. An option to Add Properties appears. The Title and Name fields are mandatory:

  • Title: Specify Add new or update shipping address in the Title field. The title field specifies the display name of the form. The title helps you identify the form in the AEM Forms user interface.
  • Name: Specify shipping-address-add-update-form in the Name field. The Name field specifies the name of the form. A node with the specified name is created in the repository. As you start typing a title, value for the name field is automatically generated. You can change the suggested value. The name field can include only alphanumeric characters, hyphens, and underscores. All the invalid inputs are replaced with a hyphen.

4. Click Create. An adaptive form is created and a dialog to open the form for editing appears. Click  Open to open the newly created form in a new tab. The form opens for editing. It also displays the sidebar to customize the newly created form according to the needs.

 

FormA
A new adaptive form

Add header and footer

AEM Forms provides many components to display information on an adaptive form. Header and Footer components help provide a consistent look and feel to a form. A header typically includes the logo of a corporation, the title of the form, and summary. A footer typically includes copyright information and links to other pages. 


Perform these steps:

1. Click the Side Panel Toggle button and then the component button. The component browser opens. Drag the Header component from component browser to the adaptive form.

2. Click Image. The toolbar appears. Click  . The properties browser opens on the left of the screen. Browse and upload the logo image. Click . The image appears on the header.

3. Drag the Footer component from  to the adaptive form. At this stage, the form looks like the following:  

FormB
An adaptive form with a header and footer

Add components to the adaptive form

Components are building blocks of an adaptive form. AEM Forms provides many components to capture and display information in an adaptive form. You can drag the components from  to a form. Perform these steps: 

1. Drag the Numeric Box component to the adaptive form. Place it before the footer component. Open properties of the component, change Title of the component to Customer ID, change Element Name to customer_ID, enable the Required Field option, enable the Use HTML5 Number Input Type option, and click .

2. Drag three Text Box components to the adaptive form. Place these before the footer component. Set the following properties for these text boxes.

Property Text Box 1 Text Box 2 Text Box 3
Title Name Shipping Address State
Element Name customer_Name customer_Shipping_Address customer_State
Required Field Enabled Enabled Enabled
Allow multiple lines Disabled Enabled Disabled

3. Drag a Numeric Box component before the footer component. Open properties of the component, set values listed in the below table, click .

Property Value
Title ZIP Code
Element Name customer_ZIPCode
Maximum Number of Digits 6
Required Field Enabled
Display Pattern Type No Pattern

4. Drag an Email component before the footer component. Open properties of the component, set values listed in the below table, and tap .

Property Value
Title Email
Element Name customer_Email
Required Field Enabled

5. Drag a Submit Button component to the adaptive form. Place it before the footer component. Open properties of the component, change Element Name to address_addition_update_submit. Click . The layout of the form is complete and the form looks like the following:

FormC
An adaptive form

Create an Experience Manager 12 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. 

ProjectA
An Experience Manager Maven Archetype 13 project

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 org.apache.maven.plugins:maven-archetype-plugin:2.4:generate -DarchetypeGroupId=com.adobe.granite.archetypes -DarchetypeArtifactId=aem-project-archetype -DarchetypeVersion=12 -DarchetypeCatalog=https://repo.adobe.com/nexus/content/groups/public/

3. When prompted, specify the following information:

  • groupId - HandleForm
  • artifactId - HandleForm
  • version - 1.0-SNAPSHOT
  • package - com.aem.form
  • appsFolderName - HandleForm
  • artifactName - HandleForm
  • componentGroupName - HandleForm
  • contentFolderName - HandleForm
  • cssId - HandleForm
  • packageGroup - HandleForm
  • siteName -HandleForm

4. When prompted, specify Y.

5. Once done, you will see a message like:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:42 min
[INFO] Finished at: 2016-04-25T14:34:19-04:00
[INFO] Final Memory: 16M/463M
[INFO] ------------------------------------------------------------------------

6. Change the working directory to HandleForm and then enter the following command.

mvn eclipse:eclipse

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

Note:

If you have not setup Maven, see this article Creating an Adobe Experience Manager 6.4 Project using Adobe Maven Archetype 13.

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
Eclipse Import Project Dialog

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.

The next step is to add two Java files to the com.aem.form.core package:

  • HandleForm- a Java interface that exposes the method used in the service
  • HandleFormImp - the implementation class that implements HandleForm

 

HandleForm

The HandleForm interface defines the method exposes by the custom AEM Service that uses Java Mail API to send an email message. The following Java code represents this interface. 

package com.aem.form.core;

public interface HandleForm {
	
	
	public void injestFormData(String customer_ID, String customer_Name, String customer_Shipping_Address, String customer_State, String customer_ZIPCode, String customer_Email); 

}

HandleFormImp

The HandleFormImp class implements HandleForm and defines the implementation logic for the interface. This class uses the Java MAIL API to send an email messaege that contains the submitted form data.  

The following Java code represents this class. 

package com.aem.form.core;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.engine.EngineConstants;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Properties;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

@Component
public class HandleFormImp implements HandleForm{
	
	/** Default log. */
    protected final Logger log = LoggerFactory.getLogger(this.getClass());
 
    @Override
    public void injestFormData(String customer_ID, String customer_Name, String customer_Shipping_Address, String customer_State, String customer_ZIPCode, String customer_Email)
    {
		
    	//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 - customer_ID: "+customer_ID +" customer_Name: "+customer_Name +" customer_Shipping_Address: "+customer_Shipping_Address +" customer_State "+customer_State) ;
    	
        String toaddress = "scottm@adobe.com";
       
        final String username =  "<SMTP user name>";
       
        final String password =    "<SMTP password>";

        String mailserver =  "<MAIL SERVER>";

        String subject = "More Web Form";
        String message2 = "Hi "+customer_Name +"The following address is added as the shipping address for your account: "	+  customer_Name +" We.Retail" ;

        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", mailserver);
        props.put("mail.smtp.port", "587");

        Session session = Session.getInstance(props,
                new javax.mail.Authenticator() {
                    protected javax.mail.PasswordAuthentication getPasswordAuthentication() {
                        return new javax.mail.PasswordAuthentication(username, password);
                    }
                });

        try {

            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("<From Address>));
            message.setRecipients(Message.RecipientType.TO,
                    InternetAddress.parse(toaddress));
            message.setSubject(subject);
            message.setText(message2);


            Transport.send(message);

            log.info("Done");

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

}

Note:

Replace the String Values within <> with SMTP values required to send an mail. Replace these values: mailserver, username, and userpassword

Modify the Maven POM file

Add the following POM dependency to the POM file located at C:\AdobeCQ\HandleForm.

<dependency>
               <groupId>com.adobe.aem</groupId>
               <artifactId>uber-jar</artifactId>
               <version>6.3.0</version>
               <!-- for AEM6.1 use this version     : <version>6.1.0</version> -->
               <!-- for AEM6.1 SP1 use this version : <version>6.1.0-SP1-B0001</version> -->
               <!-- for AEM6.1 SP2 use this version : <version>6.1.0-SP2</version> -->
               <!-- for AEM6.2 use this version     : <version>6.2.0</version> -->
               <classifier>obfuscated-apis</classifier>
               <scope>provided</scope>
           </dependency>
              
           <dependency>
               <groupId>org.apache.geronimo.specs</groupId>
               <artifactId>geronimo-atinject_1.0_spec</artifactId>
               <version>1.0</version>
               <scope>provided</scope>
           </dependency>

When you add new Java classes under core, you need to modify a POM file to successfully build the OSGi bundle. You modify the POM file located at C:\AdobeCQ\HandleForm\core. The following code represents this POM file.

<?xml version="1.0" encoding="UTF-8"?>
<!--
 |  Copyright 2017 Adobe Systems Incorporated
 |
 |  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.
-->
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>HandleForm</groupId>
        <artifactId>HandleForm</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>HandleForm.core</artifactId>
    <packaging>bundle</packaging>
    <name>HandleForm - Core</name>
    <description>Core bundle for HandleForm</description>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.sling</groupId>
                <artifactId>maven-sling-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <!-- Import any version of javax.inject, to allow running on multiple versions of AEM -->
                        <Import-Package>javax.inject;version=0.0.0,*</Import-Package>
                        <Sling-Model-Packages>
                            com.aem.form.core
                        </Sling-Model-Packages>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <!-- OSGi Dependencies -->
           <dependency>
            <groupId>com.adobe.aem</groupId>
            <artifactId>uber-jar</artifactId>
            <classifier>apis</classifier>
        </dependency>
     
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-atinject_1.0_spec</artifactId>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>osgi.core</artifactId>
        </dependency>
        
        <dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4</version>
</dependency>
        
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>osgi.cmpn</artifactId>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>osgi.annotation</artifactId>
        </dependency>
        <!-- Other Dependencies -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.jcr</groupId>
            <artifactId>jcr</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.adobe.aem</groupId>
            <artifactId>uber-jar</artifactId>
            <classifier>apis</classifier>
        </dependency>
        <dependency>
            <groupId>org.apache.sling</groupId>
            <artifactId>org.apache.sling.models.api</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
        </dependency>
        <dependency>
            <groupId>junit-addons</groupId>
            <artifactId>junit-addons</artifactId>
        </dependency>
    </dependencies>
</project>

Build the OSGi bundle using Maven

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

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

The command -PautoInstallPackage automatically deploys the OSGi bundle to AEM.

View the Active OSGi bundle

After you deploy the OSGi bundle, you can see it in the Apache Felix Web Console.

OSGi
OSGi bundle

View your OSGi bundle by performing these steps:

  1. Login to Adobe 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.

Create a custom submit action for the customer form

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.

Perform these steps: 

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.

 

CRXDE
A custom submit action folder

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 click the Adaptive Form Container, as shown in this illustration (you have to click on the outside of the adaptive form - see blue line below).

FormD
Click the adaptive form container

4. Click the wrench icon.

5. From the Adaptive Form container that appears in the left column, select Submission. Then from the Submit Action, select Invoke Service (the custom submit action). 

FormE
Select the custom submit action

8. 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 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 customer_ID = request.getParameter("customer_ID");
    String customer_Name = request.getParameter("customer_Name");
    String customer_Shipping_Address = request.getParameter("customer_Shipping_Address");
    String customer_State = request.getParameter("customer_State");
 String customer_ZIPCode = request.getParameter("customer_ZIPCode");
 String customer_Email = request.getParameter("customer_Email");

 
    com.aem.form.core.HandleForm hf = sling.getService(com.aem.form.core.HandleForm.class);
    hf.injestFormData(customer_ID,customer_Name,customer_Shipping_Address, customer_State,customer_ZIPCode,customer_Email);
 
 
%>

This code captures the posted form fields that are submitted from the adaptive form. It then creates an instance of com.aem.form.core.HandleForm object. Finally it invokes the HandleForm object's injestFormData method and passes the submitted values.  

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.

Submit the form data

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

http://localhost:4502/editor.html/content/forms/af/shipping-address-add-update-form.html

Click the Preview icon and fll out the Fields and click the Submit button. The following video shows this form being sumitted and an email message is sent. 

https://www.youtube.com/watch?v=S9o5Cim_xi4&feature=youtu.be

See also

Congratulations, you have just created an AEM workflow that approves or rejects an asset. 

You can view additional AEM Community generated content:

Join the AEM community at: Adobe Experience Manager Community

 

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