# # Form Interaction Event Handling Mechanism

Foxit PDF SDK for Web provides a comprehensive event handling mechanism for form interactions in Form Filling Mode, enabling developers to precisely control and customize form interaction behaviors. This mechanism supports various event types, including mouse events (e.g., mouse down, move, release, etc.) and keyboard events (e.g., key down, key release, etc.). Developers can implement event control through the following three approaches:

- Event Listening: Monitor form interaction events using methods like `FormFillerService.onMouseDownWidget`, `FormFillerService.onMouseMoveWidget`, etc.
- Interceptor: Intercept and process form interaction events by implementing the `FormInteractionEventInterceptor` interface.
- Method Overriding: Register mixin methods using `ViewerAnnotManager.registerMatchRule`, inherit `WidgetAnnot`, and override related methods such as `handleOnGotFocus` and `handleOnClick`.

Below is a detailed explanation of each approach.

## # Form Interaction Event Listening

Event listening allows developers to handle logic unrelated to form control implementation through event callbacks during form control interactions. This approach enables adding additional processing logic without modifying the original behavior of the controls. Typical use cases include:

- User Behavior Analysis:
  - Collect user behavior data by listening to form control interaction events (e.g., clicks, movements, keyboard inputs).
- Real-Time Assistance and Hints:
  - Dynamically trigger the display of help information or tooltips when users input or click specific fields.
- Other Scenarios:
  - Extend more customized functionalities based on specific business requirements.

Foxit PDF SDK for Web provides the following event listening methods:

- `FormFillerService.onMouseDownWidget`：Listen for mouse down events.
- `FormFillerService.onMouseMoveWidget`：Listen for mouse move events.
- `FormFillerService.onMouseUpWidget`：Listen for mouse up events.
- `FormFillerService.onClickWidget`：Listen for left mouse click events.
- `FormFillerService.onRightClickWidget`：Listen for right mouse click events.
- `FormFillerService.onMouseOverWidget`：Listen for mouse hover (mouse over) events.
- `FormFillerService.onMouseLeaveWidget`：Listen for mouse leave events.
- `FormFillerService.onKeyDown`：Listen for key press (key down) events.
- `FormFillerService.onKeyUp`：Listen for key release (key up) events.
- `FormFillerService.onFocusChange`：Listen for focus change events.

For more information about the available interfaces, please refer to the FormFillerService documentation.

Below is a simple example:

    const formFillerService = pdfViewer.getFormFillerService();
    // The removeEvent function can be used to remove event listeners when needed
    const removeEvent = formFillerService.onMouseOverWidget((widgetId, event) => {
        console.log('Mouse over widget:', widgetId, event);
    });

    const removeEvent = formFillerService.onMouseDownWidget((widgetId, event) => {
      if(widgetId) {
        console.log('Mouse down on widget:', widgetId, event);
      } else {
        console.log('Mouse down on page');
      }
    });

## # Form Interaction Event Interceptor

The interceptor mechanism allows developers to intervene before or after an event occurs, enabling them to selectively permit or prevent event propagation. Typical use cases include:

- Access Control:
  - Dynamically control the interactivity of form fields based on user roles or permissions.
- UI (User Interface) Protection:
  - By intercepting events (such as `mouseup`), prompt the user for confirmation before executing high-risk actions to reduce the risk of accidental operations.
- Behavior Modification:
  - Modify form interaction behavior according to specific scenario requirements.

Foxit PDF SDK for Web provides the following interceptor interfaces:

    interface FormInteractionEvent {
      type: string; // mousedown|mousemove|mouseup|keydown|keyup
      timestamp: number; // The timestamp of the event, measured in milliseconds.
    }
    interface FormInteractionEventInterceptorOptions {
      type: FormInteractionEvent;
      widgetId: AnnotId;
    }
    type FormInteractionEventInterceptor = (options:FormInteractionEventInterceptorOptions,next:()=>Promise<unknown>)=>Promise<void>;

The `options` parameter contains the ID of the target form widget (an object including `pageIndex` and `objNumber`) and the event type. The `next` function is used to invoke the next interceptor. For more detailed information, please refer to the FormInteractionEventInterceptor documentation.

Here is an example implementation of an interceptor:

    // removeInterceptor can be used to remove the interceptor at a specific point in time
    const removeInterceptor = formFillerService.appendInteractionEventInterceptor(async (options, next) => {
      if(options.type === 'mouseup') {
        // Intercept mouse release event
        console.log("Before mouse up");
        // Call the next interceptor or handle the actual event
        await next();
        // Execute after the mouse release event is completed
        console.log("After mouse up");
      }
    })

Notes:

1. If the `next` method is not called, the interceptor will block the event propagation, and the SDK's internal handling logic will not be executed.
2. `click` and `right-click` are composite events triggered by specific conditions of `mousedown/mouseup`. They cannot be directly handled and can only be implemented by intercepting `mousedown` or `mouseup` events.

A complete example can be found at: <examples/UIExtension/form/interaction-event-interceptor/index.js>

## # Method Overriding

Method overriding is implemented by registering mixin methods through `ViewerAnnotManager.registerMatchRule`. This involves inheriting `WidgetAnnot` and overriding methods such as `handleOnGotFocus` and `handleOnClick`. This approach not only enables event listening but also allows control over whether the SDK's internal presentation layer logic is executed. Typical use cases include:

- All scenarios supported by event listeners.
- Scenarios requiring the override of Foxit PDF SDK for Web's presentation layer logic.

The event-related methods provided by Foxit PDF SDK for Web that can be overridden are as follows:

- `handleOnClick`：Handle left mouse button click events.
- `handleOnMouseOver`：Handle mouse hover (mouseover) events.
- `handleOnMouseLeave`：Handle mouse leave (mouseout) events.
- `handleOnGotFocus`：Handle focus gained events.
- `handleOnLostFocus`：Handle focus lost events.

Note: To override right-click events or customize the context menu, you can achieve this by overriding the `showContextMenu` method.

Here is a simple example:

    pdfViewer.getAnnotManager().registerMatchRule(function(annot, AnnotComponentClass) {
      if(annot.getType() !== 'widget') {
          return;
      }
      return class CustomWidgetAnnot extends AnnotComponentClass {
          handleOnClick() {
              super.handleOnClick();
              console.log('CustomWidgetAnnot handleOnClick');
          }
          handleOnMouseOver() {
              super.handleOnMouseOver();
              console.log('Handle on mouse over');
          }
          handleOnMouseLeave() {
              super.handleOnMouseLeave();
              console.log('Handle on mouse leave');
          }
          handleOnGotFocus() {
              super.handleOnGotFocus();
              console.log('Handle on got focus');
          }
          handleOnLostFocus() {
              super.handleOnLostFocus();
              console.log('Handle on lost focus');
          }
      }
    })

## # Method Comparison

Method | Supported Scope | Control Level | Flexibility
--- | --- | --- | ---
Event Listening | mousedown/mouseover/mouseup/click/right-click/mouseover/mouseleave/keydown/keyup/focus-change | After event occurs | General
Interceptor | mousedown/mousemove/mouseup/keydown/keyup | Before and after event occurs | Highest
Method Overriding | click/mouseover/mouseleave/get-focus/lost-focus | After event occurs | General