Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.

How Stamps Execute

When a stamp is placed on a PDF:

  1. Form fields within the stamp become active
  2. Calculation scripts execute with event.source.forReal set to true
  3. Any dialogs defined in the stamp appear
  4. Form fields populate with the collected data
  5. 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.

Stamp Architecture

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 Builder Object

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"
}

Critical: Every field referenced in JavaScript must have a corresponding form field in the stamp PDF with an exactly matching name. If these don't match, the stamp won't populate correctly.

Default Value Functions

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();
} }

Accessing the Target Document

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;
            } 
        }
    ]
};

Adding Dropdowns

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
        }
    }]
}

Field Naming Requirements

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

Complete Working Example

Here's a complete engineering review stamp that demonstrates the key concepts:

// 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.

Common Issues and Solutions

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.

Debugging Stamps

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