Stefan Cameron on Forms
Building intelligent forms using Adobe LiveCycle Designer

Correspondence Management

There are some activities that all businesses need to do. Two of those are corresponding with customers and opening new accounts (they could be simple processes or they could be very complicated depending on various requirements). Adobe has recognized this need and has added a new segment to it’s LiveCycle Enterprise Suite called Solution Accelerators.

These Solution Accelerators come in the form of development kits that provide tools, built on top of LiveCycle, that are designed to help businesses, enterprises and government agencies quickly get started on a correspondence (eg. building letters and sending them to customers) and/or enrollment (eg. opening a new bank account) solution tailored to their business requirements.

For the past few months now, I’ve been working on the Correspondence Management Team at Adobe. We’re building some really cool tools that leverage many aspects of LiveCycle, Flex and AIR. Today is an exciting day because I’ve just found-out that we now have our own spaces, for enterprise, financial services and government, on Adobe’s web site!

Are you excited about this? Is this something your company has been looking for? What kind of features would you expect to see in a Correspondence Management or Enrollment Solution Accelerator?

PS: This doesn’t mean the Designer-related posts will stop. I’m still very much involved with Designer and I use it every day so there’s still plenty to talk about.


Posted by Stefan Cameron on June 19th, 2008
Filed under CM
Both comments and pings are currently closed.

15 Responses to “Correspondence Management”

  1. nep on November 9th, 2008

    Hello Stefan,

    Nice to know you are putting your hands in this kind of projects.

    Actually I believe this accelerators can be a great help for adobe livecycle users. I knew about them due to some questions I made to Adobe and livecycle users in general concerning a specific goal. I would like to share this goal with you, and get your always useful opinion, if possible.

    I m evaluating the possibility of dynamically create a pdf/xdp form using a process in workbench. the steps would be like this:

    1 – a designer would design a pdf/xdp in designer (workbench) and then create a formguide with it. This form would be only to get the necessary answers to evaluate process conditions.

    2 – a process would be designed. The first activity would be to get a formguide and answer to its questions. The output of this activity would be the xml data of the form guide/pdf source. The next activities would run depending of the data in the xml. In each activity, and depending of the data, a new pdf/xdp form would be constructed, activity by activity. At the end I would get a new xdp file.

    3 – When a user invokes the process (external application), it will get the formguide, the data is submited and the process continues. A new and final xdp/pdf file will be given to this user.

    Do you think this is possible to achieve? Any recomendation?

    Thank you

    nep

  2. Stefan Cameron on November 10th, 2008

    nep,

    What you’re describing is almost what we do for CM however we re-use the same XDP to produce the output letter. We collect data for the letter using a Form Guide (we call it the “Letter Filling Experience”) and then re-merge that data into the same XDP and serve it out as a PDF in order to generate the letter.

    I don’t see why this wouldn’t be possible. Collecting data via a Form Guide is trivial, as well as getting Form Server to serve-up a new XDP as a PDF. The hard part will be generating the new XDP file since it may involve some deeper knowledge of XFA to do it properly. Of course, you could cheat by creating a template XDP file and putting some PIs in it, for example, as insertion points. Then you could just load the structure as plain XML, find the PIs and replace them with the XFA pieces you want. Or you could even use string parsing to do the replacement. In any case, you’ll want to ensure that the final product is valid XFA syntax.

    Let me know how it goes!

  3. nep on November 10th, 2008

    Hello again Stefan,

    The idea is to create a new xdp file based on previous created fragments. Given the data collected from the FormGuide, we would create, step by step, the new xdp file, by adding new fragments.

    I think we could, and we will, begin the process from a default template, but I dont know waht you mean by using PIs. Any example somewhere?

    Thank you

  4. Stefan Cameron on November 10th, 2008

    nep,

    What I meant by using PIs (processing instructions) is that you would use them to identify locations in the XDP where you would place the fragment references.

    For instance, say your XDP template was like this:

    <xdp>
        <template>
            <subform name="rootSF">
                <?insert mainContent?>
            </subform>
        </template>
    </xdp>

    You could then load that into an XML DOM, find the <?insert mainContent?> PI node and replace it with your fragment reference(s):

    <xdp>
        <template>
            <subform name="rootSF">
                <subform usehref="../frag/main.xdp#som($template.#subform[0].fragSF)"/>
            </subform>
        </template>
    </xdp>

    In this way, you wouldn’t really need to write a DOM that understood the XFA structure, provided the subform fragment reference you insert is in good order.

    But if you’re considering doing this, especially on the server in an LC process, you might consider having a look at the DDX technology included in the CM Solution Accelerator’s PDK. It’s a Java library meant specifically to do dynamic server-side XFA document assembly. In fact, you might also want to check-out the Enrollment Solution Accelerator since it might contain some UI (Flex app?) that uses DDX in the back-end.

  5. nep on November 12th, 2008

    Hello Stefan,

    I now understand the PIs solution, thank you. However, I think I will not be able to use them because I don´t know, at (template) design-time, how many PIs I will need. Because I only need to add paragraphs one after another, I believe I will only need to add this kind of instruction, one after another (in each process activity) to the xdp I will be creating:

    What do you think would be the best approch to add this line of code to a xdp file in an activity? Do you think xpath would be the best approch?

    Another question I would like to make is about the start of the process and more specifically formguides. I know that to create a formguide, one needs to have a template as a source. However, is it possible to delivery only the formguide to the user invoking it without delivering the pdf? I ask this because what I really need is the data captured in the formguide and not the pdf template. Thus the PDF template would only be needed to create the formguide and nothing more than that.

    Finally, if I invoke a process using soap inan external application (Java or .net), is it possible to define a formguide as the first step (activity), in order to delivery the formguide as a soap response (maybe as a base64 stream), and then use it to invoke the second step of the process using that formguide (to submit the data) from the external application that received the formguide?

    Thank you again

  6. Stefan Cameron on November 18th, 2008

    nep,

    I’m guessing you included some code with a “<” bracket in it and it got wiped-out so I can’t help you there. If you re-post it, replace any “&lt” brackets with “&lt;”.

    Yes, you can render a form as a form guide without the PDF. LC Forms will have a switch you can set (or not) to choose whether to include the PDF with the form guide.

    As for your last question, I’m guessing you’re trying to get the form guide to show-up within some other framework. As I understand it, this can be done by using an iframe and setting its source to the HTML stub returned from a call to LiveCycle Forms’ “renderform” API. Using this API call, you can request that a particular form be rendered as a form guide and the HTML stub returned will contain the code necessary to display the form guide rendered by LC Forms. I’ve never done this myself but I’ve seen it done before.

  7. nep on November 30th, 2008

    Stefan,

    The code I was trying to show here was actually your own code from a previous post. The idea was to add one of this line in the final xdp, based on the avaliation rules about which fragments that final xdp should have. I think this should be something easy to accomplish…

    <subform usehref=”../frag/main.xdp#som($template.#subform[0].fragSF)”/>

    About form guides, you are saying that form server will reply a stub to the formguide. This was confusing me, because I was seeing the reply as a base64 stream ripped from the xdp of the source template. What I was not understanding was how all those javascript files used by formguides would come from. If that stub is something like an html link, then I think I understand how it will work. However, if you know someone that as done this, or any example elsewhere, please let me know, becuase that would be a great help.

    With this formguide, I would like to invoke another livecycle process, passing it a xml stream of the data. That way I will not need to create a custom screen/form in any other technology. However, the call to the formguide should be done using a java/.net client, that is why I need to retrieve a formguide from livecycle. I know I could use workspace as the client, but I would like to have other alternatives.

    Thank you

  8. Stefan Cameron on December 3rd, 2008

    nep,

    Since PIs not generated by XFA are ignored in XFA processors, you should be able to define one PI to mark the insertion point for the <subform usehref=”…”/> nodes and append them after the PI in the document instead of trying to predict how many PIs you will need. After you’re done adding fragment references, you can either leave the PI in there or remove it; it shouldn’t make a difference either way.

    For form guide rendering from LiveCycle, what I’m saying is that you would set the innerHTML property of an <iframe/> node to what the call to the “renderform” API returns which will be a short HTML stub containing some callbacks for FormServer. The result, when the iframe is rendered, will be what you asked for in the “renderform” API call. If you ask for the form guide without the PDF, that’s what you’ll end-up with.

    As for invoking another LC process from within the form guide and passing it the guide’s data, you should be able to get the guide’s data by doing xfa.datasets.data.saveXML() as you would normally do in the PDF and then do a remove object call into LC in order to invoke the process. For an example, have a look at the Custom Communications “CSR” AIR app that’s included in the CM SDK’s applications folder (source is included in the SDK as well).

  9. nep on January 8th, 2009

    Hello Stefan,

    Using some steps in process, I was able to create a xfa template held in a xml variable. This xfa template has some fragments with relative urls to the repository. However, when I tranform this xdp template into a pdf it seems my fragments are not being resolved. I think this happens because there is not a position context to this xfa template in the repository as it was created dynamically. As so, do you know another way to point to the repository fragments without depending of the location of the main template?

    thank you

  10. nep on January 11th, 2009

    Stefan,

    While trying to solve the problem from my last reply, I think I discover a bug. If possible I would like to send you the xml of my process.

    thank you

  11. Stefan Cameron on January 14th, 2009

    nep,

    With regards to your first comment (on Jan 8, 2009), I believe the template you create will need to be stored in the LiveCycle Repository prior to being rendered as a PDF. Otherwise, the render service will not be able to resolve the fragments, as you’re seeing in your test.

    This is where the Correspondence Management SDK could help you out since the CM Model API has classes that can create assets directly in the LC Repository. The only problem here might be that it’s written in ActionScript and I think you’re using Java — not sure.

    In any case, here’s how you would use the API to create a new generic form resource, stuff your dynamically-generated template content into it and save it to the LC Repository using the currently-posted release:

    import cm.model.CmObject;
    import cm.model.CmSession;
    import cm.model.repository.CmResourceType;
    import cm.model.repository.CmRepositoryEvent;
    import cm.model.repository.CmRepositoryFactory;
    import cm.model.repository.CmResourceCollection;
    import cm.model.repository.ICmRepository;
    
    private function onBtnClick(event:Event):void
    {
        // create a new generic form template resource object
        var xdp:CmObject = new CmObject();
        xdp.resourceType = CmResourceType.FORM_TEMPLATE;
        xdp.path = "/cm/content/myForm.xdp";
        xdp.contentType = "application/vnd.adobe.xdp+xml";
        xdp.contentData = '<xdp><template><subform name="root"><subform name="page"><field/></subform></subform></template></xdp>';
    
        // make sure there's an active, authenticated session
        if (CmSession.getInstance() == null || !CmSession.getInstance().authenticated)
            CmSession.createInstance(username, password, server, port);
    
        // get an instance of the LC Repository
        var rep:ICmRepository = CmRepositoryFactory.getInstance();
    
        // save it in the LC Repository
        rep.save(xdp, true, onSave, onSaveFault);
    }
    
    private function onSave(event:CmRepositoryEvent):void
    {
        Alert.show("Saved XDP to LC Repository");
    }
    
    private function onSaveFault(event:FaultEvent):void
    {
        Alert.show("Error occurred while attempting to save: " + event.fault.toString());
    }
  12. Stefan Cameron on January 15th, 2009

    nep,

    In response to your second comment (on Jan 11th, 2009), what bug is it you think you have discovered?

  13. Duarte Cunha Leão on January 18th, 2009

    I am using LiveCycle Workbench to design xdp documents. We reference fragment xdp documents from the repository and also we have the “usehref”, directly used on field.s, draw.s, to inherit behavior from a common xdp at the repository.
    We use something like this: usehref=”..\Fragments\Base.xdp”.
    The relative uri limits the placement of refering documents relative to the common xdp (unless, of course we would change the relative path accordingly, but we have fixed templates in the object library , so we would like to avoid that).

    Is there a way to use absolute uris, in the usehref attribute, to reference documents in the repository?

    I’ve tried all obvious combinations of uris containing a “repository” or “resource” uri-scheme, like in:
    repository://Base.xdp

    Thanks in advance

  14. Duarte Cunha Leão on January 19th, 2009

    I forgot to include the “element” identifier, in the usehref example:
    usehref=”..\Fragments\Base.xdp#idFieldABC”

  15. Stefan Cameron on January 26th, 2009

    Duarte Cunha Leao,

    Yes, you can reference fragments in the LiveCycle Repository using an absolute path. The path must be in the form of

    repository:///root/path/form.xdp#fragRef

    where “root” is the root folder in the Repository in which the content is located, “path” is the intermediate path from the root to the content, “form” is the XDP that contains the fragment to be referenced and “fragRef” is the ID or SOM reference to the fragment in the form.

    Note the 3 slashes following “repository:” in the path above. If you specify only two (2), the first element in the path is considered to be the “authority” but this syntax is currently not supported.

    Also note that “repository:///” paths are not resolved by Designer which means that when you go to the XML Source to set the absolute path and go back to Designer’s “Design View” or “Master Pages” tabs, you’ll see a broken fragment reference instead of the actual (resolved) fragment content.

    LiveCycle Forms is therefore required to resolve “repository:///” paths. When you render your form using LC Forms, the fragments will be resolved properly.