Create custom Mobile Form profile

Mobile Form renders the form based on profile. If you want to change the look and feel or do other customization, you are required to make modifications in the default profile. In ES4, Mobile Form profile script was one single monolithic jsp file. So if you want to modify the profile script you have to copy the whole script and then make the changes as suggested in ES4 Adobe documentation. This way, you loose the updates provided in the script over different patches.

With ES4 SP1, we have modularized the various constituents of profile renderer instead of one monolithic profile. The profile script is still html.jsp and html.POST.jsp for GET and POST requests. One can choose to override or add his customization by copying and modifying one or more files. It is not recommended to modify any of the files in place or you will loose the changes after a patch.

You should create an application directory in /apps space and copy html.jsp and other files you want to modify. Before delving into the steps of customization, I will discuss the changed structure of html.jsp.


<%@ page session="false"
               contentType="text/html; charset=utf-8"%><%
%><%@ taglib prefix="cq" uri="" %><%


As you can see html.jsp is just serves as composition jsp. Now customization means, you need to create new components and add them into the appropriate section of html.jsp.

In subsequent sections, I will explore all the components of html.jsp in detail.


<%@ page import="java.util.ArrayList" %><%
%><%@taglib prefix="cq" uri="" %><%
    String acceptLang = request.getHeader("accept-language");
    if(acceptLang == null || "".equals(acceptLang.trim()))
        acceptLang = "en-US";
    acceptLang = acceptLang.trim();

    String[] locales = acceptLang.split(",");
    ArrayList localeChainList = new ArrayList();
    for(int i=0; i<%

LC Forms

As you can see it contains the references to the client libraries to include. It also depicts how one can extract locale information from the request and include the localized messages related to Mobile Forms runtime. You can create a JSP like this to include your own scripts and styles and add it to the head section of html.jsp.


<%@ page session="false"
               " %>
<%@ page import="" %>
%><%@taglib prefix="sling" uri=""%><%
    LCFormsOptionService lcFormsOptionService = sling.getService(LCFormsOptionService.class);
    //read debugDir to pass it along with server API endpoint -- use it for debugging.
    String debugDir = lcFormsOptionService.get(slingRequest, "debugDir");

    if(debugDir != null && !debugDir.isEmpty()) {
        debugDir = "?debugDir="+debugDir;
    else {
        debugDir = "";

    SlingSettingsService slingSettingsService = sling.getService(SlingSettingsService.class);
    boolean  isLCEmbedded = slingSettingsService.getRunModes().contains("livecycle");

    //lcServerProxy that will handle forms server api requests and also submission...
    String submitServiceProxy = lcFormsOptionService.get(slingRequest, "submitServiceProxy");
    if(submitServiceProxy == null) //if running into lc embedded mode then append /lc
        submitServiceProxy = (isLCEmbedded ? "/lc" : "") + "/bin/xfaforms/submitaction"+debugDir;
    String logServiceProxy = lcFormsOptionService.get(slingRequest, "logServiceProxy");

    if(logServiceProxy == null)
        logServiceProxy = (isLCEmbedded ? "/lc" : "") + "/bin/xfaforms/logger";

    String submitUrl = lcFormsOptionService.get(slingRequest, "submitUrl");
    if(submitUrl == null)
        submitUrl = "";
    //to enable logging options...
    LCFormsAdminService formsAdminService = sling.getService(LCFormsAdminService.class);
    formsAdminService.setupLogging (slingRequest);
    String originalVersion = formsAdminService.getOriginalVersion();

As you can see this component of profile contains the various configurations like logging, proxy services, behaviour version etc. If you want to add you own config then this is the place. You can add various configurations like custom widget registration etc just like this in a JSP of your own.


<%@taglib prefix="cq" uri="" %><%

This component is responsible for the red coloured toolbar you notice at the top. In case you want to get rid of the toolbar, you can remove this from the html.jsp.


<%@taglib prefix="sling" uri=""%>

This component is for the html presentation of the XFA form. As shown in html.jsp, you can include this component in the body section of the html.


Mobile Form only renders the first page of the form at first and then subsequently load the pages on scroll to give faster loading experience. This component contains all the styles and required elements to facilitate this.


This is empty for now. But in case you want to add any scripts that is used in user interaction only then you should include that in this section.

Creating Custom profile

Now that we understand what all components does then one can choose to modify a component. Here are the steps on how to create a custom profile.

Creating profile node:

Note: The name of the newly created folders (hrform and demo) can be anything as per your preference.

  1. Navigate to the CRX DE interface at the URL: http://<server>:<port>/lc/crx/de and log in to the interface with administrator credentials.
  2. In the left pane, navigate to the location: /content/xfaforms/profiles.
  3. Copy the node default, and paste the node in different folder e.g. (/content/yourapp/profiles) with the name: hrform.
  4. Select the new node, hrform, and add a string property: sling:resourceType with value: hrform/demo.
  5. Click Save All in toolbar menu to save the changes.

Creating the profile renderer script:

After creating a custom profile, add render information to this profile. On receiving a request for the new profile, CRX verifies the existence of the /apps folder for the JSP page to be rendered. Create the JSP page in the /apps folder.

  1. In the left pane, navigate to the /apps folder.
  2. Right-click on the /apps folder and choose to create a folder with name: hrform.
  3. Insider the hrform folder create a folder: demo.
  4. Click the Save All button.
  5. Navigate to /libs/xfaforms/profile/html.jsp and copy the node html.jsp.
  6. Paste html.jsp node into the /apps/hrform/demo folder created above with same name html.jsp and click Save.
  7. You copy any of the other components of profile script as described above and paste it in the same folder.

Verifying the updates

Render a form using Mobile Forms IVS with the custom profile:

  1. Navigate to http://localhost:8080/mobileformsivs.
  2. Choose and update the form demo.xdp.
  3. Select the demo.xdp form. Choose Custom in profile, and specify hrform as the profile name.

Debugging Mobile Form

Logging in Mobile Form or any application for that matter is of utmost importance. It helps our customers in debugging the various issues in forms including performance. Mobile Form is a distributed application. It has a server component that generates data for the XFA runtime. XFA runtime is a javascript implementation of XFA reference that runs inside the browser and interprets the data generated by the Mobile Form server to render an XFA template and data in html5. In distributes scenario, logging helps a lot in keeping tab at what is going on at various sites.

Mobile Form has two distinct sites or two different components the Mobile Form server and XFA runtime.  One can configure Logger, individually (server and client), based on the requirements and set the levels for any specific request.

I will first describe on how to enable fine level logging in Mobile Form server and how to make sense out of it.

The steps are outlined as following:

  1. Go to http://<server>:<port>/lc/system/console/configMgr and look for “Apace Sling logging logger configuration” and click on it. You see a dialog like following:
  2. Select the Log Level to Debug.
  3. Specify a log file name. If you want to generate logs in the same directory i.e. <lc-install-dir>/crx-repository/logs, where other log files are kept then specify ../logs/<logfilename>.
  4. Specify Logger to HTMLFormsPerfLogger and save the configuration.



That’s it. Now you can find the logs with performance for each render request. The log entries should look like the following:

04.07.2012 17:58:14.054 *DEBUG* [ [1341404888673] GET /content/xfaforms/profiles/test.html HTTP/1.1] HTMLFormsPerfLogger !PERFORMANCE! <RenderOsgiServiceImpl.render>

04.07.2012 17:58:14.142 *DEBUG* [ [1341404888673] GET /content/xfaforms/profiles/test.html HTTP/1.1] HTMLFormsPerfLogger !PERFORMANCE! <time>4004644004ns</time></RenderOsgiServiceImpl.render>

We are interested only in the last word of these log line. That will give you a valid xml file containing all the timings. Each label of the node represents the name of the API and <time> node contains the time taken by that API. You can use awk to generate that xml file. The following command would do: awk ‘{ print $11 }’ <logfilepath>

It is called perf logger because it generates performance information along with the trace. That is it about Mobile Form server logging. Now let’s move to client side logging.

There are two ways to enable XFA runtime client side logging. Like Mobile Form server logging, one way is to enable logs via configuration another via request parameter log. If you just want to generate logs for one particular request, you should use the 2nd approach i.e. pass the request parameter. The log parameter takes log configuration that is defined as follows:

{destination}-{a level}-{b level}-{c level}

For example:

Log Configuration Description
2-a4-b5-c6 Destination: Server
xfa level: INFO
xfaView level: DEBUG
xfaPerf level: TRACE


Let’s explore various constituents of log configuration. destination  is where log is redirected:

Log Destination

Log Destination Description
1 Logs are directed to the browser Console
2 Logs are collected in a JavaScript object on client side and can be posted to the Server
3 Both of the above options


Log Levels and Logger Categories are other constituents.

Log Levels

Log Level Description

Logger Categories

Log Category Description
a xfa (Scripting engine related logs)
b xfaView (Layout engine related logs)
c xfaPerf (Performance related logs)

The default log level for each log category a (xfa), b (xfaView), and c (xfaPerf) is 2 (ERROR). Accordingly, for log configuration: 2-b6, the log levels for different categories are:

a (xfa): 2 (default level ERROR)
b (xfaView): 6 (user specified TRACE)
a (xfaPerf): 2 (default level ERROR)


You specify the log configuration using LC Forms Configuration:

  1. Search for and click LC Forms Configurations on http://<server>:<port>/lc/system/console/configMgr page.
  2. In the Debug Options text box, enter the log configurations as described in the previous section e.g. 2-a4-b5-c6.




If the destination is set as 1, all client script log messages are directed to the console. But at times Admin might need these logs along with server logs to co relate the two and for such cases destination level can be set to 2. At this level, all logs would be collected in a JS object on client side and if form is rendered with default Profile then a Send Logs button would appear to the left of Highlight Existing Fields button in toolbar. On click of this link all collected logs would be posted to the server and will be logged in the configured error log file on the server.

With ES4 SP1, you can also redirect client logs to a separate log file like Mobile Form server logs using the same steps mentioned to configure “Apace Sling logging logger configuration”  above in server logging section.