Javascript to populate data between dynamic XFA forms

Dear Thom,

let me ask you for professional advice on following:

I have a dynamic PDF form build in LiveCycle, which is basically an interactive pdf catalog. It is overloaded with graphic and has more than 30 Mbytes size. Last page of this form contains dynamic table which generates a purchase order information, based on user's selections.

My problem now is I need to extract that purchase order data saved as separate file. I need it because it will have much smaller size, so it can be easily emailed to supervising person, without the need to pass the whole 30 mbytes file.

I made some progress by creating a small-size analog file by removing all images and hiding the catalog pages, leaving only purchase order page visible. So basically it's the same file, having same fields structure. This allowed me to submit xml data from big file and then import it using Acrobat to small-size version.

What I want to achieve now is that user could have both files in his local folder, and after finishing working with large catalog file, just press a button, which would copy all the data (perhaps as xml) to small-size version, so only the purchase order page can be saved separately.

I read some info about usage of following command:
this.slave = app.openDoc("smallsizefilename.pdf",this);

and then copy field values by something like this:
var oEnd = this.getField ("endDate");
var sEnd = this.slave.getField("endDate");
sEnd.value = oEnd.value;

my problem is that my form is dynamic, so I can't make any fixed fields connections, like in the shown example.

I need to mention that copy data operation will take place offline, with both files located in the same folder. I hope this would make things easier.

I would be really thankful for any ideas to solve this task.

Thank you for all your great support.

Kind regards,
Sergiy.


Sergiy Kotenko


6 Answers

Voted Best Answer

You are getting close, but there are some problems with your code.

First, watch this video:
https://adobechats.adobeconnect.com/_...

Next, Do not use the "getField" function and do not specific the instance index in your field reference. Do it like this.

var oCustomer = form1.page1.First_Name.rawValue;

// Get the value of target form field
var tCustomer = event.target.slave.xfa.form2.page1.First_Name.rawValue;

xfa.form2.page1.First_Name.rawValue = oCustomer;


By Thom Parker   

You are moving in the right direction. What you should do is make the catelog a regular PDF, not a LiveCycle form. It will look and perform better. Then make a separate dynamic XFA form for the order bit, and make it an attachment to the catelog PDF so it travels with it. Code in the catelog can open the LiveCycle form, very much like your idea. Except filling the XFA form is a bit tricky. Code in a PDF is non-privileged. It cannot acquire the document object for the opened file directly. If you have already tried the code you show above, then you will have noticed that "this.slave" is null. The only way for the catelog (or XFA) to acquire the object for the other document is if it is "disclosed". You'll need to add this code to a top level event that is run at document open:

this.disclosed = true;

Disclosure makes the document visible in the Acrobat JavaScript model to non-privileged scripts. It matters not whether the forms are dynamic, static, Acroform, or XFA. Copying data between them is straight forward. You just have to use the correct syntax and access for each form model.

The best method is to put code in the XFA form that acquires the Catelog document object and then copies data out of it. This is the best method because the Catelog is already open and has a valid object. Whereas the XFA is being opened. The validity of it's document object is non deterministic when "app.openDoc()" is called.

Thom Parker
The source for PDF Scripting Info pdfscripting.com
All About PDF Stamps in Acrobat and Paperless Workflows

The Acrobat JavaScript Reference, Use it Early and Often

The most important JavaScript Development tool in Acrobat
The Console Window (Video tutorial)
The Console Window(article)

Having trouble, Why Doesn't my Script Work


Thom Parker   

Hello Thom,
thank you for your answer, it took me awhile to try this and that, but my progress is still poor. I don't want to turn my main file into AcroForm pdf, because I have there some dynamic functionality like hidden pages, and I'm not sure if this can be achieved with AcroForm.

Anyway, if you still follow this question, could you please share with me your opinion on following idea: is there a way to create a script which can do following:

1. User clicks a button within main file (form_a.pdf), which starts the script.
2. Script grabs all the form data and saves it locally in the same folder as .xml or .xpdf (I think XFA forms does not support .fdf format)
3. Then script opens an empty file (form_b.pdf) with the same structure as form_a.pdf and pushes that new .xml or .xpdf file to fill out form_b.pdf with data grabbed from form_a.pdf.
4, (optionally) The .xml (.xpdf) data file is being deleted to clean up the folder (and not create further overwriting issues).

Do you think this is possible at all? Could you give me some ideas on what scripting commands I need to dig to achieve that sentence?

Thank you for all your priceless advices.

Kind regards,
Sergiy.



Sergiy Kotenko   

Acrobat, and especially Reader, is heavily sandboxed. You cannot save a file to the local hard drive without the direct consent of the user. But there are some things you can do. For example, you can have a script open another LiveCycle form. Then scripts in that form would search for catelog document, and copy data out of if it exists. Copying data is simpler than you might think. If both files have the same data hierarchy, then all you need to do is overwrite the data model in the target document with the data model from the source document. Of course, the documents must be "disclosed" for this to work.

You'll find the data model down this path

xfa.data


Thom Parker   

Hello again,
thanks for all your support, I still dig around for a solution, but because I'm really newbie to scripting, I get nothing but challenges even in the easiest questions :)

I realized that "slavery" script I shared in my initial posting does not fit to my needs, because I work on XFA forms, so syntax needs to be updated. I also made very simple forms, with only few static fields, just to make things running. Now my script is almost working, I managed to get the value out of my target form into my source form, and I really need your assistance to make the opposite direction operational (which is basically my main goal). Here is what I have now:

// open target form
event.target.slave = app.openDoc("form_b.pdf", this);event.target.bringToFront();

// Get the value of source form field
var oCustomer = event.target.getField("form1[0].page1[0].First_Name[0]").value;

// Get the value of target form field
var tCustomer = event.target.slave.getField("form2[0].page1[0].First_Name[0]").value;

// Send the values to check fields of source form just to prove I have access to the target form
form1.page1.Check.rawValue = oCustomer;
form1.page1.Check2.rawValue = tCustomer;

// Send the source form value to target form field
xfa.form2[0].page1[0].First_Name[0].rawValue = oCustomer;

now, the last line is my BIGGEST problem (which I'm sure sounds like a joke for you). I tried this and that and all the possible ways and it just doesn't work. Could you please help me to write correct target form field object syntax, so I can finally push the value from the source form to the target form.

Thank you very much!


Sergiy Kotenko   

Hello Thom,

thank you for your reply, I found your tutorials really great and finally I made my script working (you did it actually, but in very educative style :)

First I just copied your script and it was not working, but then I went into Scripting Object Model subject and found out that the root path to reach another DOM model (which in my case is a target form) must start with xfa.form and not just xfa.

So my correct path to access my target form structure is event.target.slave.xfa.form.form2.page1...

And that made the trick. Thanks a lot for your support, I hope I can select all your answers as best ones.

Wishing you all the best and until next time :)

Sergiy.


Sergiy Kotenko   


Please specify a reason: