Skip to content

Commit 9f700ca

Browse files
1007872: Updated and Resolved CI failures. Updated missed file changes
1 parent 99d1909 commit 9f700ca

2 files changed

Lines changed: 287 additions & 267 deletions

File tree

Lines changed: 113 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,136 @@
11
---
22
layout: post
3-
title: Custom annotation tools in React PDF Viewer | Syncfusion
4-
description: Learn how to build a custom toolbar for Syncfusion React PDF Viewer and switch annotation tools programmatically using setAnnotationMode.
3+
title: Custom annotation tools in Angular PDF Viewer | Syncfusion
4+
description: Learn how to build a custom toolbar for Syncfusion Angular PDF Viewer and switch annotation tools programmatically using setAnnotationMode.
55
platform: document-processing
66
control: PDF Viewer
77
documentation: ug
88
domainurl: ##DomainURL##
99
---
1010

11-
# Custom annotation tools in React PDF Viewer
11+
# Custom annotation tools in Angular PDF Viewer
1212

1313
The PDF Viewer supports adding a custom toolbar and toggling annotation tools programmatically using the `setAnnotationMode` method. The viewer can enable tools such as Highlight, Underline, Rectangle, Circle, Arrow, Free Text, Ink, and measurement annotations (Distance, Perimeter, Area, Radius)
1414

1515
Follow these steps to build a minimal custom annotation toolbar.
1616

1717
Step 1: Start from a basic PDF Viewer sample
1818

19-
Refer to the [Getting started guide](https://help.syncfusion.com/document-processing/pdf/pdf-viewer/react/getting-started) to create a basic sample.
19+
Refer to the [Getting started guide](https://help.syncfusion.com/document-processing/pdf/pdf-viewer/angular/getting-started) to create a basic sample.
2020

21-
Step 2: Add a lightweight custom toolbar with React buttons
21+
Step 2: Add a lightweight custom toolbar with Angular buttons
2222

23-
Add buttons for the tools to expose. The sample below uses plain React buttons for simplicity; replace with a Syncfusion ToolbarComponent for a richer UI if desired.
23+
Add buttons for the tools to expose. The sample below uses plain Angular buttons for simplicity; replace with a Syncfusion ToolbarComponent for a richer UI if desired.
2424

2525
Step 3: Import and inject modules
2626

2727
Ensure the `Annotation` module is injected. Include text selection and search modules if those capabilities are required.
2828

2929
{% tabs %}
30-
{% highlight js tabtitle="Standalone" %}
31-
{% raw %}
32-
import * as React from 'react';
33-
import * as ReactDOM from 'react-dom/client';
34-
import { PdfViewerComponent, Inject, Toolbar, Annotation, TextSelection } from '@syncfusion/ej2-react-pdfviewer';
35-
36-
function getViewer() { return document.getElementById('container').ej2_instances[0]; }
37-
38-
function setMode(mode) { getViewer().annotation.setAnnotationMode(mode); }
39-
40-
function App() {
41-
return (
42-
<>
43-
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '4px', marginBottom: '8px' }}>
44-
<button onClick={() => setMode('Highlight')}>Highlight</button>
45-
<button onClick={() => setMode('Underline')}>Underline</button>
46-
<button onClick={() => setMode('Strikethrough')}>Strikethrough</button>
47-
<button onClick={() => setMode('Rectangle')}>Rectangle</button>
48-
<button onClick={() => setMode('Circle')}>Circle</button>
49-
<button onClick={() => setMode('Line')}>Line</button>
50-
<button onClick={() => setMode('Arrow')}>Arrow</button>
51-
<button onClick={() => setMode('Polygon')}>Polygon</button>
52-
<button onClick={() => setMode('FreeText')}>Free Text</button>
53-
<button onClick={() => setMode('Ink')}>Ink</button>
54-
<button onClick={() => setMode('StickyNotes')}>Sticky Note</button>
55-
<button onClick={() => setMode('Distance')}>Distance</button>
56-
<button onClick={() => setMode('Perimeter')}>Perimeter</button>
57-
<button onClick={() => setMode('Area')}>Area</button>
58-
<button onClick={() => setMode('Radius')}>Radius</button>
59-
<button onClick={() => setMode('None')}>Exit</button>
60-
</div>
61-
<PdfViewerComponent
62-
id="container"
63-
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
64-
resourceUrl="https://cdn.syncfusion.com/ej2/31.2.2/dist/ej2-pdfviewer-lib"
65-
style={{ height: '640px' }}
66-
>
67-
<Inject services={[Toolbar, Annotation, TextSelection]} />
68-
</PdfViewerComponent>
69-
</>
70-
);
30+
{% highlight ts tabtitle="Standalone" %}
31+
import { Component } from '@angular/core';
32+
import { PdfViewerModule, ToolbarService, AnnotationService, TextSelectionService } from '@syncfusion/ej2-angular-pdfviewer';
33+
34+
@Component({
35+
selector: 'app-root',
36+
standalone: true,
37+
template: `
38+
<div style="display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 8px;">
39+
<button (click)="setMode('Highlight')">Highlight</button>
40+
<button (click)="setMode('Underline')">Underline</button>
41+
<button (click)="setMode('Strikethrough')">Strikethrough</button>
42+
<button (click)="setMode('Rectangle')">Rectangle</button>
43+
<button (click)="setMode('Circle')">Circle</button>
44+
<button (click)="setMode('Line')">Line</button>
45+
<button (click)="setMode('Arrow')">Arrow</button>
46+
<button (click)="setMode('Polygon')">Polygon</button>
47+
<button (click)="setMode('FreeText')">Free Text</button>
48+
<button (click)="setMode('Ink')">Ink</button>
49+
<button (click)="setMode('StickyNotes')">Sticky Note</button>
50+
<button (click)="setMode('Distance')">Distance</button>
51+
<button (click)="setMode('Perimeter')">Perimeter</button>
52+
<button (click)="setMode('Area')">Area</button>
53+
<button (click)="setMode('Radius')">Radius</button>
54+
<button (click)="setMode('None')">Exit</button>
55+
</div>
56+
<ejs-pdfviewer
57+
id="container"
58+
[documentPath]="documentPath"
59+
[resourceUrl]="resourceUrl"
60+
style="height:640px;display:block">
61+
</ejs-pdfviewer>
62+
`,
63+
imports: [PdfViewerModule],
64+
providers: [ToolbarService, AnnotationService, TextSelectionService]
65+
})
66+
export class AppComponent {
67+
public documentPath: string = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
68+
public resourceUrl: string = 'https://cdn.syncfusion.com/ej2/31.2.2/dist/ej2-pdfviewer-lib';
69+
70+
getViewer() {
71+
return (document.getElementById('container') as any).ej2_instances[0];
72+
}
73+
74+
setMode(mode: string) {
75+
this.getViewer().annotation.setAnnotationMode(mode);
76+
}
7177
}
72-
73-
ReactDOM.createRoot(document.getElementById('sample')).render(<App />);
74-
{% endraw %}
7578
{% endhighlight %}
7679
{% endtabs %}
7780

7881
## Custom tools using Syncfusion Toolbar for a richer UI
7982

80-
Replace the plain buttons with a Syncfusion `ToolbarComponent` and icons for a richer UI. Add the `@syncfusion/ej2-react-navigations` package and wire each item's `clicked` handler to `setAnnotationMode`.
83+
Replace the plain buttons with a Syncfusion `ToolbarComponent` and icons for a richer UI. Add the `@syncfusion/ej2-angular-navigations` package and wire each item's `clicked` handler to `setAnnotationMode`.
8184

8285
{% tabs %}
83-
{% highlight js tabtitle="Standalone" %}
84-
{% raw %}
85-
import * as React from 'react';
86-
import * as ReactDOM from 'react-dom/client';
87-
import { PdfViewerComponent, Inject, Toolbar, Annotation, TextSelection } from '@syncfusion/ej2-react-pdfviewer';
88-
import { ToolbarComponent, ItemsDirective, ItemDirective } from '@syncfusion/ej2-react-navigations';
89-
90-
function getViewer() { return document.getElementById('container').ej2_instances[0]; }
91-
92-
function onToolbarClick(args) {
93-
const modeMap = {
86+
{% highlight ts tabtitle="Standalone" %}
87+
import { Component } from '@angular/core';
88+
import { PdfViewerModule, ToolbarService, AnnotationService, TextSelectionService } from '@syncfusion/ej2-angular-pdfviewer';
89+
import { ToolbarModule, ClickEventArgs } from '@syncfusion/ej2-angular-navigations';
90+
91+
@Component({
92+
selector: 'app-root',
93+
standalone: true,
94+
template: `
95+
<ejs-toolbar overflowMode="Scrollable" (clicked)="onToolbarClick($event)">
96+
<e-items>
97+
<e-item id="annHighlight" text="Highlight" tooltipText="Highlight" prefixIcon="e-pv-highlight-icon"></e-item>
98+
<e-item id="annUnderline" text="Underline" tooltipText="Underline" prefixIcon="e-pv-underline-icon"></e-item>
99+
<e-item id="annStrike" text="Strike" tooltipText="Strikethrough" prefixIcon="e-pv-strikethrough-icon"></e-item>
100+
<e-item type="Separator"></e-item>
101+
<e-item id="annRect" text="Rect" tooltipText="Rectangle" prefixIcon="e-pv-shape-rectangle-icon"></e-item>
102+
<e-item id="annCircle" text="Circle" tooltipText="Circle" prefixIcon="e-pv-shape-circle-icon"></e-item>
103+
<e-item id="annLine" text="Line" tooltipText="Line" prefixIcon="e-pv-shape-line-icon"></e-item>
104+
<e-item id="annArrow" text="Arrow" tooltipText="Arrow" prefixIcon="e-pv-shape-arrow-icon"></e-item>
105+
<e-item id="annPolygon" text="Polygon" tooltipText="Polygon" prefixIcon="e-pv-shape-pentagon"></e-item>
106+
<e-item type="Separator"></e-item>
107+
<e-item id="annFreeText" text="Free Text" tooltipText="Free Text" prefixIcon="e-pv-freetext-icon"></e-item>
108+
<e-item id="annInk" text="Ink" tooltipText="Ink" prefixIcon="e-pv-inkannotation-icon"></e-item>
109+
<e-item id="annSticky" text="Note" tooltipText="Sticky Note" prefixIcon="e-pv-sticky-notes"></e-item>
110+
<e-item type="Separator"></e-item>
111+
<e-item id="annDistance" text="Distance" tooltipText="Distance" prefixIcon="e-pv-calibrate-distance-icon"></e-item>
112+
<e-item id="annPerimeter" text="Perimeter" tooltipText="Perimeter" prefixIcon="e-pv-calibrate-perimeter-icon"></e-item>
113+
<e-item id="annArea" text="Area" tooltipText="Area" prefixIcon="e-pv-calibrate-area-icon"></e-item>
114+
<e-item id="annRadius" text="Radius" tooltipText="Radius" prefixIcon="e-pv-calibrate-radius-icon"></e-item>
115+
<e-item type="Separator"></e-item>
116+
<e-item id="annNone" text="Exit" tooltipText="Exit drawing" align="Right"></e-item>
117+
</e-items>
118+
</ejs-toolbar>
119+
<ejs-pdfviewer
120+
id="container"
121+
[documentPath]="documentPath"
122+
[resourceUrl]="resourceUrl"
123+
style="height:600px;display:block">
124+
</ejs-pdfviewer>
125+
`,
126+
imports: [PdfViewerModule, ToolbarModule],
127+
providers: [ToolbarService, AnnotationService, TextSelectionService]
128+
})
129+
export class AppComponent {
130+
public documentPath: string = 'https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf';
131+
public resourceUrl: string = 'https://cdn.syncfusion.com/ej2/31.2.2/dist/ej2-pdfviewer-lib';
132+
133+
private modeMap: { [key: string]: string } = {
94134
annHighlight: 'Highlight',
95135
annUnderline: 'Underline',
96136
annStrike: 'Strikethrough',
@@ -108,51 +148,18 @@ function onToolbarClick(args) {
108148
annRadius: 'Radius',
109149
annNone: 'None'
110150
};
111-
const mode = modeMap[args.item.id];
112-
if (mode) { getViewer().annotation.setAnnotationMode(mode); }
113-
}
114151

115-
function App() {
116-
return (
117-
<>
118-
<ToolbarComponent overflowMode="Scrollable" clicked={onToolbarClick}>
119-
<ItemsDirective>
120-
<ItemDirective id="annHighlight" text="Highlight" tooltipText="Highlight" prefixIcon="e-pv-highlight-icon" />
121-
<ItemDirective id="annUnderline" text="Underline" tooltipText="Underline" prefixIcon="e-pv-underline-icon" />
122-
<ItemDirective id="annStrike" text="Strike" tooltipText="Strikethrough" prefixIcon="e-pv-strikethrough-icon" />
123-
<ItemDirective type="Separator" />
124-
<ItemDirective id="annRect" text="Rect" tooltipText="Rectangle" prefixIcon="e-pv-shape-rectangle-icon" />
125-
<ItemDirective id="annCircle" text="Circle" tooltipText="Circle" prefixIcon="e-pv-shape-circle-icon" />
126-
<ItemDirective id="annLine" text="Line" tooltipText="Line" prefixIcon="e-pv-shape-line-icon" />
127-
<ItemDirective id="annArrow" text="Arrow" tooltipText="Arrow" prefixIcon="e-pv-shape-arrow-icon" />
128-
<ItemDirective id="annPolygon" text="Polygon" tooltipText="Polygon" prefixIcon="e-pv-shape-pentagon" />
129-
<ItemDirective type="Separator" />
130-
<ItemDirective id="annFreeText" text="Free Text" tooltipText="Free Text" prefixIcon="e-pv-freetext-icon" />
131-
<ItemDirective id="annInk" text="Ink" tooltipText="Ink" prefixIcon="e-pv-inkannotation-icon" />
132-
<ItemDirective id="annSticky" text="Note" tooltipText="Sticky Note" prefixIcon="e-pv-sticky-notes" />
133-
<ItemDirective type="Separator" />
134-
<ItemDirective id="annDistance" text="Distance" tooltipText="Distance" prefixIcon="e-pv-calibrate-distance-icon" />
135-
<ItemDirective id="annPerimeter" text="Perimeter" tooltipText="Perimeter" prefixIcon="e-pv-calibrate-perimeter-icon" />
136-
<ItemDirective id="annArea" text="Area" tooltipText="Area" prefixIcon="e-pv-calibrate-area-icon" />
137-
<ItemDirective id="annRadius" text="Radius" tooltipText="Radius" prefixIcon="e-pv-calibrate-radius-icon" />
138-
<ItemDirective type="Separator" />
139-
<ItemDirective id="annNone" text="Exit" tooltipText="Exit drawing" align="Right" />
140-
</ItemsDirective>
141-
</ToolbarComponent>
142-
<PdfViewerComponent
143-
id="container"
144-
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
145-
resourceUrl="https://cdn.syncfusion.com/ej2/31.2.2/dist/ej2-pdfviewer-lib"
146-
style={{ height: '600px' }}
147-
>
148-
<Inject services={[Toolbar, Annotation, TextSelection]} />
149-
</PdfViewerComponent>
150-
</>
151-
);
152-
}
152+
getViewer() {
153+
return (document.getElementById('container') as any).ej2_instances[0];
154+
}
153155

154-
ReactDOM.createRoot(document.getElementById('sample')).render(<App />);
155-
{% endraw %}
156+
onToolbarClick(args: ClickEventArgs) {
157+
const mode = this.modeMap[args.item.id];
158+
if (mode) {
159+
this.getViewer().annotation.setAnnotationMode(mode);
160+
}
161+
}
162+
}
156163
{% endhighlight %}
157164
{% endtabs %}
158165

@@ -173,7 +180,7 @@ Note
173180
- [Remove Annotation](../annotation/delete-annotation)
174181
- [Handwritten Signature](../annotation/signature-annotation)
175182
- [Export and Import Annotation](../annotation/export-import/export-annotation)
176-
- [Annotation Permission](../annotation/annotation-permission)
183+
- [Annotations Permission](../annotation/annotation-permission)
177184
- [Annotation in Mobile View](../annotation/annotations-in-mobile-view)
178185
- [Annotation Events](../annotation/annotation-event)
179186
- [Annotation API](../annotation/annotations-api)

0 commit comments

Comments
 (0)