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

invoking pdf javascript code from servlet FDF response

adoacr
Registered: May 4 2011
Posts: 41
Answered

Hi,
 
I want to invoke client(pdf) side javascript from a servlet when a user
submits a form. I am sending the servlet response in FDF format. How do I execute
this javascript on the client side from the servlet?
 
Thanks in advance

thomp
Expert
Registered: Feb 15 2006
Posts: 4411
The FDF spec includes before and after scripts that are included in the FDF and executed before data is loaded into the PDF and after data is loaded into the PDF. Do you have the FDF Spec?

There are however some security restrictions on delivering FDF content to a PDF. For example, both need to be in the same domain. Or the PDF needs to specify a cross domain file that allows the FDF.

Here's a simple example

%FDF-1.2
1 0 obj
<</FDF
<<
/Fields [<</T (ImportRslt) /V (JSTest.fdf Imported)>>]
/JavaScript <</Before (console.println("Before Import Script");)>>
>>
>>
endobj
trailer << /Root 1 0 R >>
%%EOF


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

adoacr
Registered: May 4 2011
Posts: 41
so, for example, I want to remove Watermarks from a pdf in response to a form submission. The javascript would look something like this. How Do I make this part of the FDF response. Im not very familiar with the FDF spec. :

function SetWatermarkState(doc, bState) {
/* set the "Watermark" to bState for doc
doc - doc object to process
bState - value for logical state
true = show
false = hide
*/

var ocgArray = doc.getOCGs();
for (var i=0; i < ocgArray.length; i++) {
if (ocgArray[i].name == "Watermark") {
ocgArray[i].state = bState;
} // end if Watermark
} // end loop through the OCG object
return;
} // end SetWatermarkState function

SetWatermarkState(this, false);

adoacr
Registered: May 4 2011
Posts: 41
How do I get the reference of the doc object in the response... or is there some way to just send the js script file down to the pdf or embed the js in the pdf at the time of pdf creation itself?...
maxwyss
Registered: Jul 25 2006
Posts: 255
If you know in advance that you will use the script, you could define it as a function in a document-level script. And then, all you would have to do in the FDF is calling the function. (and that's even simpler than the example given above).

On the other hand, you would send the code to be executed, in the way given in the example; just look at it as one string, which means that you may have to encode line breaks etc.

However, in order to properly debug your FDF, you will not get around to learn more about it. In my experience, it can sometimes be a little bit tricky, and therefore, you simply have to understand it. It is a good idea to practice…

Hope this can help.

Max Wyss.

thomp
Expert
Registered: Feb 15 2006
Posts: 4411
Max has a good idea, put the function you'll need as a document level script. This makes constructing the FDF much easier. The Doc object should be "this", since the FDF is in the context of the current document.

If the FDF is a direct response to a submit from the PDF then no reference to the doc is needed. Acrobat knows to apply the FDF to the PDF.

To get a feel for how FDFs are constructed, export one from Acrobat. And Read the spec of course.

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

gkaiseril
Online
Expert
Registered: Feb 23 2006
Posts: 4307

George Kaiser

adoacr
Registered: May 4 2011
Posts: 41
ok, i added the javascript to my pdf programatically, but the FDF servlet respnonse from the servlet throws a 'general error' on the pdf... and says the file is damaged and cannot be repaired. think the issue may be more to do with the FDF response Im sending, though need to find out whats wrong. my servlet response looks like this :
StringBuilder sbFDF = new StringBuilder( 200 );
sbFDF.append( "%FDF-1.2\n" );
sbFDF.append( "1 0 obj\n" );
sbFDF.append( "<<\n" );
sbFDF.append( "/FDF\n" );
sbFDF.append( "<<\n" );
sbFDF.append( "/JavaScript << /After (SetOCGState(this, false);)");
sbFDF.append( ">>\n" );
sbFDF.append( ">>\n" );
sbFDF.append( "endobj\n" );
sbFDF.append( "trailer\n" );
sbFDF.append( "<<\n" );
sbFDF.append( "/Root 1 0 R\n" );
sbFDF.append( ">>\n" );
sbFDF.append( "%%EOF" );
return sbFDF.toString();

The javascript method is called SetOCGState and is added as below:
function SetOCGState(doc, bState) {
var ocgArray = doc.getOCGs();
for (var i=0; i < ocgArray.length; i++) {
if (ocgArray[i].name == "OCG1") {
ocgArray[i].state = bState;
} // end if Watermark
} // end loop through the OCG object
return;

any ideas?
maxwyss
Registered: Jul 25 2006
Posts: 255
Accepted Answer
Try to manually create the FDF, and test it. When it works correctly, recreate it with your server script and manually test the result; compare it with what you have created beforehand.

You might also use \r instead of \n.

Hope this can help.

Max Wyss.

adoacr
Registered: May 4 2011
Posts: 41
how do i test out the FDF in this case? since it dosent result in a pdf in itself but is rather a response object being sent to the pdf to trigger a javascript?
maxwyss
Registered: Jul 25 2006
Posts: 255
Your FDF needs a base PDF to be fed into. So, you create it, and load it into the base PDF you are using.

So, you import the FDF into the target document, as if you would import form data, or comments. Note: there are Acrobat versions which refuse to import form data, if there is no form field present, you'd have to add a dummy text field, and then, the Import Data menu item becomes active.

Hope this can help.

Max Wyss.

George_Johnson
Expert
Registered: Jul 6 2008
Posts: 1875
To test, you can create a sample FDF and manually import it into the form locally in Acrobat. But you're missing a closing double bracket. The code should be:

sbFDF.append( "%FDF-1.2\n" );
sbFDF.append( "1 0 obj\n" );
sbFDF.append( "<<\n" );
sbFDF.append( "/FDF\n" );
sbFDF.append( "<<\n" );
sbFDF.append( "/JavaScript << /After (SetOCGState(this, false);)");
sbFDF.append( ">>\n" );
sbFDF.append( ">>\n" );
sbFDF.append( ">>\n" );
sbFDF.append( "endobj\n" );
sbFDF.append( "trailer\n" );
sbFDF.append( "<<\n" );
sbFDF.append( "/Root 1 0 R\n" );
sbFDF.append( ">>\n" );
sbFDF.append( "%%EOF" );
return sbFDF.toString();
adoacr
Registered: May 4 2011
Posts: 41
thanks folks. that worked