These forums are now Read Only. If you have an Acrobat question, ask questions and get help from one of our experts.

Another Software Purchase Necessary?

cyanstudios
Registered: May 6 2008
Posts: 81
Answered

Well I thought I had researched everything that's necessary to make a .PDF interface with a database and provide end user interaction thoroughly, so I developed a very interactive time sheet form for employee entry. After all that development and testing, I've found that getting this form to populate the correct fields with our ODBC and face this data to the internet, I'm going to need new software.

LiveCycle Reader Extensions. Is this true? Every last thing that I need this form to do in Reader is covered in Acrobat Pro's functionality except display of ODBC connection values.

I'm sorry if this turns out to be a really basic question, but it wasn't really that clear in the documentation.

My Product Information:
LiveCycle Designer, Windows
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
No, its not necessarily true.

You do need special rights to write data from Reader to a "local" database using Acrobat's ODBC access features. But most people don't use a local DB, they use a server DB like MySQL. In this case you submit data to a server script which then handles the DB access. There's no reason that you couldn't use a local network server to handle the DB transactions.

Thom Parker
The source for PDF Scripting Info
[url=http://www.pdfScripting.com]pdfscripting.com[/url]

The Acrobat JavaScript Reference, Use it Early and Often
[url=http://www.adobe.com/devnet/acrobat/javascript.php]http://www.adobe.com/devnet/acrobat/javascript.php[/url]

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

cyanstudios
Registered: May 6 2008
Posts: 81
"You do need special rights to write data from Reader to a "local" database using Acrobat's .."
Yes but this form imports data from the DB at runtime. Writing to the database, I could do with PHP and understand that fully. Pulling IN from the DB is another story.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
You can pull data into the form from a remote DB at runtime in the same way that it's submitted to the DB, i.e., using a submitForm(). You can use this function to send The PHP script a custom XML that tells the script what to do. Then the PHP places the return data in the body of the HTTP Repsonse in a format that Acrobat recognizes. Acrobat will merge the data back into the PDF.

Search around for the "submitForm" function. You'll find plenty.

Thom Parker
The source for PDF Scripting Info
[url=http://www.pdfScripting.com]pdfscripting.com[/url]

The Acrobat JavaScript Reference, Use it Early and Often
[url=http://www.adobe.com/devnet/acrobat/javascript.php]http://www.adobe.com/devnet/acrobat/javascript.php[/url]

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

cyanstudios
Registered: May 6 2008
Posts: 81
The form will be located on a local server and the connection is now ODBC, an SQL db. We'll share the form to the web. We can host it remotely also, but migration of the SQL db values to the web would be a task of its own.

So as far as the submitForm function goes, I think I understand that it's rudimentary use is to take data in the form and hand it over to a versatile language like CGI or PHP. So if we have drop downs that are to be populated by the db, in the initialize event on the drop down, I use a submitForm function, the data goes to PHP and PHP sends back a response as to what values to put in?

If that's the case, I understand submitForm fine enough, but I'm not sure what to have the script say, how to have it indicate what the values are for the right fields, and how to have PHP actually do the responding. Are there any examples of the scripting side of this that I can be led to, tutorials, or explanations? The API doesn't appear to outline this and for once, Google is failing me. I've tried every search string, lol.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
Unfortunately there's not really any general info on this topic. For one thing it cuts across a lot of boundaries. It's not really Acrobat or LiveCycle programming.

But the basic idea is that any data format that Acrobat recognizes will be incorporated into the current form.

As a simple example do this:
1. Make a very simple form in LC Designer, 3 fields.
2. In Acrobat Pro, export the form data as XDP
3. Open the XDP in a plain text editor (or XML editor if you have one)
4. Modify some of the exported data values.
5. Delete the PDF File reference, including all associated tags
3. Import the XDP back into the PDF.

You'll see the data values in the form change to what ever you made them in the XDP.

The XDP is a data format that's recognized by Acrobat. This is exactly what you're PHP script would place in the HTTP Response body. And of course the MIME type has to be set properly in the header.

If you want to populate list items it gets more complicated. There are several ways to do this. Which way you go depends on your comfort level for programming the XFA and the complexity of the form. The easy way is to simply return the list items to a hidden text field and then copy them over to the actual list. But before you can do this you've got to be comfortable with the Submit/Response mechanism for the PHP.

Thom Parker
The source for PDF Scripting Info
[url=http://www.pdfScripting.com]pdfscripting.com[/url]

The Acrobat JavaScript Reference, Use it Early and Often
[url=http://www.adobe.com/devnet/acrobat/javascript.php]http://www.adobe.com/devnet/acrobat/javascript.php[/url]

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

cyanstudios
Registered: May 6 2008
Posts: 81
Alright, so to try to nail this functionality, I have XAMPP helping me run the PHP client side with the ODBC Connection, so here goes.

I've made a new PDF and placed a list box in there, multi line capable. In the initialize event, I've placed the following in Javascript per the API:
var aSubmitFields = new Array( "first", "last" );this.submitForm({cURL: "http://localhost/phptest.php#FDF",aFields: aSubmitFields,cSubmitAs: "FDF" // the default, not needed here});

This "phptest.php" file does work in the browser and shows the correct values in the database, table "PREmployees", records "fname", "lname", and "empl" (id). Now, what it says is:
<html><body><?php$conn=odbc_connect('dbname','username','password');if (!$conn){exit("Connection Failed: " . $conn);}$sql="SELECT fname, lname, empl FROM PREmployees";$rs=odbc_exec($conn,$sql);if (!$rs){exit("Error in SQL");}echo '<items>';while (odbc_fetch_row($rs)){$first=odbc_result($rs,"fname");$last=odbc_result($rs,"lname"); echo '<text> ' . $first . ' ' . $last . ' </text>';}echo '</items>';echo '<items save="1" presence="hidden">';while (odbc_fetch_row($rs)){$empid=odbc_result($rs,"empl"); echo '<text> ' . $empid . ' </text>';}echo '</items>';odbc_close($conn);?></body></html>

As you can see, I'm just trying to generate code for that specific field, or am I to be generating code for the entire XDP? I've tried doing this before and it seemed like no matter how close I matched the xml schema of the source xdp document, it wouldn't actually render as a .pdf. Let me know if I should pursue that.

If I am going the right way with what I've done, I'm pretty sure it's showing nothing because of something to do with the MIME type you brought up. Is that MIME type placed in the header of the php or the code generated by the php?

Thank you again for your help Thom.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
The MIME type goes in the header, or Acrobat won't recognize it. The entire XDP format has to be returned to Acrobat, or again, Acrobat won't recognize it. And there is another issue with LiveCycle forms. LiveCycle forms are displayed in Acrobat by merging the Data model with the Form template. Unless explicitly specified, the data model is composed of all fields with normal binding. Any data thats in the data model, that is not specified by the returned XDP is considered empty and defaulted. So, you're returned XDP must specifiy every bound piece of data in your form. Not just the ones you want filled in. Otherwise the unspecified fields will be cleared.

Just as a sanity check, try returning an XDP that's was exported directly out of Acrobat. Return it verbatim to Acrobat, and remember to set the MIME type.

And another thing. If you are using a LiveCycle document, the submit code above won't work. That code is for an AcroForm PDF. For live cycle you need this.

var aSubmitFields = new Array( "first", "last" );event.target.submitForm({cURL: "http://localhost/phptest.php#FDF",aFields: aSubmitFields,cSubmitAs: "FDF" // the default, not needed here});

It looks like you are making progress. It's just a matter of figuring out the details. I've written tons of server scripts for doing similar tasks in PHP, ASP.NET, and Java. The two most important things to making it work are getting the data format right and setting the mime type.

Thom Parker
The source for PDF Scripting Info
[url=http://www.pdfScripting.com]pdfscripting.com[/url]

The Acrobat JavaScript Reference, Use it Early and Often
[url=http://www.adobe.com/devnet/acrobat/javascript.php]http://www.adobe.com/devnet/acrobat/javascript.php[/url]

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

cyanstudios
Registered: May 6 2008
Posts: 81
I have to admit that I am finding it a little tough to get a good and clean write up on how to begin this process, though I've tried a few things of my own from the bottom up, but I'm pretty sure the flaws are so numerous that it will take forever to refine it.

Is there a class, book, or something similar I can sign up for/purchase? I really like the LiveCycle vision and want to get it down so that I'm answering more questions here than asking.

In the meantime, I've come across a few tutorials, and I'm curious if you think these methods, tweaked a little, will work.
http://www.andrewheiss.com/Tutorials?page=LiveCycle_PDFs_and_MySQL

Right now I'm actually not concerned with outputting to the database with what the user inputs. Just receiving database values in the first place for the form. So if I start from the segment he titles "PDF Madness", it does appear that this could be a good starting point, except that from what I see, the user is directed straight away to the php script that makes the FDF and then merges it into the actual PDF.

This isn't exactly what you are suggesting, but if it will work, I at least have a roadmap using this method. I've seen this similar method done again with example files here

http://accesspdf.com/html_pdf_form/

But there's really no walk through like Andrew's.

Anyway, I'm going to begin working on trying to make this method work for the purpose, but if you have insight (such as maybe the pdftk isn't going to work with newer versions, or there's a liability I'm not picking up on) please let me know.

The only reason I'm leaning this way is because there's something to backwards engineer, study, and learn from, so if your method has any examples I can dissect and work backward from, that would be, as the French say, "So cool".

I appreciate your help Thom.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
This is very good stuff and should give you some good ideas about what you need to do.

However, I would caution against using FDF to populate an XFA form directly. There are a few of issues. First, FDF doesn't support data for repeated fields, Second, the name syntax in for XFA fields is very awkward for FDF. XFA also likes to use Unicode names, which is also awkward, but there is a way around it. And third, Acrobat merges FDF directly into the form fields (which is why you need the funky field naming), it completely bypasses the XFA data model. This has the potential to cause data loss and operational problems on the form.

FDF is fantastic if you want to pass some JavaScript into an XFA form, but if its straight data, then I'd stick with XDP as the data format.

The method outlined by Andrew Heiss is for merging the data into the PDF on the server side. Pdftk is mainly for working with regular AcroForms, but the technique should work for a Static XFA form, although I'm not sure, and of course Pdftk has some reported problems with Acrobat 7 PDFs.

I think this is a dead end solution. It's so much easier to merge the data on the client side by just passing an XDP back to Acrobat from the server.

As for resources, there are only two organized resources for PDF scripting, and nothing that I know of for PDF server side data handling. The two resources are www.pdfscripting.com and www.adobe.com/devnet. pdfscripting.com will have LiveCycle scripting tutorials and samples up before the end of January, and data handling materials will be added some time in the summer. But what you've already found on the web is about it for now.

Cheers,
Thom Parker
The source for PDF Scripting Info
[url=http://www.pdfScripting.com]pdfscripting.com[/url]

The Acrobat JavaScript Reference, Use it Early and Often
[url=http://www.adobe.com/devnet/acrobat/javascript.php]http://www.adobe.com/devnet/acrobat/javascript.php[/url]

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

cyanstudios
Registered: May 6 2008
Posts: 81
Oh, yeah I did fail to mention that the idea was to instead generate information XDP wise in a similar fashion to how he generated FDF, but it appears I'll have some monstrous editing of the forge_fdf.php file. Sounds like more work than necessary also.

Well maybe once I get this done, I can write up something to explain how I did what I did. Or, as a web site host and designer, take some matters into my own hands and maybe get an unaffiliated resource going. The possibilities with this stuff is really cool, just seems a little documentation could go a long way.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
I think you are making this much more difficult that it needs to be. I've written very short PHP scripts, with no external libraries that accept and return data from/to a PDF. Your first php script above is very close. All you need to do is include the full XDP format in the return data, and set the MIME type.

Follow my previous suggestion of testing this out by returning an XDP that was exported directly from a simple form.


Thom Parker
The source for PDF Scripting Info
[url=http://www.pdfScripting.com]pdfscripting.com[/url]

The Acrobat JavaScript Reference, Use it Early and Often
[url=http://www.adobe.com/devnet/acrobat/javascript.php]http://www.adobe.com/devnet/acrobat/javascript.php[/url]

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

cyanstudios
Registered: May 6 2008
Posts: 81
Well here's how far I got with what you're suggesting.

It's a simple form with two rectangles and one drop down list. I know that the drop down list will cause some problems, and I would probably be better off using a textbox for now, but at the time this was as apparent to me.

There's also one button to click to execute this event:
var aSubmitFields = new Array( "first", "last" );event.target.submitForm({cURL: "http://localhost/parse.php#FDF",aFields: aSubmitFields,cSubmitAs: "FDF"});

As you suggested, and this did take one step farther. However, here are two text files for the code in my php files in htdocs.

One was an attempt at following syntax per some posts I read [url=http://www.adobeforums.com/webx/.59b67d7e]like this fellow did[/url].

http://www.cyan-studios.net/posted_parse.txt

In tweaking this around a few ways, I was able to manage to get this submit to try opening something in Reader, but it had no idea what to do with it, so it ended up being just Reader with a dark gray background.

The next is what I got from following your suggestion as best as I could apply it. I know you'll open it up and recognize something I did real fast though.

http://www.cyan-studios.net/posted_parse_mime.txt

This one was more successful in that I saw a huge block of text that was the values that I was calling for from the database, but it was flat HTML and not viewing through reader. I also see that in my first example, there are some calls to data and datasets that I do not see in the XDP template that I get from LCD. Nor does it attempt to reference the PDF file in htdocs, which I'm betting I need to work in there somewhere.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
First, "cSubmitAs" on the submitForm() function should be set to "XDP.

Next, both of the scripts you've posted start and end with HTML tags, this is very bad because this is text that shows up in body of the HTTPResponse. The content of the body has to be purely XDP. Also the MIME type has to the in the Header info in the HTTP Response Packet, not in an HTML header.

Here's some simple code that returns FDF to Acrobat.
<?php$thePost = $HTTP_RAW_POST_DATA; $FDFBuff = "%FDF-1.21 0 obj

<</FDF<</Fields [<</T (Name) /V (JSTest.fdf Imported)>> <</T (company) /V ($thePost)>>]/JavaScript

<</Before (app.alert('Hello World');)

>>>>>>endobj

trailer << /Root 1 0 R >>%%EOF"
;$len = strlen($FDFBuff) + 1;header('Content-Type: application/vnd.fdf');echo $FDFBuff;?>

Notice that it's purely PHP code, there's nothing else. And only the single echo at the bottom. I think the first file, "posted_parse.txt" will work just fine if you removed the HTML tags and set the content type properly.

Also, if the PDF is already open in Acrobat then there is no need for a file reference and the "pdf" tag should be removed. However, if this script is a link from an HTML page, then you will need the "pdf" tag.

Thom Parker
The source for PDF Scripting Info
[url=http://www.pdfScripting.com]pdfscripting.com[/url]

The Acrobat JavaScript Reference, Use it Early and Often
[url=http://www.adobe.com/devnet/acrobat/javascript.php]http://www.adobe.com/devnet/acrobat/javascript.php[/url]

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

cyanstudios
Registered: May 6 2008
Posts: 81
This is really close. The submitas is switched to XDP. I considered that but there seem to be places in these processes where FDF is left in, perhaps residually from acroform adaptations? Sorry for that.

I've changed the field that I'm trying to populate to a simple text field, not being fed by a database for now, but just trying to populate it with a concretely defined value in php.

For object model laziness reasons, I left its name "drop1". Here is the code I have for the php.

Now, the php I have written now looks like this:
<?php$thePost = $HTTP_RAW_POST_DATA;$xdpStr = '<?xml version="1.0" encoding="UTF-8"?><?xfa generator="AdobeLiveCycleDesignerES_V8.2.1.3144.1.471865" APIVersion="2.8.8118.0"?><xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/"><xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/"><xfa:data><subform name="form1"><subform name="p1"><field name="drop1"><caption><value><text>caption</text></value></caption><value><text>test</text></value></field></subform></subform></xfa:data></xfa:datasets></xdp:xdp>';header('Content-Type: application/vnd.adobe.xdp+xml');echo $xdpStr;?>

Is there a reason for the +1 to the string, and do I need it for this application? I left that out, and it doesn't seem to make a difference if I add it in.

If I click the submit button from Firefox-Reader, it says "Transferring data from localhost" but never achieves anything. Nothing populates.

If I add in
<pdf href='http://localhost/parsetest2.pdf' xmlns='http://ns.adobe.com/xdp/pdf/'/>
before closing the xdp, then try going to the php first, it leads to the pdf, obviously, but no values inserted there either.

Conceptually, I think you've almost helped me get there. Is there anything else that could be messing up? I'm going through and trying a lot of different things but nothing is really changing much.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
I don't think the XFA dataset gramar is correct. The easiest way to check this is export data from your from using the "Form->Manage Form Data->Export Data..." menu item. The data that your form recieves has to match the gramar in the exported XFD exactly.Thom Parker
The source for PDF Scripting Info
[url=http://www.pdfScripting.com]pdfscripting.com[/url]

The Acrobat JavaScript Reference, Use it Early and Often
[url=http://www.adobe.com/devnet/acrobat/javascript.php]http://www.adobe.com/devnet/acrobat/javascript.php[/url]

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

cyanstudios
Registered: May 6 2008
Posts: 81
I've been exporting XML different this whole time, no wonder I couldn't nail the schema. This works choice, especially coupled with [url=http://groups.google.com/group/livecycle/browse_thread/thread/7969bb47722e08bf/07a4c2dbb449c5e5]this response from Justin Klei[/url] for anyone wanting to do, as Thom said, a hidden box that has comma delimited values that automatically populates the drop down.

The one last thing I need is to get the drop down list items to have bound values that are also coming from the database, since an employee will choose his/her name, and the actual value will be their employee ID.

I suspect I need to go into the change event of the drop down, make another hidden comma delimited text field "valnum", and do something like
var vChoice = valnum.rawValue;if (vChoice == null) vChoice = ""; if (vChoice.length > 0) { var astrChoiceNum;var numericvals; drop1.clearItems; astrChoiceNum = valnum.rawValue; numericvals = astrChoiceNum.split(",");var numnumericvals = numericvals.length; for (var i = 0; i < numnumericvals; i++){drop1.boundItem(numericvals[i], numericvals[i]);} if (numnumericvals > 0){drop1.boundItem = numericvals[0];}}

Something like that. If you get the time, that'd be nice, Thom, but I've used a lot of your time and you've more than gracious and also awesome. I can't tell you how badly I've wanted to accomplish this for a long time.

I'll update if I find the answer to this last small thing for the Googlers out there.
cyanstudios
Registered: May 6 2008
Posts: 81
Well, for now what it does, is in the PHP file, it takes the first and last names, then concatenates the employee number to the end of the string also that will go into the drop down.

Since I need a field that will show the employee number, I am using JS string methods to trail back 4 characters, since every employee ID is 4 characters, and it reports that.

This will work for now, hoping for something a little more solid, but it's good enough for now.

Cheers.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
Excellent!! Congrats on getting it to work. I think you're over the hump.

Here's an article (in two parts) that shows several different ways to handle list data.

http://www.acrobatusers.com/tutorials/2007/js_list_combo_livecycle/

Thom Parker
The source for PDF Scripting Info
[url=http://www.pdfScripting.com]pdfscripting.com[/url]

The Acrobat JavaScript Reference, Use it Early and Often
[url=http://www.adobe.com/devnet/acrobat/javascript.php]http://www.adobe.com/devnet/acrobat/javascript.php[/url]

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

cyanstudios
Registered: May 6 2008
Posts: 81
Just as a follow up for anyone that Googles this in the future:
I created another hidden text box that takes any other record that I want to bind in the drop down then I use the following code in the form:ready or initialize events. Initialize for any drop down that's generated dynamically.
var textFeed = insert structure pointing to hidden text box for catching text valuesvar valFeed = insert structure pointing to hidden text box for catching bound valuesvar sChoice = textFeed.rawValue;var sVal = valFeed.rawValue;if (sChoice == null) sChoice = "";if (sVal == null) sVal = ""; if (sChoice.length > 0) {// Set the contents of this drop-down list box// equal to list in the text value text box.// This is required when the form is opened for the very// first time. // Populate action list array from the comma delimited stringvar astrChoiceList;var astrValList;var choices;var Vals // Clear drop-down list boxthis.clearItems(); astrChoiceList = textFeed.rawValue;astrValList = valFeed.rawValue; // add each choice to thischoices = astrChoiceList.split(",");Vals = astrValList.split(",");var numchoices = choices.length; for (var i = 0; i < numchoices; i++){this.addItem(choices[i], Vals[i]);} // Automatically select the first item// only if the array is not emptyif (numchoices > 0){this.rawValue = choices[0];drop.value = Vals[0];}}

this.addItem(choices[i], Vals[i]);
note that I just replaced choices[i] for the bound value.

This doesn't totally employ the methods you have in that article, Thom, but it accomplishes what we need with minimal brain damage.

Everything I needed accomplished is done here! You have no idea how appreciative I am Thom, I mean that.