Author Archive: Anthony Rumsey

Guide Styling Made Easy

Have you ever tried creating a custom style for a LiveCycle Guide?  Editing the CSS in your favorite text editor was not an enjoyable experience and most often did not produce the desired results.

If this describes a situation you’ve had in the past consider today your lucky day!  A Guide Style Builder tool has been released on the Adobe Developer Connection.  The Style Builder application is a standalone GUI tool to create style sheets for LiveCycle ES2 Guides. This simple AIR application makes it dead simple for anyone to create their own custom Guide compatible CSS that can then be compiled to a SWC and referenced by Guide Builder.

With the Style Builder, you can:

  • Change colors and fonts for various elements of the guide
  • Set the background image and the logo to use
  • Change indent settings and set the appearance of rectangles

Share on Facebook

Controlling Navigation of Dynamically Added Modules in Cairngorm

In a recent application I was building there was a requirement for modules to be dynamically added at runtime based on a configuration file.  Since the application was already using Parsley and Cairngorm I looked to the existing Cairngorm navigation and module libraries to see if this was supported. I quickly discovered that the dynamic addition of modules and then being able to navigate to these modules was not supported out of the box. This led me to implement my own solution on top of the existing Cairngorm 3 libraries. There have also been a number of questions over on the Adobe forums about this topic so I decided it would be worth blogging about.

To solve my problem I had to implement two new distinct features.

  1. Dynamically add modules at runtime
  2. Connect these dynamically loaded modules to Cairngorm navigation

Dynamically Adding Modules

I’ll first look at how modules can be dynamically added to a Cairngorm/Parsley application based on a configuration file.

This is the simple XML file I defined that contains information about each module that needs to be loaded.

<modules>
<module id="mod1" label="Module 1" url="Module1.swf" location="content"/>
<module id="mod2" label="Module 2" url="Module2.swf" location="content"/>
</modules>

During the initialization of the main presentation model a message is dispatched to load the XML.

sendMessage(new LoadModuleConfigMessage(LoadModuleConfigMessage.LOAD));

Once the XML is loaded, a ModuleSet is updated to include a collection of Modules defined in the XML.  After the XML completes loading and is configured a second message is dispatched to add the modules to the view.  In this example all the modules are added to a ViewStack through the use of a repeater.

<mx:Repeater id="panelRepeater" dataProvider="{model.panels}"
repeatEnd="model.handleRepeatEnd(this)">
  <core:ControllerViewLoader width="100%" height="100%"
automationName="{panelRepeater.currentItem.moduleId}"
moduleManager="{panelRepeater.currentItem.moduleInfo}"
loadPolicy="{panelRepeater.currentItem.loadPolicy}"/>
</mx:Repeater>

You’ll notice that the repeater gets its data from a panels collection in its presentation model and simply repeats a ControllerViewLoader.  In the presentation model for this ViewStack there is a handler for the LoadModuleConfigMessage complete message.  In this handler the panels collection is generated by creating objects that contain the moduleId, moduleInfo and loadPolicy. The moduleInfo property is an instance of the ParsleyModuleManager which implements the IModuleManager interface.  It is this module manager that defines the location of the actual module SWF and what context and domain it should be loaded into.

[MessageHandler(selector="complete")]
public function loadComplete(msg:LoadModuleConfigMessage):void
{ 
    toolbarPM.menuItems.items.removeAll();
    ...
    moduleViews = new Array();
    var i:int;
    for (i = 0; i < modSet.modules.length; i++)
    { 
  var module:Module = modSet.modules.getItemAt(i) as Module;
       var view:Object = new Object();
       view.moduleId = module.location + "." + module.id;
       var modInfo:ParsleyModuleManager =
new ParsleyModuleManager(module.url, this.context,
                ClassInfo.currentDomain, null, null);
       view.moduleInfo = modInfo;
       view.loadPolicy = new BasicLoadPolicy(); ;
       moduleViews.push(new ObjectProxy(view));
       //Add menu bar item
       var dest:ContentDestination = new ContentDestination();
      dest.label = module.label;
      dest.destination = view.moduleId; 
      toolbarPM.menuItems.addDestination(dest);
    }
}
panels = new ArrayCollection(moduleViews);
}

Connecting Dynamically Added Modules to Navigation

A [Waypoint] metadata tag was first added to the ViewStack as specified in the Cairngorm documentation.

After the repeatEnd event is dispatched by the repeater in the ViewStack the modules have all been added and can now be safely wired to Cairngorm navigation.  This can be achieved by dispatching the Initialize event of the view stack.

vs.dispatchEvent(new Event(FlexEvent.INITIALIZE));

In order to actually navigate to a module the module has to be loaded first and then navigated to.  The module only needs to be loaded the first time it is navigated to.

 dispatchMessage(new LoadModuleMessage(destination));
 dispatchEvent(NavigationEvent.createNavigateToEvent(destination));

Finally, when defining landmarks in each individual module the landmark id must match the module id that was defined.  In the case of my solution moduleId is created from the location and id attributes defined in moduleConfig.xml.

Feel free to check out the full solution form the link below.

Share on Facebook

Move your Enterprise Applications to the Cloud

Over the past few months I have been working on a team that has been busy developing a solution to allow production quality applications to be hosted and deployed “in the cloud”.

 

Adobe LiveCycle is already established as a leader in automating processes to ease communication in your organization.  Now the burden of deploying and maintaining your own server infrastructure can also be eased by using LiveCycle Managed Services 

 

With Adobe LiveCycle® Managed Services, you can develop and deploy LiveCycle applications securely without installing, configuring, or maintaining LiveCycle instances in your own data center. All instances are hosted on the proven Amazon Elastic Compute cloud architecture.

 

The following LiveCycle ES2 modules are currently supported:

 

PDF Generator, Reader Extensions, Output, Rights Management, Digital Signatures, Forms, Process Management, and Content Services.

 

With 1.0 now out the door we are already busy working on lots of new features for future releases. Feel free to leave a comment however if you have any questions about using LiveCycle in the cloud.

 

Share on Facebook

Programmatically displaying LiveCycle ES2 Guides

The delivery of Guides (formally form guides) in LiveCycle ES2 has changed significantly.  Previously, form guides were rendered from an XDP using the Forms API.  Now that Guides in LiveCycle ES2 are derived from a model however the Forms API does not have to be used.  Instead, services have been made available that make it very easy to create a LiveCycle process that will return a guide.  When using LiveCycle Workspace this work is handled automatically but there will be situations where a developer will want to display a guide as part of their own web application.  In these cases LiveCycle provides several methods to invoke a process.  A simple REST URL or web service call could be made or the invocation API could be accessed programmatically.

In order to show how you can programmatically display a guide in a web application I have posted a recipe to the new LiveCycle Cookbook that is part of the Adobe Developer Connection.  Check it out and let me know what you think!  Also, I plan to start adding more LiveCycle and Guide recipes to the cookbook.  If you have any suggestions for content feel free to pass them along.

View all my cookbook recipes here.

Share on Facebook

LiveCycle DevNet site updated

It has been only a week since LiveCycle ES2 was officially released to the world.  To coincide with this release our DevNet site has also been appropriately redesigned and updated.

The new design should help inspire developers to get started creating their own LiveCycle applications and also offers plenty of opportunity to get involved in the community when help or advice is required.

So to all current and potential LiveCycle developers go forth and explore the new site and feel free to provide comments if you see any room for improvement.

Share on Facebook

LiveCycle MAX sessions worth watching

Adobe MAX has wrapped up for another year but that doesn’t mean it is over quite yet.  All of the sessions and keynotes presented during the three days are available online for free.

Marcel Boucher provided an excellent sold out session on what to expect next in LiveCycle ES.  Marcel introduced the latest application constructs that integrate the best-in-class technologies such as Flash Builder, Data Services, and LiveCycle ES solution components.

http://max.adobe.com/online/session/46

If you are interested in how to architect Adobe LiveCycle ES into your enterprise solutions, the session by Danny Saikaly is worth looking at.  Danny goes over how to design and implement Adobe LiveCycle ES in your technology stacks and enterprise applications. This session also reviews three recent LiveCycle ES implementations, including actual architectures and best practices.

http://max.adobe.com/online/session/343

Finally, if you are interested in the emergence of cloud computing be sure to check out an overview of the technology behind recently released Adobe LiveCycle ES Developer Express. LiveCycle Express is an enterprise SaaS product that leverages Adobe LiveCycle ES and cloud-based computing services to make the deployment and maintenance of enterprise software faster, easier, and less costly.

http://max.adobe.com/online/session/289

Check back here as more sessions I find interesting become available online.

Share on Facebook

Have you been to the cafe?

Adobe® LiveCycle® Café is a web-connected desktop application created with Adobe AIR. Café helps you stay in touch with the LiveCycle community, receive news, find information, and aggregate content related to Adobe LiveCycle ES (Enterprise Suite) software in a timely and customized fashion. Targeted at developers and technical staff, LiveCycle Café is the one tool you need to search across the entire community knowledge base and stay in touch with the Adobe LiveCycle teams.

I have been using this application since it was launched and even as an Adobe employee I find it to be an invaluable tool.  Through one interface I am able to track all the Adobe blog feeds I am interested in as well as monitor forums and news.

If you are a LiveCycle developer I highly recommend you try out Adobe Cafe at least once.

Share on Facebook

LiveCycle ES2 is just around the corner

With Adobe MAX just wrapping up now there were plenty of announcements made over the past couple of days for developers.  One announcement I am particularly excited about is LiveCycle Enterprise Suite 2 (ES2).

LiveCycle ES2 is Adobe’s enterprise offering for generating, capturing, and exchanging business information using integrated RIAs, secure documents and automated processes. LiveCycle ES2 helps businesses and governments more effectively deliver engaging applications across devices and channels to customers, citizens, and partners inside and outside the organization. New features of LiveCycle ES2 include personalized rich Internet application (RIA) workspaces, mobile and desktop access to business critical applications, a more collaborative and productive development environment, and a new deployment option in the cloud – allowing workers, developers and decision makers to bring value to their organizations faster than ever before.

LiveCycle ES2 now provides an ActionScript and JavaScript RIA application programming interface (API) that allows for rapid model-driven application development that reduces the amount of code required and simplifies data integration. Developers will also appreciate the new Adobe Solution Accelerators, which are deployable solution framework and best practices methodologies that help developers kick start project planning and decrease development time by leveraging best practices and processes and re-using existing code and building blocks to extend LiveCycle solution components.

Also announced is a cloud deployment option for Adobe LiveCycle ES2 hosted in the Amazon Web Services cloud computing environment, making it easier for developers to stage multiple LiveCycle applications before going live in production.

Over the next couple of months as LiveCycle ES2 gets closer to being launched I will continue to post information on what I feel are some of the more compelling reasons to use LiveCycle ES2.  Feel free to post coments as well if there are any particular areas you would like to be discussed.

Share on Facebook

Adobe MAX Online

I am unable to attend Adobe MAX in person this year but I am going to be sure to still participate by using Adobe MAX Online. 

Adobe MAX Online will allow me to view the live streaming keynotes on Oct 5 & 6 to get the latest design & development trends.

After 8 P.M. PST each day, from October 5th to 7th, I will also be able to see the top session of the day from each track: Design, Develop, and Envision. I’ll be able to view these sessions on demand on MAX Online and join the buzz by participating in the extended Twitter conversation.

Finally I plan to check back on Sunday, October 11th, for all of the sessions available on demand.

http://www.max.adobe.com/online

Participants will also be able to connect with the community during the webcast through twitter at #adobemaxgs.

Follow me on Twitter at #planetrumsey.
 

Share on Facebook

Executing web service calls in a form guide

LiveCycle ES Designer makes it easy to set up a connection to a WSDL in order to execute some web service call.  This functionality can also be extended to your form guide with a few simple steps.

A data connection to a web service will first need to be defined on your form.  These steps are the same regardless of what your ultimate form rendering will be.

  • Create your data connection in LiveCycle Designer.
  • Set up required data bindings.
  • Add the web service invoke button to your form.

At this point if you were to preview your form and click the invoke button a client-side web service call would be invoked by the PDF based on your data bindings.  A form guide however must execute its web service calls on the server which means a few extra steps are required.

Now let’s make the required changes to have this web service executed by a form guide.

  • Change the execution options of the invoke button to Run At Server.  If you also want the PDF to execute web service calls on the client you will need to add two invoke buttons and hide the one that will be used by the form guide.

As a minimum this is all that needs to be done.  Adding this button you your form guide will allow it to execute the desired web service and display the result based on your data bindings.  I am now going to dig a little deeper however to see how we can improve the experience on the form guide.

  • Add a hidden field to hold the status of asynchronous calls (eg. asyncCallActive).  This field will indicate to the guide if a server-side web service call is currently active.
  • Add another hidden button (eg. executeWS) whose click event is set to run at server.
  • Add the following script to the button’s click event (invokeBtn is the name of your web service execute button).
invokeBtn.execEvent("click");
asyncCallActive.rawValue = "false";

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

At this point we have all the server-side pieces in place for the form guide to be able to execute a web service.  All that still needs to be done is add the ability on the client to actually invoke this web service.  This step for the most part depends on your particular form design.  Typical usage includes invoking the web service on exit of some field or just by clicking a button.  Let’s look at the on exit case.

Let’s assume we have a web service that looks up the weather for a given zip code.  In this case it would make sense to invoke the web service on the exit event of a zip code field.

  • Add the following client-side script to the field’s exit event.
asyncCallActive.rawValue = "true";
executeWS.execEvent("click");

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

In the form guide whenever this field is executed the click event of the executeWS button will be executed on the server.  The result of the web service call will be merged back into the form guide based on what ever field bindings you had defined.

We’re almost done but not quite. You may have noticed that I have been setting the rawValue of the asyncCallActive field but not doing anything with it.  Add the following client-side script to this field’s change event.

if (xfa.host.name == "Flash" && this.rawValue)
{
    import mx.managers.CursorManager;
if (this.rawValue == "true")
CursorManager.setBusyCursor();
else
CursorManager.removeBusyCursor();
}

This script is a form guide trick that allows you to add ActionScript to your form that will only be executed in the form guide.  The check that xfa.host.name is Flash ensures this script will not execute on the PDF.  As a result we are able to set the Flex busy cursor state based on the value of the asyncCallActive field.  This helps your form provide feedback to the user that some back-end processing is being done.

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Download XDP

Share on Facebook