Step 1: Check us out

You don't have to be a member to look at any content on the site. Increase your expertise with our helpful tutorials, videos, forums, and sample PDFs.

Step 2: Sign up for a free account

Like what you see? Take the next step and become a member. Register now to get discounts, attend eSeminars, ask questions and more.

Step 3: Start participating

Get the most out of your membership. Post in the forums, create your profile, submit to the gallery, attend a user group meeting. Log In now.

Dynamic Stamp Secrets

Scope: Acrobat 7.0 and later

Skill Level: Intermediate and Advanced

Prerequisites: Familiar with Acrobat JavaScript and Stamps

So you’ve finally figured out how to create a custom dynamic stamp for Acrobat. But after all that hard work, what seemed like days of slogging through molasses, it still doesn’t do what it’s supposed to and your boss is getting impatient. There are three things yet to be done. The stamp needs to display the filename of the document on which it is being placed, it needs to ask the user for some state information (i.e., approved, rejected and so on), and it needs to write this information and a date into the document metadata. This is crazy! Documentation on dynamic stamps is already hard enough to come by. But there’s nothing anywhere about how to do these tasks. Take heart! There is a solution. 

Building a dynamic stamp

Before getting into the advanced details, let’s review some dynamic-stamp basics (full dynamic-stamp tutorial). A dynamic stamp is created by adding form fields to an existing stamp file. It doesn’t count if the fields are added to the original PDF that is turned into a stamp. Those fields are flattened out when the stamp file is created. They have to be added after the stamp is created. The stamp files live in two different folders on your hard drive. You can find out where these folder are by executing the following lines of code in the JavaScript Console:

app.getPath ("app", "stamps");

app.getPath ("user", "stamps");

Results shown below in Figure 1.

Figure 1 – Acrobat Stamp Folders

Zoom imageSee larger image

A stamp file is a regular PDF in which Acrobat has added some special information. Acrobat automatically generates stamp files and gives them very cryptic names, so you’ll have to look through all of them to find the one that contains your stamps. Once you find it, you can change the filename to something more descriptive. This is a good practice to have anyway. Renaming your stamp files makes it easier to keep track of them.  

To make the stamp dynamic, at least one of the added form fields must have a calculation script. When Acrobat displays the stamp on the menu or places the stamp on a document, it calls the calculation scripts on the stamp. If the calculation script changes the value of the field, then it is followed by a format event. The Validate and Keystroke events are not reliable, so don’t use them.

These events all occur in the context of the stamp file, i.e., the this object is the doc object of the stamp file. To demonstrate, place the following line of code in the calculation script for a field on your dynamic stamp:

event.value = this.documentFileName;

When you place the stamp on a PDF, it will display the name of the stamp file, not the name of the file on which the stamp is placed.

Limitations

There is only one serious limitation to a dynamic-stamp script. Stamp files do not execute JavaScript like a normal PDF file. For example, there are no document or page events. Variables and functions cannot be defined in a document script. The only scripts guaranteed to execute are the calculation scripts of the fields placed on the stamp. Everything necessary to execute this script must be present in the script.

Another, less-important limitation is that the event.rc value is meaningless in a dynamic stamp calculation script.   It doesn’t block the field from acquiring the assigned value as it would in a normal calculation script.

Privileges

Acrobat grants dynamic stamp scripts a small amount of privilege. They are able to access the identity object, which is normally off limits to scripts in a PDF. The identity object contains the same user information listed in the Identity panel in Acrobat’s Preferences. However, dynamic stamp scripts are not fully privileged, so they cannot use other secure Acrobat properties and functions, i.e., anything in the Acrobat JavaScript Reference marked with a red (S) in the Rights Bar.

Figure 2 – Identity Object Entry from the Acrobat JavaScript Reference

Zoom imageSee larger image



Dynamic scripts can call functions defined in a Folder-level script, so if you need some privileged code for your stamp, you can always place it in an external script file.

The secrets

Now, down to business. In the introduction, our intrepid PDF developer was directed to implement three seemingly impossible dynamic-stamp features. 

  1. Display the name of the file (onto which the stamp is being placed) onto the stamp.
  2. Ask the user to choose some document state text to display on the stamp.

    (Approved, Rejected or In Process)
  3. Write the document state info and a date into the document metadata.

Features 1 and 3 require access to the document being stamped. We can’t use the this keyword because the dynamic-stamp script is in the context of the stamp file and we can’t use the app.activeDocs property because a document has to be disclosed before it shows up on the list. There are some other possible coding solutions, but they are all awkward and pose problems with version compatibility.

This issue seems impossible, but fortunately Acrobat JavaScript provides us with a solution. For dynamic-stamp scripts, the event.source property is an object containing several useful parameters, one of which is the Doc Object for the PDF being stamped,  event.source.source. Use the following code to get the file name for the “source” PDF:

event.value = event.source.source.documentFileName;

To write a value into the document’s metadata, use this code:

var cDate = util.printd("mm/dd/yyyy", new Date());

event.source.source.info.StampInfo = "Rejected:" + cDate;

That takes care of issues 1 and 3. For feature 2, we can simply use app.response() to ask the user for a simple string. But there are a couple problems. The calculate script is called in two different situations: when it is shown on the menu, as well as when it is actually being placed on the document. We only want the popup to be displayed when the stamp is being placed on the document. To further complicate this, all calculation scripts on the stamp file are called at once, not just the ones on the particular stamp in use. So how do we tell the difference between these situations? 

Again, event.source comes to the rescue. In this case, we use the event.source.forReal and event.source.stampName properties. The forReal property is true when the stamp is being placed on the document and false at all other times. The stampName property uniquely identifies the stamp in use. The trick for using the stampName property is getting the stamp’s name in the first place so we can write the script. Use the following code the first time you create the dynamic stamp:

event.value = event.source.stampName;

console.println("Stamp Name: " + event.source.stampName);

This short script displays the internal name of the dynamic stamp on the stamp, and in the JavaScript Console. Copy the name to the clipboard from the console to use in the final dynamic stamp script. For example:

if( event.source.forReal && (event.source.stampName == "#UdzyXagRctZoS5p43TZ43C")) event.value = app.response();




Putting it all together

Let’s soup up the code a little and lay it out for specific implementation. Our stamp needs two fields:  one on which to place PDF file name and one on which to place the user entered value. 



Calculation (Dynamic) Script for Document Name Field

event.value = event.source.source.documentFileName;


Calculation (Dynamic) Script for User Data Field

(this is also the same script that will set metadata)

var cAsk =  "Enter One of: Approved, Rejected, or In Process " ;

var cTitle =  "Document State For Stamp  ";

if(event.source.forReal && (event.source.stampName == "#UdzyXagRctZoS5p43TZ43C "))
{

var cMsg = app.response(cAsk, cTitle);
cMsg +=  " :  " + util.printd( "mm/dd/yyyy ", new Date());
event.value = cMsg;
      event.source.source.info.DocumentState = cMsg;
}




That’s all there is to it. Here’s what the stamp and popup response box look like:

Figure 3 – User input response box and resulting stamp 



All code is presented in the example stamp file below, which will operate on either Acrobat 7 or 8. To use these stamps, place the file in one of Acrobat’s stamp folders. “Secrets Examples” should instantly appear on your Stamps menu.

Stamp Secrets Sample

Download [PDF: 91 KB]  



Good Stamping!



Comments

add new comment

RE: How to access the Annotation Properties from the Java Script

At the time the dynamic stamp code is run, the stamp has not yet been created so there is not way to access it's properties from the stamp code. The "event.source.source" property refers to the document object of the PDF being stamped.

If you want to fill in this information you'll need a different approach. For example, use a folder level automation script to place the stamp and then fill in the author info.

The reason the article is called "Dynamic Stamp Secrets is because forReal and stampName properties are not documented anywhere.

-

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.html]http://www.adobe.com/devnet/acro

How to access the Annotation Properties from the Java Script ?

Great instructions and examples !

How can I access the Annotation Properties and methods from the Java Script ?

I tried serveral way but I don't get it. I also can't find references in manuals for forReal and stampName.

I would like to fill in values for the author and the subject properties from the java Script at stamp instance creation time.

My attempts so far:
var cAsk = "Enter the name of the Printer " ;

var cTitle = "Printer Name ";

// For debugging: Display StampName Value in Java Console (CTRL-J)
// event.value = event.source.stampName;
// console.println("Stamp Name: " + event.source.stampName);
console.println("");
console.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");

if(event.source.forReal && (event.source.stampName == "#zEc19aw-fN1IcVUEI9-3rA"))
{
console.println("Author: " + event.source.source.author);

var cMsg = app.response(cAsk, cTitle);

// Update value in this text field (Only on Create)
event.value = cMsg;

// Update author field in general stamp properties
//
//This line alters the author fiels in the main document, this was not intended.
//event.source.source.author = cMsg;

console.println("Author: " + event.source.source.author);

//ERROR:event.source.stampName.setProps is not a function
//event.source.setProps({author: "test string"});

//ERROR:event.source.stampName.setProps is not a function
//event.source.stampName.setProps({author: "test string"});

//ERROR:this.setProps is not a function
//this.setProps({author: "test string"});

console.println("");
}

Acrobat Job Board

Looking for a job or seeking to fill a job? Check out the new Acrobat job board.

Job board >

Tech Talks

Go deeper into Acrobat through a new series of informal technical talks by Acrobat experts.

Tech Talks >

Membership

Sign up for your free membership today and save up to 40% on books, training, and more.

Join for free >