# # Action

## # Concept Overview

PDF "Action" is a type of instruction that can be automatically executed when specific events occur, such as opening a document, clicking a link, or interacting with a form. Actions can enable functionalities like page navigation, form submission, script execution, and file operations, significantly enhancing the interactivity and automation capabilities of PDFs.

Actions are divided into two main categories:

- Action: Introduced in PDF 1.1. Actions can be bound to the A entry in the dictionary of objects such as annotations (e.g., Link, Screen, Widget), bookmarks (outline items), or the OpenAction entry in the document catalog. Actions are used to automatically execute specific operations when an object is activated (e.g., clicked, selected, or when a document is opened). These operations include jumping to a destination, launching an application, playing a sound, changing the appearance of an annotation, etc.

- Additional Action: Introduced in PDF 1.2. Additional actions can be bound to the AA entry in objects such as the document catalog, pages, annotations, or form widgets. Additional actions respond to various specific trigger events, such as entering, exiting, pressing, releasing, gaining/losing focus, changing field values, etc. Each event can have a designated action, enabling more fine-grained event-driven behavior.

> ⚠️ Note: The `Action`
> (opens new window) class and its related subclasses have been deprecated. All operations related to Actions should now use the dedicated APIs provided by each object (such as Annot, Widget, PDFFormField, PDFDoc).

## # Typical Use Cases

- Page Navigation：Navigate to a specific page or location by clicking a link or button (e.g., GoTo, GoToR, GoToE).
- Form Interaction: Include submitting forms (SubmitForm), resetting forms (ResetForm), importing data (ImportData), and hiding/showing fields (Hide).
- Script Automation：Automatically execute JavaScript scripts during specific events, such as field value changes, page opening, or document saving.
- Multimedia and External Operations: Launch external applications (Launch), open a URI (URI), and render multimedia content (Rendition).

## # Supported Action Types

Action Type | Description | Editable (UI) | Triggerable | API Support
--- | --- | --- | --- | ---
GoTo | Navigate to a specified page/location/zoom in the current document | Y | Y | Y
GoToR | Navigate to a specified location in another PDF file (non-embedded file) | Y | N | Y
GoToE | Navigate to a specified target location in a PDF file embedded within another PDF file | N | N | Y
Hide | Hide or show specified form fields | Y | Y | Y
ImportData | Import an FDF file into the PDF to update form fields | Y | N | Y
JavaScript | Execute JavaScript scripts | Y | Y | Y
Launch | Launch external applications, typically to open files | Y | N | Y
ResetForm | Reset form fields to their default values | Y | Y | Y
SubmitForm | Submit form data to a specified URL | Y | N | Y
URI | Open a specified URI address | Y | N | Y
Rendition | Multimedia rendering actions | N | Y | N

> For detailed action types and their data structures, please refer to the definitions of ActionType
> (opens new window) and ActionSpecification
> (opens new window).

## # Trigger Events

The execution of actions depends on trigger events, and different objects support different types of events. Common trigger events include:

- Document-Level (DocActionTriggerEvents
  (opens new window)): Events such as document closing, saving, or printing.
- Page-Level (PageActionTriggerEvents
  (opens new window)): Events such as page opening or closing.
- Annotation/Widget-Level (AnnotActionTriggerEvents
  (opens new window)): Events such as mouse enter, exit, press, or release.
- Form Field-Level (FieldActionTriggerEvents
  (opens new window)): Events such as typing, formatting, value changes, or recalculation.

## # Action Data Structure

- ActionSpecification
  (opens new window): Describe the action type and its parameters (e.g., target for navigation, script content, etc.).
- ActionHierarchy
  (opens new window): Describe the hierarchical structure of actions, supporting nested sub-actions.
- ActionData
  (opens new window): The data carrier for specific actions.

## # Main API Description

### # Action Related APIs

- `Annot.getAllActionData()`: Get all action data associated with an annotation, including both primary actions and additional actions.
- `Annot.getActionData()`: Get the primary action data of an annotation.
- `Annot.setAction(actionSpec)`: Set the primary action for an annotation.
- `Annot.appendAction(actionSpec)`: Append a primary action to an annotation.
- `Annot.updateAction(actionObjNumber, actionData)`: Update the primary action of an annotation.
- `Annot.removeAction(actionObjNumber)`: Remove the primary action of an annotation.
- `Annot.supportsAction()`: Check whether the current annotation type supports actions (supported types include: screen, link, sound, widget).

### # Additional Action Related APIs

- `getAdditionalAction`: Get the instance of additional actions.
  - `Widget.getAdditionalAction()`: Get the additional action instance for a form widget.
  - `PDFPage.getAdditionalAction()`: Get the additional action instance for a page.
  - `PDFFormField.getAdditionalAction()`：Get the additional action instance for a form field.
  - `PDFDoc.getAdditionalAction()`: Get the additional action instance for a document.
- `AdditionalAction.setAction(trigger, actionSpec)`: Set an additional action for a specific event.
- `AdditionalAction.addAction(trigger, actionSpec)`: Append an additional action to a specific event.
- `AdditionalAction.updateActionData(trigger, actionObjNumber, actionData)`: Update the additional action for a specific event.
- `AdditionalAction.removeAction(trigger, actionObjNumber)`: Remove the additional action for a specific event.
- `AdditionalAction.getActions([triggers])`: Get the list of additional actions for the specified events.

### # Document-Level Action

- `PDFDoc.setOpenAction(actionType, actionData)`: Set an action to be automatically executed when the document is opened.
- `PDFDoc.getOpenAction()`: Get the action set for document opening.
- `PDFDoc.removeOpenAction()`: Remove the action set for document opening.

## # Notes on Using Actions

- Actions are supported only by specific annotation types: screen, link, sound, and widget.

- Additional actions are supported only by specific annotation types: screen and widget.

- The trigger event types for additional actions must match the object type; otherwise, they will not work (AnnotActionTriggerEvents
  (opens new window), DocActionTriggerEvents
  (opens new window), FieldActionTriggerEvents
  (opens new window), PageActionTriggerEvents
  (opens new window)). PageActionTriggerEvents
  (opens new window): Applicable to pages.

- Certain action types (such as GotoR, GoToE, and Rendition) are limited by the SDK's support and are either only supported for triggering or only for setting via the API.

## # Action and Additional Action

### # Action

Action is a core action mechanism in PDF, initially introduced in version 1.1 of the PDF specification. It is defined through the A entry (Action entry) of an object. Its main characteristics include:

- Direct Binding: Actions can be directly bound to the dictionary of annotations or bookmarks.
- Single Trigger: Actions are typically triggered when an object is "activated", such as clicking a link annotation or selecting a bookmark item.
- Chained Execution: Support building action chains through the `Next` entry, enabling complex tree-like action sequences.
- Document-Level Support: The `OpenAction` entry in the document catalog allows specifying actions to be executed when the document is opened.

### # Additional Action

Additional Action is an extended action mechanism in PDF, initially introduced in version 1.2 of the PDF specification. It is defined through the AA entry (Additional Action entry) of an object. Its main characteristics include:

- Event-Driven: Actions are triggered by specific events (Trigger Events), rather than simple "activation".
- Multi-Event Support: A single object can bind different actions to different types of events.
- Broad Applicability: Support various object types, such as documents, pages, annotations, form widgets, and more.
- Granular Control: Support fine-grained event management, such as mouse enter/exit, gaining/losing focus, and similar interactions.

### # Key Differences

Feature | Action | Additional Action
--- | --- | ---
Introduced Version | PDF 1.1 | PDF 1.2
Binding Method | A entry | AA entry
Trigger Mechanism | Object activation (e.g., click) | Specific event-driven
Event Types | Single (activation) | Multiple (enter, exit, press, release, etc.)
Applicable Objects | Annotations, bookmarks, documents | Documents, pages, annotations, form widgets
Complexity | Relatively simple | More flexible and complex
Typical Use Cases | Page navigation, link clicks | Form validation, dynamic interactions, state changes

### # Event Trigger System

The power of Additional Action lies in its diverse event trigger system. According to the `ActionTriggerEvents` definition in Foxit PDF SDK for Web, the trigger events are mainly divided into the following four categories.

#### # Document-Level Events (DocActionTriggerEvents)

- DOC_WILL_CLOSE: Trigger a JavaScript action before the document is closed.
- DOC_WILL_SAVE: Trigger a JavaScript action before the document is saved.
- DOC_SAVED: Trigger a JavaScript action after the document is saved.
- DOC_WILL_PRINT: Trigger a JavaScript action before the document is printed.
- DOC_PRINTED: Trigger a JavaScript action after the document is printed.

#### # Page-Level Events (PageActionTriggerEvents)

- PAGE_OPENED: Trigger an action when the page is opened.
- PAGE_CLOSED: Trigger an action when the page is closed.

#### # Annotation/Widget-Level Events (AnnotActionTriggerEvents)

- ANNOT_CURSOR_ENTER: Trigger an action when the cursor enters the annotation's active area.
- ANNOT_CURSOR_EXIT: Trigger an action when the cursor leaves the annotation's active area.
- ANNOT_MOUSE_BUTTON_PRESSED: Trigger an action when the mouse button is pressed within the annotation's active area.
- ANNOT_MOUSE_BUTTON_RELEASED: Trigger an action when the mouse button is released within the annotation's active area.
- ANNOT_RECEIVE_INPUT_FOCUS: Trigger an action when the annotation (Widget annotations only) receives input focus.
- ANNOT_LOSE_INPUT_FOCUS: Trigger an action when the annotation (Widget annotations only) loses input focus.
- ANNOT_PAGE_OPENED: Trigger an action when the page containing the annotation is opened (executed after `PAGE_OPENED` and document open actions).
- ANNOT_PAGE_CLOSED: Trigger an action when the page containing the annotation is closed (executed after `PAGE_CLOSED`).
- ANNOT_PAGE_VISIBLE: Trigger an action when the page containing the annotation becomes visible in the viewer UI.
- ANNOT_PAGE_INVISIBLE: Trigger an action when the page containing the annotation becomes invisible in the viewer UI.

#### # Form Field-Level Events (FieldActionTriggerEvents)

- FIELD_KEY_STROKE: Trigger a JavaScript action when a user types in a text field or combo box, or modifies the selection in a scrollable list box. This can be used to validate or modify keystrokes.

- FIELD_WILL_FORMAT: Trigger a JavaScript action before a field's value is formatted for display. This can be used to modify the field's value.

- FIELD_VALUE_CHANGED: Trigger a JavaScript action when the field value is changed. This can be used to validate the new value.

- FIELD_RECALCULATE_VALUE: Trigger a JavaScript action when the value of other fields changes, in order to recalculate the current field value. The calculation order can be determined using the `PDFForm.getFieldsInCalculationOrder` function.

### # Practical Application Scenarios

#### # Typical Applications of Action

    // Set the hyperlink annotation's jump action
    linkAnnot.setAction({
        type: "GoTo",
        dest: { page: 5, view: "FitH" },
    });

    //  Set the document open action
    pdfDoc.setOpenAction(PDF.actions.ActionType.javaScript, {
        script: 'app.alert("Welcome to this document!");',
    });

#### # Typical Applications of Additional Action

    // Validation when the form widget value changes
    const additionalAction = formField.getAdditionalAction();
    additionalAction.setAction(PDF.actions.ActionTriggerEvents.FIELD_VALUE_CHANGED, {
        type: PDF.actions.ActionType.javaScript,
        data: {
            javascript: 'if (event.value < 0) { app.alert("The value cannot be negative"); event.rc = false; }'
        },
    });

    //  Initialization action when the page opens
    const pageAdditionalAction = pdfPage.getAdditionalAction();
    pageAdditionalAction.setAction(PDF.actions.ActionTriggerEvents.PAGE_OPENED, {
        type: PDF.actions.ActionType.javaScript,
        data: {
            javascript: 'console.log("The page has been opened");',
        }
    });

    // Actions triggered when the cursor enters the active annotation area
    const annotAdditionalAction = annotation.getAdditionalAction();
    annotAdditionalAction.setAction(PDF.actions.ActionTriggerEvents.ANNOT_CURSOR_ENTER, {
        type: PDF.actions.ActionType.javaScript,
        data: {
            javascript: "this.highlight = true;",
        }
    });

    // Data validation before saving the document
    const docAdditionalAction = pdfDoc.getAdditionalAction();
    docAdditionalAction.setAction(PDF.actions.ActionTriggerEvents.DOC_WILL_SAVE, {
        type: PDF.actions.ActionType.javaScript,
        data: {
            javascript: 'if (!validateFormData()) { event.rc = false; app.alert("Please complete the required information"); }',
        }
    });