Creating a Flip Book CQ Component

The canvas element is a new tag included in HTML 5. This allows for dynamic renderings of 2D shapes and bitmap images. I recently stumbled across a great example of the powerful effects that can be accomplished with the canvas element and javascript on a web app called 20 Things I learned about Browsers and the Web. The web application tells a nice summary of the basic history of the internet and open web technologies. What really makes it cool is that the information is presented as an interactive book and allows the user to “flip” the pages by dragging the mouse.

I thought it would be interesting to take this functionality and create a re-usable component in CQ. This would allow authors to add the component onto any paragraph system and drag text and images from the content finder to populate the “pages” of the book. The following tutorial focuses on creating a custom CQ component that uses its own CSS, images, and Javascript to make it run.

Continue reading…

Populate a Drop Down List in LiveCycle Designer with Dynamically Generated XML

One way to populate a Drop-down List on a LiveCycle form is using XML binding. In the situation explained below, the XML document is dynamically generated and bound to the form’s data model within a LiveCycle process by querying the database.

Situation:

Querying a database for all the supervisors and their ID. Then populate a drop-down list on the form with a single Data Connection.

4 Steps:

  1. Create a DataConnection on your form with an XSD that includes unbound occurrence of the list items.
  2. Add a Drop-down list to the form
  3. Bind the data to the drop-down list
  4. Create an Action Profile process to pre-populate the form with data from the database

1. Create a DataConnection on your form with an XSD that includes unbound occurrence of the list items.

Since the drop down list is only one field in the form and we are using a single data connection to bind data to the form, insert the following element node for the Supervisor Drop-down List. The selected fields are to be used to hold the currently selected value in the drop-down list.

<xs:element name="supervisorList">
      <xs:complexType>
              <xs:sequence>
                   <xs:element name="supervisor">
                         <xs:complexType>
                             <xs:sequence maxOccurs="unbounded">
                                 <xs:element name="supervisorID" type="xs:int"/>
                                 <xs:element name="supervisorName" type="xs:string"/>
                             </xs:sequence>
                         <xs:complexType>
                     </xs:element>
              </xs:sequence>
       </xs:complexType>
 </xs:element>
<xs:element name="selectedSupervisorName" type="xs:string"/>
<xs:element name="selectedSupervisorID" type="xs:int"/>

To add the Data Connection to your form:

  • Right click on the Data View Tab
  • Select New Data Connection
  • Select XML Schema
  • Browse to the XSD in your Application
  • Select the root node and Press OK

2. Add a Drop-down list to the form

From the Object Library in LiveCycle Designer, drag the Drop-down List object on to the form.

3. Bind the data to the drop-down list

Under the Object Panel, click on the Binding Tab. Bind the item to the selectSupervisorID in the Data Connection.

After adding data binding, the Specify Item Values text should become a green hyperlink. If link text is not green, ensure that dynamic properties is turned on. Click on the Specify Items Value.

Fill out the fields as shown above. Notice the [x] in the Items field. This enables all the elements to be loaded in to the list.

4. Create an Action Profile process to pre-populate the form with data from the database

In order to pre-populate the Drop-down list before the user sees the form:

  1. Create an Action Profile for the form that will call a Prepare Data Process
  2. Inside the Prepare Data Process, Create an XML variable called SupervisorList
  3. Inside the Prepare Data Process, Query the Database and Build an XML Variable using the Service Query for Multiple Rows as XML Service (Foundation/JdbcService).  After applying a SQL Statement to retreive the Supervisor ID and Supervisor Name from the database, click on the elipses button next to XML Information and fill it according to the image below according to your XSD.
  4. Set the Output for Step 3 Service to be the XML Variable created in Step 2.
  5. Bind the XML to the XSD element used in the forms DataConnection using setValue

Now, when the user pulls up the form in Workspace, it comes pre-populated with all of the Supervisors Names. The value for each field will be the Supervisor ID in this case.

Compiling a PDF Portfolio in LiveCycle

Situation:

How to merge multiple PDFs (retreived from a Database BLOB) and compile them using DDX and LiveCycle (ADEP). The portfolio will build based on the number of documents stored inside the database.

In this situation we will be compiling a Cover Page, Content Document(s), and a Final Document. Depending on the workflow state, there could be 0-5 documents in the database under the Content Document(s) section. The process is flexible enough to handle this.

Create the DDX File:

  1. Start by looking at the Assembly Descriptor documentation and DDX Reference Guide.
  2. In Workbench: Create a New Application (File>New>Application)
  3. Inside the Application directory, create a new folder and name it Assets.
  4. Locate the Acrobat .nav File you want to use. It will be located on your filesystem here: [Acrobat Location]\Acrobat\Navigators. For this situation AdobeRevolve.nav is being used. Import the .nav file into your Application’s Assets folder.
  5. Create a DDX file
    1. Right Click on Asset Folder> New > Assembly Descriptor.
    2. Provide a name for the DDX document.
    3. Click Finish.
    4. The Document Builder Window should come up inside Workbench
  6. The DDX File in the End will look like this:
    1. Start by Selecting New Result>PDF and Name it CompiledPDF
    2. Drag the Portfolio Component Under the CompiledPDF
    3. Under the Portfolio Editor paste the following elements:
      <Portfolio>
        <ColorScheme scheme="darkblueScheme"/>
        <Header/>
        <WelcomePage/>
        <Schema/>
        <DisplayOrder/>
        <SortOrder/>
        <Navigator source="AdobeRevolve.nav"/>
      </Portfolio>
    4. Press Apply in the Editor
    5. Drag the Navigator icon under the Portfolio Icon
    6. Paste the following under the Navigator Editor:  <Navigator source=”AdobeRevolve.nav”/>
    7. Press Apply in the Editor
    8. Drag the Packaged Files Icon underneath the Portfolio Icon
    9. Then add Seven PDF Documents sources under the Packaged Files and Name them in their Source field accordingly
    10. For Only the CoverPage document (the first one), go under the Basic tab and select both “This is the Base Document” and “There must be at least one valid source in this document” and ensure both of these boxes are deselected for the other PDF Document.
  7. Validate the DDX and Save it

Create a Process that will retrieve the documents from the database BLOB, assign them to a document map, invoke the DDX, Output a single PDF Portfolio document

The process will be built to look something like this:

In this process you will need the following variables:

    • thePortfolio–document–Output–Required
    • retrievedDocument –document
    • mapPortfolioDocs–map <document>
    • totalContentDocs–int
    • counter–int
    • tempContentDocID– string
    • PortfolioAssemblerResult–AssemblerResult
Retrieve a specific PDF document from the Oracle database BLOB and store it in the local variable retrievedDocument by executing the following executeScript service.
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.ResultSet;
import javax.sql.DataSource;
import javax.naming.InitialContext;
 try {
   InitialContext context = new InitialContext();
   String queryQuery = [input your query here to get blob]
   //If you need to pass a process variable use "patExecContext.getProcessDataValue("/process_data/@counter");
   try {
    DataSource ds = (DataSource) context.lookup("java:/DDXDocs_DS");
    connection = ds.getConnection();
    queryStatement = connection.prepareStatement(queryQuery);
    results = queryStatement.executeQuery();
    if (results.next()) {
        java.sql.Blob documentBlob = results.getBlob(1);
        com.adobe.idp.Document document = new com.adobe.idp.Document(documentBlob.getBinaryStream());|
        patExecContext.setProcessDataValue("/process_data/@retrievedDocument", document);
     }
   }catch(Exception ex){
	System.out.println(ex.printStackTrace());
} finally {
    if (results != null) {
    	 results.close();
    }
    if (queryStatement != null) {
        queryStatement.close();
    }
    if (connection != null) {
        connection.close();
    }
   }
 } catch (Exception e) {
   e.printStackTrace();
 }

 

To test if a BLOB had been retrieved use the following route condition:

getDocLength(/process_data/@retrievedDocument)==0

 

If the document  was successfully retrieved, map it to the map <document> variable (mapPortfolioDocs) based on the id you gave it in the DDX source, using the setValue mapping below:

After retrieving all of the documents available, it is time to InvokeDDX. Using the Invoke DDX Service:
Finally, using the setValue operation, map the AssemblerResult to the output document variable (thePortfolio):