Interactive stamps
Stamps in Revu are more than simple annotations—they're mini PDF files that can contain form fields and JavaScript. When you apply a stamp to a document, Revu executes any calculation scripts within the stamp, allowing for dynamic behavior and user interaction.
When a stamp is placed on a PDF:
-
Form fields within the stamp become active
-
Calculation scripts execute with event.source.forReal set to true
-
Any dialogs defined in the stamp appear
-
Form fields populate with the collected data
-
The resulting PDF file is flattened as a static stamp annotation on the target PDF
The event.source.forReal property is key—it's only true during stamp placement, allowing your code to distinguish between the initial application and other calculation events.
An interactive stamp consists of two JavaScript components:
-
Document-Level Script: This defines your stamp's configuration and behavior. Users modify this section to customize the stamp for their needs. It includes field definitions, default values, and dialog configurations.
-
Calculation Field Script: A hidden form field with calculation JavaScript that runs when the stamp is applied. This handles dialog creation, user input collection, and field population. Users rarely need to modify this.
The document-level script centers around a builder object that defines what information your stamp collects:
var builder = {
// Text fields that will appear in the dialog
textBoxes: [
{
field: "CheckedBy", // Must match text field name in stamp PDF
description: "Checked by:", // Label shown in dialog
default: function() { return Collab.user; } // Dynamic default
},
{
field: "Date",
description: "Date:",
default: function() {
var curDate = new Date();
return (curDate.getMonth() + 1) + "/" +
curDate.getDate() + "/" +
curDate.getFullYear();
}
},
{
field: "SubmittalNumber",
description: "Submittal #:",
default: function() { return ""; } // Static default
}
],
// Radio button group for status selection
radioGroup: "Status", // Must match radio group name in stamp PDF
radioButtons: [
{ value: "Approved", description: "Approved" },
{ value: "Revise", description: "Revise" },
{ value: "Rejected", description: "Rejected" }
],
radioErrorMsg: "Please select a status"
}
Default values can be static or dynamic. Dynamic defaults are particularly useful:
// Static default
{ field: "Department", description: "Department:", default: function() { return "Engineering"; } }
// Dynamic default using current user
{ field: "Reviewer", description: "Reviewer:", default: function() { return Collab.user; } }
// Dynamic default using current date/time
{ field: "Timestamp", description: "Time:", default: function() {
var now = new Date();
return now.toLocaleTimeString();
} }
One important distinction when working with stamps is understanding the scope:
-
this refers to the stamp PDF itself
-
event.source refers to the field triggering the calculation
-
event.source.source refers to the target document being stamped
This allows stamps to capture information from the document they're being applied to:
var builder = {
textBoxes: [
{
field: "TargetFileName",
description: "Document:",
default: function() {
// Get filename of document being stamped
var path = event.source.source.path;
return path.split("/").pop().split("\\").pop();
}
},
{
field: "PageInfo",
description: "Page:",
default: function() {
var doc = event.source.source;
var currentPage = doc.pageNum + 1;
var totalPages = doc.numPages;
return currentPage + " of " + totalPages;
}
}
]
};
You can include dropdown menus for predefined selections:
var builder = {
// ... other properties ...
popupGroup: "Project", // Must match popup field in stamp PDF
listItems: [{
popupItems: {
"Project Alpha": -1, // -1 means not selected by default
"Project Beta": -1,
"Project Gamma": 1, // 1 means selected by default
"Project Delta": -1
}
}]
}
Use clear, consistent naming for your fields:
-
Use PascalCase: ReviewerName, ApprovalDate
-
Avoid spaces and special characters
-
Match names exactly between JavaScript and PDF form fields
-
Use descriptive names that indicate purpose
// DOCUMENT LEVEL SCRIPT - Customize this for your needs
var builder = {
// Text input fields
textBoxes: [
{
field: "ReviewedBy",
description: "Reviewed by:",
default: function() {
return Collab.user || "Unknown User";
}
},
{
field: "ReviewDate",
description: "Date:",
default: function() {
var curDate = new Date();
return (curDate.getMonth() + 1) + "/" +
curDate.getDate() + "/" +
curDate.getFullYear();
}
},
{
field: "SubmittalNumber",
description: "Submittal #:",
default: function() { return ""; }
},
{
field: "DrawingNumber",
description: "Drawing #:",
default: function() { return ""; }
}
],
// Radio button group for approval status
radioGroup: "ApprovalStatus",
radioButtons: [
{ value: "Approved", description: "Approved as Submitted" },
{ value: "ApprovedAsNoted", description: "Approved as Noted" },
{ value: "ReviseResubmit", description: "Revise and Resubmit" },
{ value: "Rejected", description: "Rejected" }
],
radioErrorMsg: "Please select an approval status",
// Dropdown for discipline
popupGroup: "Discipline",
listItems: [{
popupItems: {
"Architectural": -1,
"Structural": -1,
"Mechanical": -1,
"Electrical": -1,
"Plumbing": -1,
"Civil": -1
}
}]
};
The calculation field script that executes this builder is typically hidden and handles the dialog display and field population automatically.
Fields not populating
Field names in JavaScript don't match PDF form field names exactly. Verify spelling, capitalization, and spacing.
Dialog not appearing
Syntax error in the document-level script. Check the JavaScript console for errors.
Default values not working
Error in default value function. Check the console and ensure all referenced properties exist.
Radio buttons not saving
Radio button export values don't match JavaScript values. Check the "Choice" property of each radio button.
When developing stamps, use these techniques:
// Console logging to trace execution
default: function() {
console.println("Getting user name...");
var userName = Collab.user;
console.println("User name: " + userName);
return userName || "Unknown";
}
// Alert debugging for variable values
app.alert("Current value: " + myVariable);
// Verify fields exist
var field = this.getField("MyFieldName");
if (!field) {
console.println("Field not found: MyFieldName");
}
Summary
Interactive stamps provide a powerful way to standardize data collection in your PDF workflows. Remember:
-
Field names must match exactly between JavaScript and PDF
-
Use event.source.source to access the target document
-
The document-level script is what users customize
-
Test thoroughly before deployment
Resources
Revu 21
Revu JavaScript
JavaScript
