Skip to content
Merged
7 changes: 6 additions & 1 deletion Document-Processing-toc.html
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,12 @@
<li><a href="/document-processing/pdf/pdf-viewer/react/text-selection">Text Selection</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/globalization">Globalization</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/accessibility">Accessibility</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/context-menu/context-menu">Context Menu</a>
<ul>
<li><a href="/document-processing/pdf/pdf-viewer/react/context-menu/builtin-context-menu">Built-in Context Menu</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/context-menu/custom-context-menu">Customize Context Menu</a></li>
</ul>
</li>
<li><a href="/document-processing/pdf/pdf-viewer/react/how-to-overview">How to</a>
<ul>
<li><a href="/document-processing/pdf/pdf-viewer/react/how-to/load-document">Load the PDF documents dynamically</a></li>
Expand All @@ -1049,7 +1055,6 @@
<li><a href="/document-processing/pdf/pdf-viewer/react/how-to/retry-timeout">Retry Timeout</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/how-to/load-n-number-page">Load N number of pages on initial loading</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/how-to/conformance">Supported conformance documents</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/how-to/custom-context-menu">Customize context menu</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/how-to/pagerenderstarted-pagerendercompleted-event">PageRenderInitiate and PageRenderComplete event</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/how-to/open-bookmark">Open and Close Bookmark pane programmatically</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/how-to/signatureselect-signatureunselect">SignatureSelect and SignatureUnselect event</a></li>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
layout: post
title: Built-in Context Menu in React PDF Viewer | Syncfusion
description: Explore the default context menu items in the React PDF Viewer, including options for text selection, annotations, and form fields.
control: PDF Viewer
platform: document-processing
documentation: ug
domainurl: ##DomainURL##
---

# Built-in Context Menu Items in React PDF Viewer

The React PDF Viewer includes a context-sensitive menu that updates dynamically based on the right-clicked element within the document. This page lists the default menu items available for different document elements.

## Context Menu Scenarios

Menu items vary depending on the target element:

* **Text**: Displays options to annotate and copy selected text.

![context menu on text](../images/context-menu-text.png)

* **Annotations**: Provides options to copy, cut, paste, or remove annotations, and add comments.

![context menu on annotation](../images/context-menu-annotation.png)

* **Form Fields**: Shows standard form field interactions, such as modifying properties. The context menu for form fields appears only when the viewer is in **designer mode**.

![context menu on form fields](../images/context-menu-forms.png)

* **Empty Space**: Displays the option to paste a previously copied annotation or form field.

![context menu on empty space](../images/context-menu-empty.png)

## Default Item Reference

### Text Menu Items

The following table describes the default items available when right-clicking selected text:

| Item | Description |
| :--- | :--- |
| **Copy** | Copies selected text to the clipboard. |
| **Highlight** | Highlights selected text using the default highlight color. |
| **Underline** | Applies an underline to the selected text. |
| **Strikethrough** | Applies a strikethrough to the selected text. |
| **Squiggly** | Applies a squiggly underline to the selected text. |
| **Redact Text** | Redacts the selected text. |

### Annotation Menu Items

The following items are available when interacting with annotations:

| Item | Description |
| :--- | :--- |
| **Copy** | Copies the selected annotation for pasting within the same page. |
| **Cut** | Removes the selected annotation and copies it to the clipboard. |
| **Paste** | Pastes a previously copied or cut annotation. |
| **Delete** | Permanently removes the selected annotation. |
| **Comments** | Opens the comment panel to manage discussions on the annotation. |

### Form Field Menu Items

These items appear when the viewer is in designer mode and a form field is selected:

| Item | Description |
| :--- | :--- |
| **Copy** | Copies the selected form field for duplication. |
| **Cut** | Removes the selected form field for relocation. |
| **Paste** | Pastes a copied or cut form field. |
| **Delete** | Removes the selected form field from the document. |
| **Properties** | Launches the properties dialog for the specific form field. |

N> The availability of the context menu is a client-side feature and is independent of server configurations.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
layout: post
title: Context Menu in React PDF Viewer | Syncfusion
description: Learn about the contextual menu options in the Syncfusion React PDF Viewer, including default behavior and customization possibilities.
control: PDF Viewer
platform: document-processing
documentation: ug
domainurl: ##DomainURL##
---

# Context Menu in React PDF Viewer

The React PDF Viewer provides a built-in context menu for interacting with text, annotations, form fields, and document elements. This feature enhances the user experience by offering quick access to relevant actions based on the current selection or the specific area of the document being interacted with.

## Understanding the Context Menu

The context menu is designed to be context-aware, meaning it dynamically updates its items based on the target element. For instance, right-clicking on selected text will show annotation options, while right-clicking on an annotation will display management options like copy, cut, and delete.

### Core Capabilities

The context menu supports several configurations:

* **Default Behavior**: Provides standard actions such as cut, copy, and annotation management.
* **Customization**: Allows adding new menu items, removing default ones, or reordering them to meet specific application requirements.
* **Granular Control**: Developers can fully disable the menu or replace it with custom logic using events.

### Client-side Interaction

The availability and behavior of the context menu are governed primarily by client-side logic. It is not affected by server-side configurations or cloud environments, ensuring consistent performance across different deployment scenarios.

## Further Reading

* [Built-in Context Menu](builtin-context-menu) – A technical reference for default menu behavior and items.
* [Customize Context Menu](custom-context-menu) – A guide on how to implement custom menu items and dynamic updates.
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
---
layout: post
title: Customize the context menu in React PDF Viewer | Syncfusion
description: Learn how to add and customize custom context menu options in the React PDF Viewer using addCustomMenu, customContextMenuSelect, and related events.
control: PDF Viewer
platform: document-processing
documentation: ug
domainurl: ##DomainURL##
---

# How to Customize the context menu in PDF Viewer in React

The PDF Viewer supports extensive customization of the context menu, including reaching specific goals like adding new items, hiding default options, and handling custom click events.

## Add Custom Context Menu Items

You can add custom options to the context menu using the [addCustomMenu()](https://ej2.syncfusion.com/react/documentation/api/pdfviewer#addcustommenu) method. This is typically implemented during the [`documentLoad`](https://ej2.syncfusion.com/react/documentation/api/pdfviewer#documentload) event.

### Implementation Guide

1. Define the menu items as an array of objects.
2. Call the [`addCustomMenu`](https://ej2.syncfusion.com/react/documentation/api/pdfviewer#addcustommenu) method within the [`documentLoad`](https://ej2.syncfusion.com/react/documentation/api/pdfviewer#documentload) event handler.

```jsx
export function App() {

let menuItems = [
{
text: 'Search In Google',
id: 'search_in_google',
iconCss: 'e-icons e-search'
},
{
text: 'Lock Annotation',
iconCss: 'e-icons e-lock',
id: 'lock_annotation'
},
{
text: 'Unlock Annotation',
iconCss: 'e-icons e-unlock',
id: 'unlock_annotation'
},
{
text: 'Lock Form Field',
iconCss: 'e-icons e-lock',
id: 'read_only_true'
},
{
text: 'Unlock Form Field',
iconCss: 'e-icons e-unlock',
id: 'read_only_false'
},
];
function documentLoad(args) {
var viewer = document.getElementById('container').ej2_instances[0];
viewer.addCustomMenu(menuItems, false);
}

return (
<div>
<div className='control-section'>
{/* Render the PDF Viewer */}
<PdfViewerComponent
id="container"
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
resourceUrl="https://cdn.syncfusion.com/ej2/31.2.2/dist/ej2-pdfviewer-lib"
documentLoad={documentLoad}
customContextMenuSelect={customContextMenuSelect}
customContextMenuBeforeOpen={customContextMenuBeforeOpen}
height='640px'>
<Inject services={[Toolbar, Magnification, Navigation, Annotation, LinkAnnotation, BookmarkView,
ThumbnailView, Print, TextSelection, TextSearch, FormFields, FormDesigner]} />
</PdfViewerComponent>
</div>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('sample'));
root.render(<App />);
```

## Handle Click Events for Custom Menu Items

The [customContextMenuSelect()](https://ej2.syncfusion.com/react/documentation/api/pdfviewer#customcontextMenuselect) method defines actions for custom menu items.

```jsx
function customContextMenuSelect(args) {
var viewer = document.getElementById('container').ej2_instances[0];
switch (args.id) {
case 'search_in_google':
for (var i = 0; i < viewer.textSelectionModule.selectionRangeArray.length; i++) {
var content = viewer.textSelectionModule.selectionRangeArray[i].textContent;
if ((viewer.textSelectionModule.isTextSelection) && (\/\S\/.test(content))) {
window.open('http://google.com/search?q=' + content);
}
}
break;
case 'lock_annotation':
lockAnnotations(args);
break;
case 'unlock_annotation':
unlockAnnotations(args);
break;
case 'read_only_true':
setReadOnlyTrue(args);
break;
case 'read_only_false':
setReadOnlyFalse(args);
break;
default:
break;
}
}

function lockAnnotations(args) {
for (var i = 0; i < viewer.annotationCollection.length; i++) {
if (viewer.annotationCollection[i].uniqueKey === viewer.selectedItems.annotations[0].id) {
viewer.annotationCollection[i].annotationSettings.isLock = true;
viewer.annotationCollection[i].isCommentLock = true;
viewer.annotation.editAnnotation(viewer.annotationCollection[i]);
}
args.cancel = false;
}
}

function unlockAnnotations(args) {
for (var i = 0; i < viewer.annotationCollection.length; i++) {
if (viewer.annotationCollection[i].uniqueKey === viewer.selectedItems.annotations[0].id) {
viewer.annotationCollection[i].annotationSettings.isLock = false;
viewer.annotationCollection[i].isCommentLock = false;
viewer.annotation.editAnnotation(viewer.annotationCollection[i]);
}
args.cancel = false;
}
}

function setReadOnlyTrue(args) {
var viewer = document.getElementById('container').ej2_instances[0];
var selectedFormFields = viewer.selectedItems.formFields;
for (var i = 0; i < selectedFormFields.length; i++) {
var selectedFormField = selectedFormFields[i];
if (selectedFormField) {
viewer.formDesignerModule.updateFormField(selectedFormField, {
isReadOnly: true,
});
}
args.cancel = false;
}
}

function setReadOnlyFalse(args) {
var viewer = document.getElementById('container').ej2_instances[0];
var selectedFormFields = viewer.selectedItems.formFields;
for (var i = 0; i < selectedFormFields.length; i++) {
var selectedFormField = selectedFormFields[i];
if (selectedFormField) {
viewer.formDesignerModule.updateFormField(selectedFormField, {
isReadOnly: false,
});
}
args.cancel = false;
}
}
```

## Dynamic Context Menu Customization

The [customContextMenuBeforeOpen()](https://ej2.syncfusion.com/react/documentation/api/pdfviewer#customcontextMenubeforeopen) event allows for dynamic showing or hiding of items based on selection or document state.

```jsx
function customContextMenuBeforeOpen(args) {
for (var i = 0; i < args.ids.length; i++) {
var search = document.getElementById(args.ids[i]);
var viewer = document.getElementById('container').ej2_instances[0];
if (search) {
search.style.display = 'none';
if (args.ids[i] === 'search_in_google' && (viewer.textSelectionModule) && viewer.textSelectionModule.isTextSelection) {
search.style.display = 'block';
} else if (args.ids[i] === "lock_annotation" || args.ids[i] === "unlock_annotation") {
var isLockOption = args.ids[i] === "lock_annotation";
for (var j = 0; j < viewer.selectedItems.annotations.length; j++) {
var selectedAnnotation = viewer.selectedItems.annotations[j];
if (selectedAnnotation && selectedAnnotation.annotationSettings) {
var shouldDisplay = (isLockOption && !selectedAnnotation.annotationSettings.isLock) ||
(!isLockOption && selectedAnnotation.annotationSettings.isLock);
search.style.display = shouldDisplay ? 'block' : 'none';
}
}
} else if (args.ids[i] === "read_only_true" && viewer.selectedItems.formFields.length !== 0) {
var selectedFormField = viewer.selectedItems.formFields[0].isReadonly;
search.style.display = selectedFormField ? 'none' : 'block';
} else if (args.ids[i] === "read_only_false" && viewer.selectedItems.formFields.length !== 0) {
var selectedFormField = viewer.selectedItems.formFields[0].isReadonly;
search.style.display = selectedFormField ? 'block' : 'none';
} else if (args.ids[i] === 'formfield properties' && viewer.selectedItems.formFields.length !== 0) {
search.style.display = 'block';
}
}
}
}
```

## Disable the Context Menu Entirely

The context menu in the PDF Viewer can be fully disabled by setting the [`contextMenuOption`](https://ej2.syncfusion.com/react/documentation/api/pdfviewer#contextmenuoption) property to `None`.

```js
<PdfViewerComponent
id="pdfViewer"
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
height="100%"
width="100%"
contextMenuOption='None' >
<Inject
services={[
Toolbar, Magnification, Navigation, LinkAnnotation, BookmarkView, ThumbnailView, Print, TextSelection, TextSearch, Annotation, FormDesigner, FormFields
]}
/>
</PdfViewerComponent>
```

The following is the output of the custom context menu with customization.

{% tabs %}
{% highlight js tabtitle="index.jsx" %}
{% raw %}
{% include code-snippet/pdfviewer/react/custom-context-menu/app/index.jsx %}
{% endraw %}
{% endhighlight %}
{% highlight ts tabtitle="index.tsx" %}
{% raw %}
{% include code-snippet/pdfviewer/react/custom-context-menu/app/index.tsx %}
{% endraw %}
{% endhighlight %}
{% endtabs %}

N> To set up the **server-backed PDF Viewer**, add the following `serviceUrl` within the <div> element in either the `index.TSX` or `index.JSX` file: **serviceUrl="https://document.syncfusion.com/web-services/pdf-viewer/api/pdfviewer"**.

{% previewsample "document-processing/code-snippet/pdfviewer/react/custom-context-menu" %}

[View the sample in Stack blitz](https://stackblitz.com/edit/react-zmbkebwq?file=index.js)
Loading