How can I help you?
How to Customize the context menu in PDF Viewer in Angular
17 Apr 202612 minutes to read
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() method. This is typically implemented during the documentLoad event.
Implementation Guide
- Define the menu items as an array of objects.
- Call the
addCustomMenumethod within thedocumentLoadevent handler.
import { Component, ViewChild } from '@angular/core';
import {
PdfViewerComponent,PdfViewerModule,ToolbarService,
NavigationService,AnnotationService,LinkAnnotationService,
BookmarkViewService,ThumbnailViewService,PrintService,
TextSelectionService,TextSearchService,
FormFieldsService,FormDesignerService,
} from '@syncfusion/ej2-angular-pdfviewer';
@Component({
selector: 'app-root',
standalone: true,
imports: [PdfViewerModule],
providers: [
ToolbarService,NavigationService,AnnotationService,
LinkAnnotationService,BookmarkViewService,ThumbnailViewService,
PrintService,TextSelectionService,
TextSearchService,FormFieldsService,
FormDesignerService,
],
template: `
<ejs-pdfviewer
#pdfviewer
id="PdfViewer"
[documentPath]="document"
[resourceUrl]="resource"
(documentLoad)="documentLoad()"
(customContextMenuSelect)="customContextMenuSelect($event)"
(customContextMenuBeforeOpen)="customContextMenuBeforeOpen($event)"
style="height: 100vh; width: 100%; display: block"
>
</ejs-pdfviewer>
`,
})
export class AppComponent {
@ViewChild('pdfviewer')
public pdfviewerObj!: PdfViewerComponent;
public document = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
public resource =
'https://cdn.syncfusion.com/ej2/32.2.3/dist/ej2-pdfviewer-lib';
public menuItems = [
{
text: 'Search In Google',
id: 'search_in_google',
iconCss: 'e-icons e-search',
},
{
text: 'Lock Annotation',
id: 'lock_annotation',
iconCss: 'e-icons e-lock',
},
{
text: 'Unlock Annotation',
id: 'unlock_annotation',
iconCss: 'e-icons e-unlock',
},
{
text: 'Lock Form Field',
id: 'read_only_true',
iconCss: 'e-icons e-lock',
},
{
text: 'Unlock Form Field',
id: 'read_only_false',
iconCss: 'e-icons e-unlock',
},
];
/* ---------------------------------- */
/* Document Load */
/* ---------------------------------- */
documentLoad(): void {
this.pdfviewerObj.addCustomMenu(this.menuItems, false);
}
/* ---------------------------------- */
/* Context Menu Select */
/* ---------------------------------- */
customContextMenuSelect(args: any): void {
switch (args.id) {
case 'search_in_google':
this.searchInGoogle();
break;
case 'lock_annotation':
this.lockAnnotation();
break;
case 'unlock_annotation':
this.unlockAnnotation();
break;
case 'read_only_true':
this.setFormFieldReadOnly(true);
break;
case 'read_only_false':
this.setFormFieldReadOnly(false);
break;
}
args.cancel = false;
}
/* ---------------------------------- */
/* Google Search */
/* ---------------------------------- */
searchInGoogle(): void {
const textModule = this.pdfviewerObj.textSelectionModule;
if (textModule?.isTextSelection) {
textModule.selectionRangeArray.forEach((range: any) => {
if (/\S/.test(range.textContent)) {
window.open(`https://www.google.com/search?q=${range.textContent}`);
}
});
}
}
/* ---------------------------------- */
/* Lock Annotation */
/* ---------------------------------- */
lockAnnotation(): void {
const selected = this.pdfviewerObj.selectedItems.annotations[0];
if (!selected) return;
const annotation = this.pdfviewerObj.annotationCollection.find(
(a: any) => a.uniqueKey === selected.id
);
if (annotation) {
const settings = annotation.annotationSettings as any;
settings.isLock = true;
annotation.isCommentLock = true;
this.pdfviewerObj.annotation.editAnnotation(annotation);
}
}
/* ---------------------------------- */
/* Unlock Annotation */
/* ---------------------------------- */
unlockAnnotation(): void {
const selected = this.pdfviewerObj.selectedItems.annotations[0];
if (!selected) return;
const annotation = this.pdfviewerObj.annotationCollection.find(
(a: any) => a.uniqueKey === selected.id
);
if (annotation) {
const settings = annotation.annotationSettings as any;
settings.isLock = false;
annotation.isCommentLock = false;
this.pdfviewerObj.annotation.editAnnotation(annotation);
}
}
/* ---------------------------------- */
/* Form Field Read-only Handling */
/* ---------------------------------- */
setFormFieldReadOnly(isReadOnly: boolean): void {
const fields = this.pdfviewerObj.selectedItems.formFields;
fields.forEach((field: any) => {
this.pdfviewerObj.formDesignerModule.updateFormField(field, {
isReadOnly: isReadOnly,
} as any);
});
}
/* ---------------------------------- */
/* Context Menu Visibility */
/* ---------------------------------- */
customContextMenuBeforeOpen(args: any): void {
args.ids.forEach((id: string) => {
const menuItem = document.getElementById(id);
if (!menuItem) return;
menuItem.style.display = 'none';
if (
id === 'search_in_google' &&
this.pdfviewerObj.textSelectionModule?.isTextSelection
) {
menuItem.style.display = 'block';
}
if (
(id === 'lock_annotation' || id === 'unlock_annotation') &&
this.pdfviewerObj.selectedItems.annotations.length
) {
const selected = this.pdfviewerObj.selectedItems.annotations[0];
const isLocked = (selected.annotationSettings as any)?.isLock;
menuItem.style.display =
(id === 'lock_annotation' && !isLocked) ||
(id === 'unlock_annotation' && isLocked)
? 'block'
: 'none';
}
if (
(id === 'read_only_true' || id === 'read_only_false') &&
this.pdfviewerObj.selectedItems.formFields.length
) {
const field = this.pdfviewerObj.selectedItems.formFields[0];
const readonly = field.isReadonly;
menuItem.style.display =
(id === 'read_only_true' && !readonly) ||
(id === 'read_only_false' && readonly)
? 'block'
: 'none';
}
});
}
}Handle Click Events for Custom Menu Items
The customContextMenuSelect() method defines actions for custom menu items. The implementation is included in the Angular component above in the customContextMenuSelect() method.
Dynamic Context Menu Customization
The customContextMenuBeforeOpen() event allows for dynamic showing or hiding of items based on selection or document state. The implementation is included in the Angular component above in the customContextMenuBeforeOpen() method.
Disable the Context Menu Entirely
The context menu in the PDF Viewer can be fully disabled by setting the contextMenuOption property to None.
import { Component, ViewChild } from '@angular/core';
import {
PdfViewerComponent,PdfViewerModule,
ToolbarService,NavigationService,
LinkAnnotationService,BookmarkViewService,
ThumbnailViewService,PrintService,
TextSelectionService,TextSearchService,
AnnotationService,FormDesignerService,
FormFieldsService,
} from '@syncfusion/ej2-angular-pdfviewer';
@Component({
selector: 'app-root',
standalone: true,
imports: [PdfViewerModule],
providers: [
ToolbarService,NavigationService,
LinkAnnotationService,BookmarkViewService,
ThumbnailViewService,PrintService,
TextSelectionService,TextSearchService,
AnnotationService,FormDesignerService,
FormFieldsService,
],
template: `
<ejs-pdfviewer
id="pdfViewer"
[documentPath]="document"
[resourceUrl]="resource"
[contextMenuOption]="contextMenuOption"
style="height: 100%; width: 100%; display: block"
>
</ejs-pdfviewer>
`,
})
export class AppComponent {
public document: string =
'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
public resource: string =
'https://cdn.syncfusion.com/ej2/32.2.3/dist/ej2-pdfviewer-lib';
public contextMenuOption: string = 'None';
}NOTE
The context menu customization works with standalone and non-standalone Angular components, providing flexible integration options for your application.