Developer Guide for Foxit PDF SDK for Web (7.1)
Contents
Foxit PDF SDK for Web Overview
By using Foxit PDF SDK for Web, developers can deploy and customize a Foxit PDF SDK for Web that supports viewing PDF documents within a web browser. Integrating a Foxit PDF SDK for Web into a zero-footprint web app allows end users to view PDF documents on desktop and mobile devices without installing anything.
Why Foxit PDF SDK for Web is your choice
Foxit is an Amazon-invested leading software provider of solutions for reading, editing, creating, organizing, and securing PDF documents. Foxit PDF SDK for Web is a cross-platform solution for PDF online viewing. Foxit PDF SDK for Web enterprise edition has been chosen by many of the world’s leading firms for integration into their solutions. Customers choose this product for the following reasons:
Fully customizable
Developers can easily design a unique style for their Foxit PDF SDK for Web interface, and make it consistent to their web applications.
Easy to integrate
Developers can easily reference Foxit PDF SDK for Web by referring to resource files and writing a small amount of code to display and edit PDF files, and have a wealth of interfaces to connect users and user data.
Standard and consistent annotation data
The annotations in Foxit PDF SDK for Web are consistent when viewing and editing in other applications.
Powered by Foxit’s high fidelity rendering PDF engine
The core technology of Foxit PDF SDK for Web is based on Foxit’s PDF engine, which is trusted by a large number of well-known companies. Foxit’s powerful engine makes document viewing fast and consistent in all environments.
In addition, Foxit’s products are offered with the full support of our dedicated support engineers if support and maintenance options are purchased. Updates are released on a regular basis. Foxit PDF SDK for Web will be the most cost-effective choice if you want to develop a cross-platform PDF document viewing solution that can control document distribution.
Audience and Scope
This document is primarily intended for developers who need to integrate the Foxit PDF SDK for Web into their web applications. It includes the direct reference examples as well as custom front-end APIs for customization.
Your Web Application
Foxit PDF SDK for Web provides a solution that enables a web application to view PDFs seamlessly without any plugins or local applications. Developers should prepare a PDF hosting server like Nginx, Apache or the HTTP server in Node.js platform and do the usual configuration before using Foxit PDF SDK for Web.
Evaluation
Foxit PDF SDK for Web allows users to download the trial version to evaluate the SDK. The trial version is the same as the standard version except for the 15-day limitation for free trial and the trial watermarks in the generated pages. After the evaluation period expires, customers should contact the Foxit sales team and purchase licenses to continue using Foxit PDF SDK for Web.
License
Developers are required to purchase licenses to use Foxit PDF SDK for Web in their solutions. Licenses grant users permission to release their applications based on Foxit PDF SDK for Web. However, users are prohibited to distribute any documents, sample codes, or source codes in the released packages of Foxit PDF SDK for Web to any third party without the permission from Foxit Software Incorporated.
Getting Started
Foxit PDF SDK for Web provides multi-level and rich features and interfaces which include the API without UI, simple UI rendering, UI customization, as well as application of complex UI interactions. This following sections introduces the package structure, integration, demos, and how to run the demos.
Understanding the Package Structure
Package Introduction
Foxit PDF SDK for Web provides two packages as follows:
• Light package: FoxitPDFSDKForWeb_7_1_0.zip (without font resources)
• Full package: FoxitPDFSDKForWeb_7_1_0_Full.zip (with font resources)
If you already have the font resources or only want to use online fonts, you can choose the light package. If you don’t want to make any change on the font library and don’t care the package size, the full package is your first choice.
The following image shows what folders or files are included in the two packages. They have virtually same folders except the “external” folder in the full package.
The package contains:
docs: | A folder containing API references, developer guide. |
examples: | A folder containing demos for Foxit PDF SDK for Web. |
lib: | A folder containing the source packages for SDK core libraries. |
external | A folder containing the font resources (only for full package). |
server | A folder containing http-server and the Node.js scripts for snapshot server. |
legal.txt: | Legal and copyright information. |
package.json: | Project description file. |
In the “lib” folder, it contains the files as follows:
jr-engine | A folder containing front-end rendering engine. |
locales | A folder containing the internationalized entries data. The entries for different languages is placed in different directories by name. |
PDFViewCtrl | A folder containing the plugins for PDFViewCtrl. |
stamps | Stamps templates. |
uix-addons | A folder containing the plugins for UIExtension. |
PDFViewCtrl.css | The CSS of the simple UI for SDK library. |
PDFViewCtrl.full.js | The SDK library with simple UI. |
PDFViewCtrl.js | The PDFViewCtrl library without third-party libraries. |
PDFViewCtrl.vendor.js | The third-party libraries used by PDFViewCtrl (See the lists later). |
PDFViewCtrl.polyfills.js | The script files that PDFViewCtrl relies on, used to be compliant with different browsers. |
UIExtension.css | The CSS of the UI for all the features. |
UIExtension.full.js | The full-featured SDK library. |
UIExtension.js | The UIExtension library without third-party libraries |
UIExtension.vendor.js | The third-party libraries used by UIExtension (See the lists later) |
UIExtension.polyfills.js | The script files that UIExtension relies on, used to be compliant with different browsers. |
WebPDFJRWorker.js | The script files running in the Web Worker, which are used for calling the front-end rendering engine. |
Package.json
Foxit PDF SDK for Web provides a package.json file to help developers to quickly experience the SDK product, and make it easier to be integrated into their project. The content is as follows:
{ "name": "foxit-pdf-sdk-for-web", "version": "7.1.0", "description": "Foxit pdf sdk for web.", "author": "Foxit Software Inc.", "main": "./lib/PDFViewCtrl.full.js", "scripts": { "start": "concurrently --kill-others \"npm run start-http-server\" \"npm run start-snapshot-server\"", "start-snapshot-server": "node ./server/snapshot/src/index -p 3002", "start-http-server": "node ./server/index" }, "devDependencies": { "boxen": "^4.1.0", "chalk": "^2.4.1", "concurrently": "^4.1.0", "http-proxy-middleware": "^0.19.1", "koa": "^2.7.0", "koa-body": "^4.0.4", "koa-body-parser": "^1.1.2", "koa-router": "^7.4.0", "koa2-connect": "^1.0.2", "lru-cache": "^4.1.3", "raw-body": "^2.3.3", "require-dir": "^1.0.0", "serve-handler": "^6.0.2" }, "serve": { "port": 8080, "public": "/", "proxy": { "target": "http://127.0.0.1:3002", "changeOrigin": true } } }
The third-party libraries used in Foxit PDF SDK for Web
Foxit PDF SDK for Web provides two formats of JS packages: the JS package with the third-party libraries, and the JS package without the third-party libraries. If your project has already used the same third-party libraries, you don’t need to add it for avoiding duplication.
For PDFViewCtrl.full.js package:
PDFViewCtrl.full.js – The SDK library with simple UI.
PDFViewCtrl.polyfills.js – The script files that PDFViewCtrl relies on, used to be compliant with different browsers.
PDFViewCtrl.vendor.js – The third-party libraries used by PDFViewCtrl (See the lists later).
PDFViewCtrl.js – The PDFViewCtrl library without third-party libraries.
So that, (PDFViewCtrl.polyfills.js + PDFViewCtrl.vendor.js + PDFViewCtrl.js) = PDFViewCtrl.full.js.
The following two forms are equivalent:
Form 1:
<script src="../FoxitPDFSDKForWeb/lib/PDFViewCtrl.full.js"></script>
Form 2:
<script src="../FoxitPDFSDKForWeb/lib/PDFViewCtrl.polyfills.js"></script> <script src="../FoxitPDFSDKForWeb/lib/PDFViewCtrl.vendor.js"></script> <script src="../FoxitPDFSDKForWeb/lib/PDFViewCtrl.js"></script>
The PDFViewCtrl.vendor.js contains the following third-party libraries:
jquery
i18next
i18next-chained-backend
i18next-localstorage-backend
i18next-xhr-backend
jquery-contextmenu
dialog-polyfill
hammerjs
eventemitter3
For UIExtension.full.js package:
UIExtension.full.js – The full-featured SDK library
UIExtension.polyfills.js – The script files that UIExtension relies on, used to be compliant with different browsers.
UIExtension.js – The UIExtension library without third-party libraries
UIExtension.vendor.js – The third-party libraries used by UIExtension (See the lists later)
So that, (UIExtension.polyfills.js + UIExtension.vendor.js + UIExtension.js) = UIExtension.full.js.
The following two forms are equivalent:
Form 1:
<script src="../FoxitPDFSDKForWeb/lib/UIExtension.full.js"></script>
Form 2:
<script src="../FoxitPDFSDKForWeb/lib/UIExtension.polyfills.js"></script> <script src="../FoxitPDFSDKForWeb/lib/UIExtension.vendor.js"></script> <script src="../FoxitPDFSDKForWeb/lib/UIExtension.js"></script>
The UIExtension.vendor.js contains the following third-party libraries:
jquery
i18next
i18next-chained-backend
i18next-localstorage-backend
i18next-xhr-backend
dialog-polyfill
hammerjs
eventemitter3
spectrum-colorpicker
file-saver
Integration
This section will introduce how to integrate Foxit PDF SDK for Web to your project.
Integrate as a Global Variable
You can integrate the Foxit PDF SDK for Web to your project as a global variable:
<script src="./lib/PDFViewCtrl.full.js"></script> var PDFViewer = PDFViewCtrl.PDFViewer; var pdfViewer = new PDFViewer(…)
Integrate as module
You can integrate the Foxit PDF SDK for Web to your project by module.
ES Modules (ESM)
Configure babelrc:
{ "presets": ["env", "stage-0"] }
Configure webpack loader:
rules: [ { test: /\.js$/, loader: 'babel-loader' }, ],
Import the library:
import {PDFViewer} from './FoxitPDFSDKForWeb/lib/PDFViewCtrl.full'; var pdfViewer = new PDFViewer(…)
CommonJS
Import the library:
var PDFViewCtrl = require('./FoxitPDFSDKForWeb/lib/PDFViewCtrl.full'); var pdfviewer = new PDFViewCtrl.PDFViewer(...);
The import way of CommonJS is simple, so that it doesn’t need additional configuration of webpack.
AMD
define('your-module-name', ['./FoxitPDFSDKForWeb/lib/PDFViewCtrl.full'], function(PDFViewerModule) { var pdfviewer = new PDFViewCtrl.PDFViewer(...); });
webpack configuration:
module.exports = { context: __dirname + 'point to the dir your app code is in', entry: 'your entry file path', output: { path: 'The path for the output built files', // ... }, // It is used to support the older versions of jquery that you might not need. amd: { jQuery: true }, module: { // loaders }, resolve: { root: [], alias: { } } };
Convenient dependency import
The above methods all use the relative path when integrating PDFViewCtrl module, but it is not easy to use the relative path to import multiple files. In this case, convenient dependency import might be a good choice. Please follow the steps below.
1) Add npm package declaration “package.json” for the unzipped package of Foxit PDF SDK for Web
lib/package.json:
{ "name": "foxitwebsdk", "version": "7.0.0", "description": "", "main": "PDFViewCtrl.full.js", // Point to the Foxit PDF SDK for Web library that you need to reference. "scripts": { }, }
2) Add the Foxit PDF SDK for Web dependencies in the package.json file of your project
"dependencies": { "foxitweb": "file:./FoxitPDFSDKForWeb/lib" },
3) Run “npm install” to install the dependencies.
4) Import and use.
// EMS import {PDFViewer} from 'foxitweb'; var pdfViewer = new PDFViewer(…); // or CommonJS var PDFViewCtrl = require('foxitweb'); var pdfviewer = new PDFViewCtrl.PDFViewer(...);
Quickly run Foxit PDF SDK for Web Demos
To run Foxit PDF SDK for Web Demos, you should prepare a web server at first. In this guide, we will introduce the demos and then take the Nginx and Node.js servers as examples to show you how to quickly run Foxit PDF SDK for Web demos.
Introduction to the Demos
In the “examples” folder, it provides multiple demos as references for users. After starting the http server, you can access and experience the demos in the browser by typing the corresponding address.
• A full-featured PDF viewer demo
It is a ready-to-go demo that you can integrate it into your project with all of the featured provided by Foxit PDF SDK for Web. This demo uses the full-featured package “UIExtension.full.js” (in the “lib” folder) including the PDF view and document parsing. You can get the source code of this demo from “examples/UIExtension/advanced_webViewer/index.html”.
In the browser, quickly access the demo at: http://localhost:{port}/examples/UIExtension/advanced_webViewer/index.html
• A simple UI demo
It is a simple UI demo that demonstrates how to call Foxit PDF SDK for Web API to load a PDF document, and zoom in/out the document. This demo uses the “PDFViewCtrl.full.js” package in the “lib” folder. You can get the source code of this demo from “examples/PDFViewCtrl/basic_webViewer/index.html”.
In the browser, quickly access the demo at: http://localhost:{port}/examples/PDFViewCtrl/basic_webViewer/index.html
• Offline demo
This demo is a sample that demonstrates how to register the “service-worker.js” found in the “examples/PDFViewCtrl/service-worker” folder to better cache the core dependency files “gsdk.js” and font files in a browser supported by the service worker, in order to speed up the file secondary opening or use the offline mode. You can get the source code of this demo from “examples/PDFViewCtrl/service-worker/cache.html “.
In the browser, quickly access the demo at: http://localhost:{port}/examples/PDFViewCtrl/service-worker/cache.html
• Inline DIV application demo
This demo renders the simple UI of Foxit PDF SDK for Web to a div container with a specified size. You can get the source code of this demo from “examples/PDFViewCtrl/div/index.html”.
In the browser, quickly access the demo at: http://localhost:{port}/examples/PDFViewCtrl/div/index.html
Nginx working sample
Using Windows as an example, assume that Nginx was installed on your system already. When you have Nginx server running, you can directly modify the ‘nginx.conf’ in the conf directory, here we directly write a configuration file to make Foxit PDF SDK for Web Demo run. Please follows the steps below:
1) Download FoxitPDFSDKForWeb_7_1_0.zip.
2) Unzip it to a new folder like “FoxitPDFSDKForWeb” in ‘D:/’ directory for example.
3) Create a Nginx configuration file in a location. For example, create a new ‘webpdf.conf’ file inside ‘D:/FoxitPDFSDKForWeb’.
4) Set up a virtual server and configure a location. The following configuration is an example. The ‘D:/FoxitPDFSDKForWeb/’ is the path to the SDK.
server { listen 8080; server_name 127.0.0.1; location / { alias "D:/FoxitPDFSDKForWeb/"; charset utf8; index index.html; } }
5) Locate to the installed path of Nginx, find the ‘nginx.conf’ in the conf directory, use include directive to reference the contents of the new configuration file.
include D:/FoxitPDFSDKForWeb/webpdf.conf;
6) For changes to the configuration file to take effect, you need to restart the nginx server or use ‘nginx -s reload’ to upgrade the configuration without interrupting the processing of current requests.
7) Access the demos in the browser.
For the full-featured PDF viewer demo, please access the page at http://127.0.0.1:8080/examples/UIExtension/advanced_webViewer/index.html.
For the simple UI demo, please access the page at http://127.0.0.1:8080/examples/PDFViewCtrl/basic_webViewer/index.html.
Note: You can run the demo according to the above configuration, but at that time the snapshot feature cannot work correctly. The snapshot cannot be cached to clipboard, so that you cannot paste it to the location as you wish. Please follow the steps below to build the snapshot server:
a) Install node.js 9.0 or higher, if it is already installed, skip it.
b) In a command prompt, navigate to the root directory (“D:/FoxitPDFSDKForWeb”), type “npm install” to install the required dependencies, and then type “npm run start-snapshot-server” to start the snapshot server (the default port is 3002).
Note: If you want to specify the port for snapshot server as desired, you can change it in the “server/snapshot/package.json” file of Foxit PDF SDK for Web package. To find the default port 3002 as below, and change it as you wish:
"start": "node src/index -p 3002"
c) Configure Nginx reverse proxy in the ‘webpdf.conf’ file under ‘D:/FoxitPDFSDKForWeb’ folder.
server { listen 8080; server_name 127.0.0.1; location / { alias "D:/FoxitPDFSDKForWeb/"; charset utf8; index index.html; } location ~ ^/snapshot/(.+)$ { proxy_pass http://127.0.0.1:3002/snapshot/$1$is_args$args; proxy_redirect off; proxy_request_buffering on; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
d) Restart Nginx server, and refresh your browser, the snapshot feature can work correctly.
Node.js working sample
Assume that Node.js 9.0 or higher is available on your system already. Then follow the steps below to run the Foxit PDF SDK for Web demos:
1) Download FoxitPDFSDKForWeb.zip.
2) Unzip it to a new folder like “FoxitPDFSDKForWeb” in ‘D:/’ directory for example.
3) In the command prompt, navigate to the above unzipped folder (“D:/FoxitPDFSDKForWeb”), type “npm install” to install the required dependencies, and then type “npm start” to start http-server.
4) Access the demos in the browser.
For the full-featured PDF viewer demo, please access the page at
http://127.0.0.1:8080/examples/UIExtension/advanced_webViewer/index.html.
For the simple UI demo, please access the page at http://127.0.0.1:8080/examples/PDFViewCtrl/basic_webViewer/index.html.
Note: Using this method, you do not need to configure the proxy, the snapshot feature can be used normally. If you want to specify the ports for http-server and snapshot server as desired, you can change the two ports in the “package.json” file of Foxit PDF SDK for Web package.
To change the port for http-server, find the default port 8080 as below, and change it as you wish:
"serve": { "port": 8080, "public": "/", "proxy": { "target": "http://127.0.0.1:3002", "changeOrigin": true } }
To change the port for snapshot server, find the default port 3002 as below, and change it as you wish: (there are two places that need to be changed.)
"start-snapshot-server": "node ./server/snapshot/src/index -p 3002", "serve": { "port": 8080, "public": "/", "proxy": { "target": "http://127.0.0.1:3002", "changeOrigin": true } }
Building a new web project
This section will help you to quickly get started with using Foxit PDF SDK for Web to build a simple PDF viewer and a full-featured PDF viewer with step-by-step instructions provided.
Preparations
Create a new web project
a) Create a new directory as a project folder, such as “D:/test_web”.
b) Copy the “lib”, “server” folders and the “package.json” file from Foxit PDF SDK for Web package to “D:/test_web”.
c) Copy a PDF file (for example, the demo guide in the “docs” folder) to “D:/test_web”.
d) Create an html file (index.html) in the “D:/test_web” folder. Then the directory structure is:
test_web +-- lib (copy from the Foxit PDF SDK for Web package) +-- server (copy from the Foxit PDF SDK for Web package) +-- package.json (copy from the Foxit PDF SDK for Web package) +-- index.html
The whole content of the index.html is:
<html> <head> <meta charset="utf-8"> <style> .fv__ui-tab-nav li span { color: #636363; } .flex-row { display: flex; flex-direction: row; } </style> <!-- ignore other unimportant code --> </head> <body> </body> </html>
Start Http-Server
You can refer to section 2.3.2 “Nginx working sample” or section 2.3.3 “Node.js working sample” to start the http-server. In this project, we use the default port 8080.
Then, access http://127.0.0.1:8080/index.html in the browser, and you will see a blank page, which indicates that the preparations have been completed.
Integrate the simple demo using PDFViewCtrl
This section will describe how to integrate the simple demo using PDFViewCtrl based on the above create project. Just follow the steps below:
a) Add a style (/lib/PDFViewCtrl.css) to the <head> tag of the HTML page.
<link rel="stylesheet" type="text/css" href="./lib/PDFViewCtrl.css">
b) Import the “PDFViewCtrl.full.js” library found in the “lib” folder:
<script src="./lib/PDFViewCtrl.full.js"></script>
c) In the HTML <body> tag, add the <div> elements as the web viewer container:
<div id="pdf-viewer"></div>
d) Initialize the Foxit PDF SDK for Web:
<script> var licenseSN = "Your license SN"; var licenseKey = "Your license Key"; </script> <script> var PDFViewer = PDFViewCtrl.PDFViewer; var pdfViewer = new PDFViewer({ libPath: './lib', // the library path of Web SDK. jr: { licenseSN: licenseSN, licenseKey: licenseKey, } }); pdfViewer.init('#pdf-viewer'); // the div (id="pdf-viewer") <script>
Note: The trial values of licenseSN and licenseKey can be found in the “example/license-key.js” file of Foxit PDF SDK for Web package.
e) Open a PDF document:
// modify the file path as your need. fetch('/FoxitPDFSDKforWeb_DemoGuide.pdf').then(function(response) { response.arrayBuffer().then(function(buffer) { pdfViewer.openPDFByFile(buffer); }) })
f) The above steps are the key points of integrating the simple demo to your created project using PDFViewCtrl. After finishing it, refresh your browser (http://127.0.0.1:8080/index.html), and then you can see the demo guide as follows:
Now, it is a simple web PDF viewer, you can zoom in/out the PDF document by right-clicking anywhere on the page to select the zoom in or zoom out options.
The whole content of the index.html is:
<html> <head> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="./lib/PDFViewCtrl.css"> <!-- You can delete the following style because it doesn't work in this project --> <style> .fv__ui-tab-nav li span { color: #636363; } .flex-row { display: flex; flex-direction: row; } </style> <!-- ignore other unimportant code --> </head> <body> <div id="pdf-viewer"></div> <script src="./lib/PDFViewCtrl.full.js"></script> <script> var licenseSN = "Your license SN"; var licenseKey = "Your license Key"; </script> <script> var PDFViewer = PDFViewCtrl.PDFViewer; var pdfViewer = new PDFViewer({ libPath: './lib', // the library path of Web SDK. jr: { licenseSN: licenseSN, licenseKey: licenseKey, } }); pdfViewer.init('#pdf-viewer'); // the div (id="pdf-viewer") // modify the file path as your need. fetch('/FoxitPDFSDKforWeb_DemoGuide.pdf').then(function (response) { response.arrayBuffer().then(function (buffer) { pdfViewer.openPDFByFile(buffer); }) }) </script> </body> </html>
Integrate the full-featured PDF viewer using UIExtension
The previous section integrates the simple demo using PDFViewCtrl, which is just a simple web PDF viewer. In this section, we will show you how to integrate the full-featured PDF viewer using UIExtension based on the created project in section 3.3.1. Just follow the steps below:
a) Add a style (/lib/UIExtension.css) to the <head> tag of the HTML page.
<link rel="stylesheet" type="text/css" href="./lib/UIExtension.css">
b) Import the “UIExtension.full.js” library found in the “lib” folder:
<script src="./lib/UIExtension.full.js"></script>
c) In the HTML <body> tag, add the <div> elements as the web viewer container:
<div id="pdf-ui"></div>
d) Initialize the Foxit PDF SDK for Web:
<script> var licenseSN = "Your license SN"; var licenseKey = "Your license Key"; </script> <script> var pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui' // the div (id="pdf-ui"). }); <script>
Note: The trial values of licenseSN and licenseKey can be found in the “example/license-key.js” file of Foxit PDF SDK for Web package.
e) Open a PDF document:
// modify the file path as your need. fetch('/FoxitPDFSDKforWeb_DemoGuide.pdf').then(function(response) { response.arrayBuffer().then(function(buffer) { pdfui.openPDFByFile(buffer); }) f})
f) The above steps are the key points of integrating the full-featured PDF viewer to your created project using UIExtension. After finishing it, refresh your browser (http://127.0.0.1:8080/index.html), and then you can see the demo guide as follows:
Now, it is a full-featured web PDF viewer, you can view/edit/comment/protect the PDF document as desired.
The whole content of the index.html is:
<html> <head> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="./lib/UIExtension.css"> <style> .fv__ui-tab-nav li span { color: #636363; } .flex-row { display: flex; flex-direction: row; } </style> <!-- ignore other unimportant code --> </head> <body> <div id="pdf-ui"></div> <script src="./lib/UIExtension.full.js"></script> <script> var licenseSN = "Your license SN"; var licenseKey = "Your license Key"; </script> <script> var pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui' // the div (id="pdf-ui"). }); // modify the file path as your need. fetch('/FoxitPDFSDKforWeb_DemoGuide.pdf').then(function (response) { response.arrayBuffer().then(function (buffer) { pdfui.openPDFByFile(buffer); }) }) </script> </body> </html>
Integrate the add-ons of UIExtension
Foxit PDF SDK for Web provides some extension features for UIExtension, such as file property, multi-media, password protection, redaction, PDF path objects, print, text object, importing/exporting form, and full screen. To integrate these add-ons, you should add the code snippets below:
addons: [ './lib/uix-addons/file-property/', // should use the relative path. './lib/uix-addons/multi-media/', './lib/uix-addons/password-protect/', './lib/uix-addons/redaction/', './lib/uix-addons/path-objects/', './lib/uix-addons/print/', './lib/uix-addons/text-object', './lib/uix-addons/import-form', './lib/uix-addons/export-form', './lib/uix-addons/full-screen' ] });
Based on the full-featured PDF viewer project in section 3.3, update the index.html as follows:
<html> <head> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="./lib/UIExtension.css"> <style> .fv__ui-tab-nav li span { color: #636363; } .flex-row { display: flex; flex-direction: row; } </style> <!-- ignore other unimportant code --> </head> <body> <div id="pdf-ui"></div> <script src="./lib/UIExtension.full.js"></script> <script> var licenseSN = "Your license SN"; var licenseKey = "Your license Key"; </script> <script> var pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). addons: [ './lib/uix-addons/file-property/', // should use the relative path. './lib/uix-addons/multi-media/', './lib/uix-addons/password-protect/', './lib/uix-addons/redaction/', './lib/uix-addons/path-objects/', './lib/uix-addons/print/', './lib/uix-addons/text-object', './lib/uix-addons/import-form', './lib/uix-addons/export-form', './lib/uix-addons/full-screen' ] }); // modify the file path as your need. fetch('/FoxitPDFSDKforWeb_DemoGuide.pdf').then(function (response) { response.arrayBuffer().then(function (buffer) { pdfui.openPDFByFile(buffer); }) }) </script> </body> </html>
Refresh your browser (http://127.0.0.1:8080/index.html), and then you can see a web PDF viewer with the extension features. For example, for the Home tab, the file property, print, and import/export form features have been integrated as follows:
Make the project adaptive to the device
Foxit PDF SDK for Web can allow the project to be adaptive to the device (desktop or mobile), which means if you access the project in your desktop browser, it will be present using the desktop UI layout, and if you access the project in your mobile browser, it will be present using the mobile UI layout. To make the project adaptive to the device, based on the Integrate the add-ons of UIExtension in section 3.4, update the index.html as follows:
<html> <head> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="./lib/UIExtension.css"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"> <!-- default(white), black, black-translucent --> <meta name="apple-mobile-web-app-status-bar-style" content="default" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-touch-fullscreen" content="yes" /> <meta name="apple-mobile-web-app-title" content="Foxit PDF SDK for Web"> <meta name="App-Config" content="fullscreen=yes,useHistoryState=no,transition=no"> <meta name="format-detaction" content="telephone=no,email=no"> <meta http-equiv="Cache-Control" content="no-siteapp" /> <meta name="HandheldFriendly" content="true"> <meta name="MobileOptimized" content="750"> <meta name="screen-orientation" content="portrait"> <meta name="x5-orientation" content="portrait"> <meta name="full-screen" content="yes"> <meta name="x5-fullscreen" content="true"> <meta name="browsermode" content="application"> <meta name="x5-page-mode" content="app"> <meta name="msapplication-tap-highlight" content="no"> <meta name="renderer" content="webkit"> <!-- Add the adaptive.js --> <script src="./lib/adaptive.js"></script> <style> .fv__ui-tab-nav li span { color: #636363; } .flex-row { display: flex; flex-direction: row; } </style> </head> <body> <div id="pdf-ui"></div> <script src="./lib/UIExtension.full.js"></script> <script> var licenseSN = "Your license SN"; var licenseKey = "Your license Key"; </script> <script> var pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). appearance: UIExtension.appearances.adaptive, addons: [ './lib/uix-addons/file-property/', // should use the relative path. './lib/uix-addons/multi-media/', './lib/uix-addons/password-protect/', './lib/uix-addons/redaction/', './lib/uix-addons/path-objects/', './lib/uix-addons/print/', './lib/uix-addons/text-object', './lib/uix-addons/import-form', './lib/uix-addons/export-form', './lib/uix-addons/full-screen' ] }); // modify the file path as your need. fetch('/FoxitPDFSDKforWeb_DemoGuide.pdf').then(function (response) { response.arrayBuffer().then(function (buffer) { pdfui.openPDFByFile(buffer); }) }) </script> </body> </html>
For example, assume the IP address of your computer is 10.203.25.23, so that access the project in mobile browser (http://10.203.25.23:8080/index.html), and then you can see a mobile PDF viewer as follows:
Customizing the UI
From version 7.0, Foxit PDF SDK for Web comes with built-in UI design including the feature modules UI, which are implemented using Foxit PDF SDK for Web and are shipped in the UIExtension.js. Furthermore, customizing UI is straightforward. Foxit PDF SDK for Web provides a rich set of APIs for developers to customize and style the appearance of your web viewer.
The user interface of UIExtension consists of two parts: template and fragments. Template is equivalent to the extension of HTML, the components in the template should be declared by tags. Template is used to customize the UI layout (css style, icon, text, and so on) without interactions. Fragments are a set of UI snippets, which can be used to customize the configuration items and interaction logic of the components in the template. Each snippets has an operation type “action” that specifies the action mode (append, prepend, before, after, ext, replace, insert, and remove, the default is ext.) of the snippets. Through these action modes, you can insert, delete, replace and modify the components in the template.
For all the built-in components used in the following examples, please refer to the section 4.4 “Understanding the built-in components“.
This section provides two standard types of code for the examples: ES6 and ES5. If you want to run the examples in IE browser, please refer to the ES5 code.
Customize the UI layout using template
Template is mainly used to customize the UI layout of the components. Following will list some examples to demonstrate the usage of template. Please note that all the examples are based on the full-featured PDF viewer project in section 3.3.
Create a simple template
A simplest template is as follows:
For ES6:
let pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). template: ` <webpdf> <viewer></viewer> </webpdf> ` });
For ES5:
var pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). template: [ '<webpdf>', ' <viewer></viewer>', '</webpdf>' ].join('') });
• <webpdf> tag listens the document state (open or not) to control enabling or disabling the UI components. If you need these features, you can use other html tags or custom component tags to replace it.
• <viewer> tag is where the PDF contents are rendered. Each template must have a <viewer> tag. It can be placed anywhere you want, please refer to the examples in the following sections.
Refresh your browser (http://127.0.0.1:8080/index.html), and then you can see a simple PDF web viewer as follows:
Add a new toolbar button
Use <toolbar> tag to add a new toolbar button.
For ES6:
let pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). template: ` <webpdf> <toolbar> <open-file-dropdown></open-file-dropdown> </toolbar> <viewer></viewer> </webpdf> ` });
For ES5:
var pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). template: [ '<webpdf>', ' <toolbar>', ' <open-file-dropdown></open-file-dropdown>', ' </toolbar>', ' <viewer></viewer>', '</webpdf>' ].join('') });
Refresh your browser (http://127.0.0.1:8080/index.html), and then you can see the new toolbar button as follows:
Add a new tab page
Use <tabs> and <tab> tags to add a new tab page.
For ES6:
let pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). template: ` <webpdf> <toolbar> <tabs> <tab title="Home"> <open-file-dropdown></open-file-dropdown> </tab> <tab title="Comment"> <div class="flex-row"> <create-strikeout-button></create-strikeout-button> <create-underline-button></create-underline-button> <create-squiggly-button></create-squiggly-button> <create-replace-button></create-replace-button> <create-caret-button></create-caret-button> <create-note-button></create-note-button> </div> </tab> </tabs> </toolbar> <viewer></viewer> </webpdf> ` });
For ES5:
var pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). template: [ '<webpdf>', ' <toolbar>', ' <tabs>', ' <tab title="Home">', ' <open-file-dropdown></open-file-dropdown>', ' </tab>', ' <tab title="Comment">', ' <div class="flex-row">', ' <create-strikeout-button></create-strikeout-button>', ' <create-underline-button></create-underline-button>', ' <create-squiggly-button></create-squiggly-button>', ' <create-replace-button></create-replace-button>', ' <create-caret-button></create-caret-button>', ' <create-note-button></create-note-button>', ' </div>', ' </tab>', ' </tabs>', ' </toolbar>', ' <viewer></viewer>', '</webpdf>' ].join('') });
Refresh your browser (http://127.0.0.1:8080/index.html), and then you can see the new tab page as follows:
Add a sidebar button
Use <sidebar> tag to add a sidebar button.
For ES6:
let pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). template: ` <webpdf> <toolbar> <tabs> <tab title="Home"> <open-file-dropdown></open-file-dropdown> </tab> <tab title="Comment"> <div class="flex-row"> <create-strikeout-button></create-strikeout-button> <create-underline-button></create-underline-button> <create-squiggly-button></create-squiggly-button> <create-replace-button></create-replace-button> <create-caret-button></create-caret-button> <create-note-button></create-note-button> </div> </tab> </tabs> </toolbar> <div class="flex-row"> <sidebar> <bookmark-sidebar-panel></bookmark-sidebar-panel> </sidebar> <viewer></viewer> </div> </webpdf> ` });
For ES5:
var pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). template: [ '<webpdf>', ' <toolbar>', ' <tabs>', ' <tab title="Home">', ' <open-file-dropdown></open-file-dropdown>', ' </tab>', ' <tab title="Comment">', ' <div class="flex-row">', ' <create-strikeout-button></create-strikeout-button>', ' <create-underline-button></create-underline-button>', ' <create-squiggly-button></create-squiggly-button>', ' <create-replace-button></create-replace-button>', ' <create-caret-button></create-caret-button>', ' <create-note-button></create-note-button>', ' </div>', ' </tab>', ' </tabs>', ' </toolbar>', ' <div class="flex-row">', ' <sidebar>', ' <bookmark-sidebar-panel></bookmark-sidebar-panel>', ' </sidebar>', ' <viewer></viewer>', ' </div>', '</webpdf>' ].join('') });
Refresh your browser (http://127.0.0.1:8080/index.html), and then you can see the bookmark sidebar as follows:
Built-in layout template
The built-in layout template for Foxit PDF SDK for Web is shown below. You can modify this template directly to customize the UI layout as desired.
<webpdf> <toolbar name="toolbar" class="fv__ui-toolbar-scrollable"> <tabs name="toolbar-tabs"> <tab title="toolbar.tabs.home.title" name="home-tab"> <group-list name="home-toolbar-group-list"> <group name="home-tab-group-hand" retain-count="3"> <hand-button></hand-button> <selection-button></selection-button> <snapshot-button></snapshot-button> </group> <group name="home-tab-group-io" retain-count="1" shrink-title="toolbar.more.document.title"> <open-file-dropdown></open-file-dropdown> <download-file-button></download-file-button> <print:print-button></print:print-button> </group> <group name="home-tab-group-nav" retain-count="3"> <goto-prev-page-button></goto-prev-page-button> <goto-next-page-button></goto-next-page-button> <goto-page-input></goto-page-input> </group> <group name="home-tab-group-zoom"> <zoom-out-button></zoom-out-button> <zoom-in-button></zoom-in-button> <editable-zoom-dropdown></editable-zoom-dropdown> </group> <group name="home-tab-group-page" retain-count="1"> <single-page-button></single-page-button> <continuous-page-button></continuous-page-button> <facing-page-button></facing-page-button> <continuous-facing-page-button></continuous-facing-page-button> </group> <group name="home-tab-group-magnifier"> <loupe-tool-button></loupe-tool-button> </group> <group name="home-tab-group-marquee"> <marquee-tool-button></marquee-tool-button> </group> <group name="home-tab-group-form" retain-count="2"> <import-form-module:import-form-button></import-form-module:import-form-button> <export-form-module:export-form-dropdown></export-form-module:export-form-dropdown> </group> <group name="file-property" @require-module="fpmodule"> <fpmodule:file-property-button></fpmodule:file-property-button> </group> </group-list> </tab> <tab title="toolbar.tabs.comment.title" name="comment-tab"> <group-list name="comment-toolbar-group-list"> <group name="comment-tab-group-hand" retain-count="3"> <hand-button></hand-button> <selection-button></selection-button> <zoom-dropdown></zoom-dropdown> </group> <group name="comment-tab-group-note" retain-count="3"> <create-note-button></create-note-button> </group> <group name="comment-tab-group-mark"> <create-text-highlight-button></create-text-highlight-button> <create-strikeout-button></create-strikeout-button> <create-underline-button></create-underline-button> <create-squiggly-button></create-squiggly-button> <create-replace-button></create-replace-button> <create-caret-button></create-caret-button> </group> <group name="comment-tab-group-text"> <create-typewriter-button></create-typewriter-button> <create-callout-button></create-callout-button> <create-textbox-button></create-textbox-button> </group> <group name="comment-tab-group-drawing" retain-count="2"> <create-drawings-dropdown></create-drawings-dropdown> <create-area-highlight-button></create-area-highlight-button> </group> <group name="comment-tab-group-pencil" retain-count="2"> <create-pencil-button></create-pencil-button> <eraser-button></eraser-button> </group> <group name="comment-tab-group-stamp"> <stamp-dropdown></stamp-dropdown> </group> <group name="comment-tab-group-measurement"> <create-distance-button></create-distance-button> </group> <group name="comment-tab-group-media"> <create-attachment-button></create-attachment-button> <create-image-button></create-image-button> <create-link-button></create-link-button> <multi-media:multi-media-button></multi-media:multi-media-button> </group> <group name="comment-tab-group-inksign" visible='false'></group> <group name="comment-tab-group-other" visible='false'></group> </group-list> </tab> <tab title="toolbar.tabs.edit.title" name="edit-tab" visible="true" @device="desktop"> <group-list name="edit-toolbar-group-list"> <group name="edit-tab-group-hand" retain-count="3"> <hand-button></hand-button> <selection-button></selection-button> <zoom-dropdown></zoom-dropdown> </group> <group name="edit-tab-group-mode" retain-count="3"> <edit-pageobjects:edit-all-objects-button></edit-pageobjects:edit-all-objects-button> <add-image-button></add-image-button> <edit-pageobjects:path-objects-dropdown></edit-pageobjects:path-objects-dropdown> <!--<edit-image-button></edit-image-button>--> <edit-text-object:add-text-button></edit-text-object:add-text-button> </group> <group name="edit-tab-group-font" retain-count="5"> <edit-text-object:text-bold-style-button></edit-text-object:text-bold-style-button> <edit-text-object:text-italic-style-button></edit-text-object:text-italic-style-button> <edit-text-object:font-color-picker></edit-text-object:font-color-picker> <edit-text-object:font-style-dropdown></edit-text-object:font-style-dropdown> </group> <group name="edit-tab-group-layer" visible="false"></group> <group name="edit-tab-group-redact" visible="false"></group> </group-list> </tab> <tab title="toolbar.tabs.protect.title" name="protect-tab" visible="true"> <group-list name="protect-toolbar-group-list"> <group name="protect-tab-group-hand" retain-count="4"> <hand-button></hand-button> <selection-button></selection-button> <zoom-dropdown></zoom-dropdown> </group> <group name="protect-tab-group-sign" retain-count="4"> <ink-sign-dropdown></ink-sign-dropdown> </group> <group name="password-protect-group" retain-count="2"> <password-protect:password-protect-button></password-protect:password-protect-button> <password-protect:remove-protect-button></password-protect:remove-protect-button> </group> <group name="redaction"> <redaction:create-redactions-dropdown></redaction:create-redactions-dropdown> <redaction:apply-redactions-button></redaction:apply-redactions-button> <redaction:redaction-search-button></redaction:redaction-search-button> </group> </group-list> </tab> </tabs> </toolbar> <div class="fv__ui-body"> <sidebar name="sidebar" @controller="sidebar:SidebarController"> <bookmark-sidebar-panel></bookmark-sidebar-panel> <commentlist-sidebar-panel></commentlist-sidebar-panel> <thumbnail-sidebar-panel></thumbnail-sidebar-panel> <layer-sidebar-panel></layer-sidebar-panel> <search-sidebar-panel></search-sidebar-panel> <attachment-sidebar-panel></attachment-sidebar-panel> </sidebar> <distance:ruler-container name="pdf-viewer-container-with-ruler"> <slot> <viewer @zoom-on-wheel @touch-to-scroll></viewer> </slot> </distance:ruler-container> </div> <template name="template-container"> <create-stamp-dialog></create-stamp-dialog> <print:print-dialog></print:print-dialog> <loupe-tool-dialog></loupe-tool-dialog> <create-ink-sign-dialog></create-ink-sign-dialog> <measurement-popup></measurement-popup> <fpmodule:file-property-dialog></fpmodule:file-property-dialog> <redaction:redaction-page-dialog></redaction:redaction-page-dialog> <!-- contextmenus --> <page-contextmenu></page-contextmenu> <default-annot-contextmenu></default-annot-contextmenu> <markup-contextmenu></markup-contextmenu> <default-annot-contextmenu name="fv--caret-contextmenu"></default-annot-contextmenu> <textmarkup-contextmenu name="fv--highlight-contextmenu"></textmarkup-contextmenu> <textmarkup-contextmenu name="fv--strikeout-contextmenu"></textmarkup-contextmenu> <textmarkup-contextmenu name="fv--underline-contextmenu"></textmarkup-contextmenu> <textmarkup-contextmenu name="fv--squiggly-contextmenu"></textmarkup-contextmenu> <freetext-contextmenu name="fv--typewriter-contextmenu"></freetext-contextmenu> <freetext-contextmenu name="fv--callout-contextmenu"></freetext-contextmenu> <freetext-contextmenu name="fv--textbox-contextmenu"></freetext-contextmenu> <action-annot-contextmenu name="fv--image-contextmenu"></action-annot-contextmenu> <action-annot-contextmenu name="fv--link-contextmenu"></action-annot-contextmenu> <comment-card-contextmenu></comment-card-contextmenu> <fileattachment-contextmenu></fileattachment-contextmenu> <media-contextmenu></media-contextmenu> <redact-contextmenu></redact-contextmenu> </template> </webpdf>
Customize the UI using fragments
Fragments are a set of UI snippets. It can be used to customize the configuration items and interaction logic of the components in the template.
Create a new drop-down menu item
The sample code below creates a new drop-down menu including two drop-down buttons, and append it to the end of the list of children of the group component with the name of “home-tab-group-hand”.
To get the name of a target component (only for widget), you can right-click the component in the browser, choose “Inspect”, and then find the value of the “component-name” attribute in the corresponding <a> tag. For a container component, for example,
"target: 'home-tab-group-hand',"
you can right-click one of the subcomponents in the browser, choose “Inspect”, and then find the value of the “component-name” attribute in the related <div> tag.
For ES6:
var pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). fragments: [{ // Add a component to the end of the list of children of a specified target component. action: UIExtension.UIConsts.FRAGMENT_ACTION.APPEND, // Specify the name of the target component that the new components defined in the above template will be appended to. All the target names of fragments are defined in the layout template. target: 'home-tab-group-hand', // Define the properties of the added component, such as icon, text, and css style. template: ` <dropdown icon-class="fv__icon-toolbar-stamp"> <dropdown-button name="show-hello-button" icon-class="fv__icon-toolbar-hand">say hello</dropdown-button> <dropdown-button name="select-pdf-file-button" accept=".pdf" file-selector icon-class="fv__icon-toolbar-open">open</dropdown-button> </dropdown> `, // Define the interaction logic of the added component. config: [{ // specify the component in the above template that the configuration will be applied to. // For example, the configuration will be applied to the component with the name of "show-hello-button". target: 'show-hello-button', callback: function () { alert('hello'); } }, { // The configuration will be applied to the component with the name of "select-pdf-file-button" which is defined in the above template of fragments. target: 'select-pdf-file-button', // Extend Controller, and implement the handle function. callback: class extends UIExtension.Controller { // the lifecycle method: mounted. It will be called after appending the component into the DOM tree. mounted() { // Get the component mounted by the current Controller instance console.info(this.component, 'mounted'); } handle(selectedFile) { alert(selectedFile.name); } } }] }] });
For ES5:
function CustomController() { UIExtension.Controller.apply(this, arguments); } CustomController.prototype = Object.create(UIExtension.Controller.prototype, { constructor: { value: CustomController } }); Object.assign(CustomController.prototype, { mounted: function () { console.info(this.component, 'mounted'); }, handle: function (selectedFile) { alert(selectedFile.name); } }); var pdfui = new UIExtension.PDFUI({ viewerOptions: { libPath: './lib', // the library path of web sdk. jr: { licenseSN: licenseSN, licenseKey: licenseKey } }, renderTo: '#pdf-ui', // the div (id="pdf-ui"). fragments: [{ // Add a component to the end of the list of children of a specified target component. action: UIExtension.UIConsts.FRAGMENT_ACTION.APPEND, // Specify the name of the target component that the new components defined in the above template will be appended to. All the target names of fragments are defined in the layout template. target: 'home-tab-group-hand', // Define the properties of the added component, such as icon, text, and css style. template: [ '<dropdown icon-class="fv__icon-toolbar-stamp">', ' <dropdown-button name="show-hello-button" icon-class="fv__icon-toolbar-hand">say hello</dropdown-button>', ' <dropdown-button name="select-pdf-file-button" accept=".pdf" file-selector icon-class="fv__icon-toolbar-open">open</dropdown-button>', '</dropdown>' ].join(''), // Define the interaction logic of the added component. config: [{ // specify the component in the above template that the configuration will be applied to. // For example, the configuration will be applied to the component with the name of "show-hello-button". target: 'show-hello-button', callback: function () { alert('hello'); } }, { // The configuration will be applied to the component with the name of "select-pdf-file-button" which is defined in the above template of fragments. target: 'select-pdf-file-button', // Extend Controller, and implement the handle function. callback: CustomController }] }] });
Refresh your browser (http://127.0.0.1:8080/index.html), and then you can see a new created drop-down menu as follows:
Delete a toolbar button
To delete a toolbar button through fragment is fairly simple. For example, to delete the Hand tool , you only need to add a new object to the fragment. Based on the above example in section 4.2.1, add the code below:
{ target: 'hand-tool', action: UIExtension.UIConsts.FRAGMENT_ACTION.REMOVE }
Refresh your browser (http://127.0.0.1:8080/index.html), and then you can see the Hand tool has been removed from the group component as follows:
Modify a toolbar button
To modify a toolbar button through fragment is also fairly simple. Just like Delete a toolbar button, you only need to add a new object to the fragment.
Change icon of a button
For example, to change the icon of the Hand tool , just add the code below based on the example in section 4.2.1:
{ target: 'hand-tool', config: { iconCls: 'fv__icon-toolbar-note' // your custom icon. } }
Refresh your browser (http://127.0.0.1:8080/index.html), and then you can see the icon of the Hand tool has been changed as follows:
Change the tooltip of a button
For example, to change the tooltip of the Hand tool , just add the code below based on the example in section 4.2.1:
{ target: 'hand-tool', config: { tooltip: { title: 'your custom tooltip' } } }
Refresh your browser (http://127.0.0.1:8080/index.html), and then you can see the tooltip of the Hand tool has been changed to “your custom tooltip” as follows:
Change the event of a button
To change the event of a button, there are two ways:
a) Overwrite the built-in event. For example:
{ target: 'hand-tool', config: { callback: function() { alert('your click event handler'); } } }
b) Add custom behavior based on the built-in event (original logic). You can configure the button using the method as follows:
For ES6:
{ target: 'hand-tool', config: { callback: { before: function(...handleMethodArguments) { console.info('called before handle callback with arguments: ', handleMethodArguments); }, after: function(value, ...handleMethodArguments) { console.info('called after handle callback with returning value and arguments: ',value, args ); } } } }
For ES5:
{ target: 'hand-tool', config: { callback: { before: function () { var handleMethodArguments = Array.prototype.slice.call(arguments); console.info('called before handle callback with arguments: ', handleMethodArguments); }, after: function (value) { var handleMethodArguments = Array.prototype.slice.call(arguments, 1); console.info('called after handle callback with returning value and arguments: ', value, handleMethodArguments); } } } }
Modularization
In order to differentiate the built-in components and user-defined components to avoid conflicts, UIExtension provides modularization feature, which allows you to register the components in different modules separately. Then, you only need to add the prefix of the module name when you declare the components in the template.
Create your own custom module
If you want to define and use a custom component which has the same name with the built-in component, you can create a custom module and then register your custom component in the custom module.
For example, in the built-in component, there is already an existing component with the name of “dropdown“, if you also want to define a custom component called “dropdown“, you can refer to the simple code below:
Create a new module “my-widgets”, and registers a user-defined component in this module:
For ES6:
// Create a new module. Please note that the second parameter must be an array if you create a new module. let module = UIExtension.modular.module('my-widgets', []); class UserDefinedDropdownComponent extends UIExtension.Component { static getName(){ return 'dropdown'; // Declare the tag name of the component. There is already an existing component with the same name of 'dropdown' in the built-in component. } render() { super.render(); this.element.innerText = 'User-defined dropdown component'; } } module.registerComponent(UserDefinedDropdownComponent);
For ES5:
// Create a new module. Please note that the second parameter must be an array if you create a new module. var module = UIExtension.modular.module('my-widgets', []); function UserDefinedDropdownComponent() { UIExtension.Component.apply(this, arguments); } UserDefinedDropdownComponent.getName = function() { return 'dropdown'; // Declare the tag name of the component. There is already an existing component with the same name of 'dropdown' in the built-in component. } UserDefinedDropdownComponent.prototype.constructor = UIExtension.Component; UserDefinedDropdownComponent.prototype.render = function() { UIExtension.Component.prototype.render.call(this); this.element.innerText = 'User-defined dropdown component'; } module.registerComponent(UserDefinedDropdownComponent);
Then, the built-in dropdown and user-defined dropdown can be differentiated in the following way:
<!-- built-in dropdown --> <dropdown></dropdown> <!-- user-defined dropdown --> <my-widgets:dropdown></my-widgets:dropdown>
For example, use the user-defined dropdown component:
var pdfui = new UIExtension.PDFUI({ // Omit other parameters. fragments: [{ action: UIExtension.UIConsts.FRAGMENT_ACTION.APPEND, target: 'home-tab-group-hand', template: '<my-widgets:dropdown></my-widgets:dropdown>' // use a colon to separate the module name and component name in the template. }] });
Understanding the built-in components
In simple terms, a tag defined in the template is a component. Container and Widget also belong to the component. The different is that container can hold subcomponents, but widget cannot. All of the native HTML tags are defined as container components, so you can freely nest them.
Foxit PDF SDK for Web has already wrapped a rich set of built-in components for developers to quickly build a web viewer, and customize it as desired. This section will list and introduce the basic components and business components.
Basic components
Type | Name | Description |
container | toolbar | Toolbar components, like an empty div (just has bottom border) |
tabs | Tab components, which are the parent components of tab and used to manage the tab pages. Note: Tab must exist as the subcomponents of the tabs component. |
|
tab | Tab pages. | |
group-list | Group list, which is used to manage group components. | |
group | Group components, which must exist as the subcomponents of group-list. | |
sidebar | Sidebar, which managers the sidebar panels. | |
sidebar-panel | Sidebar panel, which allow you to specify the icon, title and content of the panel. For example, the sidebar-search, and sidebar-bookmark in the demo page. | |
layer | Floating box component. It supports translucent backdrop and modal box, which can be used to implement dialogs. | |
layer-header | A component for the head of a dialog, which can be set with a title and a close button. | |
layer-toolbar | Equivalent to a div with 1.5em height and flex layout. It is usually used to store buttons or other components. | |
layer-view | Equivalent to a div with fv_ui-layer-panel. It is usually used to store the contents of dialogs. | |
dropdown | Dropdown component. | |
dropdown-item | Dropdown items. | |
contextmenu | Context menu component. The subcomponents must be contextmenu-item or contextmenu-separator. To show context menu component, you need to call showAt method. | |
widget | dropdown-button | A type of dropdown items. It will trigger the controller’s handle method and click event after clicking. If set to file selector mode, it will trigger the change event after clicking to select a file, and also pass the selected file to the controller’s handle method. |
container | accordion | Accordion component. |
accordion-card | The card of accordion component. It can be set with a title, and the content can be shrunk. It must be present as the subcomponent of the accordion. | |
webpdf | The root component of the default template. It will listen the document open and close event of pdfviewer object, and control to disable/enable all the components depending on the document state. | |
widget | viewer | A component that renders PDF files. Each template file must be configured with a viewer component. |
text | It will be parsed into a text node in the DOM tree. The content of the text component will be localized by i18next library | |
xbutton | Button component. It supports setting the icon and text. After clicking, it will trigger the click event and call the controller’s handle method. | |
file-selector | File selection component. It supports setting icon and text. After clicking and selecting a file, it will trigger the change event, pass the selected file to the controller’s handle method and call it. | |
number | Number input box. You can set the number range and step size. The default range is infinite, and it has no step size by default. After setting the step size, if the minimum value is not equal to infinitely small, then the value of the input box must be ( the minimum value + step size* integer). | |
contextmenu-item | Context menu item. It must be as a subcomponent of contextmenu. Other configurations and usages are the same as xbutton. | |
contextmenu-separator | The separator line of context menu. It has no other special effects. | |
slot | slot | Slot can be used to implement the requirement for inserting subcomponents to the different locations of the complex container components. Note: If “for=”slotName”, slotName” is not supported, it will report the “slot does not exist” error. In this case, it depends on how the corresponding component of the slot’s parent node handle the value, please refer to the Component#appendSlot interface. |
Business components
Type | Name | Inherited Component | Description |
widget | hand-button | xbutton | Hand tool button |
widget | selection-button | xbutton | Text/Annotation selection tool button |
widget | snapshot-button | xbutton | Snapshot tool button |
widget | open-file-dropdown | dropdown | Dropdown menu for opening document |
widget | download-file-button | xbutton | Download file button |
widget | goto-prev-page-button | xbutton | Go to the previous page |
widget | goto-next-page-button | xbutton | Go to the next page |
widget | goto-page-input | number | The input box for the page number that you want to jump to. |
widget | zoom-out-button | xbutton | Zoom out page button |
widget | zoom-in-button | xbutton | Zoom in page button |
widget | editable-zoom-dropdown | dropdown | The editable zoom dropdown menu |
widget | zoom-dropdown | dropdown | Zoom dropdown menu |
widget | continuous-page-button | xbutton | A button used to enable continuous page mode which views pages continuously with scrolling enabled |
widget | continuous-facing-page-button | xbutton | A button used to enable continuous-facing page mode which views pages side-by-side with continuous scrolling enabled |
widget | loupe-tool-button | xbutton | Loupe tool button |
widget | marquee-tool-button | xbutton | Marquee tool button |
widget | create-text-highlight-button | xbutton | Text highlight tool button |
widget | create-strikeout-button | xbutton | Text strikeout tool button |
widget | create-underline-button | xbutton | Text underline tool button |
widget | create-squiggly-button | xbutton | Text squiggly tool button |
widget | create-replace-button | xbutton | Text replace tool button |
widget | create-caret-button | xbutton | Caret tool button |
widget | create-note-button | xbutton | Note tool button |
widget | create-typewriter-button | xbutton | Typewriter tool button |
widget | create-callout-button | xbutton | Callout tool button |
widget | create-textbox-button | xbutton | Textbox tool button |
widget | create-drawings-dropdown | dropdown | Shapes tool dropdown |
widget | create-pencil-button | xbutton | Pencil tool button |
widget | eraser-button | xbutton | Eraser tool button |
widget | create-area-highlight-button | xbutton | Area highlight tool button |
widget | create-distance-button | xbutton | Distance tool button |
widget | create-attachment-button | xbutton | Attachment tool button |
widget | create-image-button | xbutton | Image tool button |
widget | create-link-button | xbutton | Link tool button |
widget | stamp-dropdown | dropdown | Stamp tool dropdown list |
widget | add-image-button | xbutton | Add image tool button |
widget | ink-sign-dropdown | dropdown | Ink signature dropdown list |
widget | create-stamp-dialog | layer | Create stamp dialog |
widget | loupe-tool-dialog | layer | Loupe tool dialog |
widget | create-ink-sign-dialog | layer | Create ink signature dialog |
widget | bookmark-sidebar-panel | sidebar-panel | Bookmark panel in the sidebar |
widget | commentlist-sidebar-panel | sidebar-panel | Comment list panel in the sidebar |
widget | thumbnail-sidebar-panel | sidebar-panel | Thumbnail panel in the sidebar |
widget | layer-sidebar-panel | sidebar-panel | PDF layers panel in the sidebar |
widget | search-sidebar-panel | sidebar-panel | Search panel in the sidebar |
widget | attachment-sidebar-panel | sidebar-panel | Attachments panel in the sidebar |
container | page-contextmenu | contextmenu | Page context menu |
container | annot-contextmenu | contextmenu | Annotation context menu |
container | action-annot-contextmenu | contextmenu | Image and link annotation context menu |
container | default-markup-contextmenu | contextmenu | Markup annotation context menu |
container | fileattachment-contextmenu | contextmenu | Attachment annotation context menu |
container | media-contextmenu | contextmenu | video/audio annotation context menu |
container | redact-contextmenu | contextmenu | Redaction context menu |
container | textmarkup-contextmenu | contextmenu | Caret/highlight/strikeout/underline/squiggly/typewriter/callout/textbox context menu |
widget | contextmenu-item-annot-actions | contextmenu-item | Show action settings dialog |
widget | contextmenu-item-apply-all | contextmenu-item | Apply all redaction annotations |
widget | contextmenu-item-apply | contextmenu-item | Apply current redaction annotation |
widget | contextmenu-item-copy-text | contextmenu-item | Copy the content data of the current annotation |
widget | contextmenu-item-delete-annot | contextmenu-item | Delete current annotation |
widget | contextmenu-item-hand-tool | contextmenu-item | Switch to hand tool |
widget | contextmenu-item-marquee-zoom | contextmenu-item | Switch to loupe tool |
widget | contextmenu-item-media-download | contextmenu-item | Download current multimedia data streams |
widget | contextmenu-item-place | contextmenu-item | Apply current redaction annotation to other page |
widget | contextmenu-item-properties | contextmenu-item | Show the properties dialog of current annotation |
widget | contextmenu-item-reply | contextmenu-item | Reply current annotation |
widget | contextmenu-item-search | contextmenu-item | Show search sidebar |
widget | contextmenu-item-select-tool | contextmenu-item | Switch to selection tool |
widget | contextmenu-item-zoom-actual-size | contextmenu-item | Zoom to 100% |
widget | contextmenu-item-fitpage | contextmenu-item | Fit page (resize the page to fit entirely in the document pane) |
widget | contextmenu-item-fitwidth | contextmenu-item | Fit width (resize the page to fit the width of the window. Part of the page may be out of view) |
widget | contextmenu-item-zoomin | contextmenu-item | Zoom in |
widget | contextmenu-item-zoomout | contextmenu-item | Zoom out |
Business components in the add-on modules
The business components in the add-on modules are valid only when your project has already integrated the related add-on modules, please refer to section 3.4 “Integrate the add-ons of UIExtension“.
Type | Module:Name | Inherited Component | Add-on Module | Description |
widget | print:print-button | xbutton | Open the print dialog | |
widget | print:print-dialog | layer | Print dialog | |
widget | import-form-module:import-form-button | xbutton | import-form | Import form data |
widget | export-form-module:import-form-dropdown | xbutton | export-form | Export form data |
widget | fpmodule:file-property-button | xbutton | file-property | Show current document information dialog |
widget | fpmodule:file-property-dialog | layer | file-property | Document information dialog |
widget | multi-media:multi-media-button | xbutton | multi-media | Switch to the multimedia Annotation creation tool |
widget | edit-pageobjects:edit-all-objects-button | xbutton | path-objects | Switch to the page objects (image/path/text) editing tool |
container | edit-pageobjects:page-objects-dropdown | dropdown | path-objects | Path objects creation tool dropdown list |
widget | edit-text-object:add-text-button | xbutton | text-object | Text editing |
widget | edit-text-object:text-bold-style-button | xbutton | text-object | Make text bold |
widget | edit-text-object:text-italic-style-button | xbutton | text-object | Italicize text |
container | edit-text-object:font-color-picker | dropdown | text-object | Set the color of text |
container | edit-text-object:font-style-dropdown | dropdown | text-object | Set font and font size of text |
widget | password-protect:password-protect-button | xbutton | password-protect | Open the password protect dialog |
widget | password-protect:remove-protect-button | xbutton | password-protect | Remove password protect |
container | redaction:create-redactions-dropdown | dropdown | redaction | Redaction options dropdown list |
widget | redaction:apply-redactions-button | xbutton | redaction | Apply redaction |
widget | redaction:redaction-search-button | xbutton | redaction | Open the left search panel |
container | redaction:redaction-page-dialog | layer | redaction | Mark page to redact dialog |
Implementing Annotation Real-time collaboration
Foxit PDF SDK for Web supports annotation real-time collaboration which means when two browsers are opening a same PDF document, if one browser adds an annotation event, the event will be added synchronization to the other browser. This section will introduce how to implement annotation real-time collaboration using Foxit PDF SDK for Web.
Device requirement
• Two browser terminals
• A host with http-server (to handle network events and distribution)
• Foxit PDF SDK for Web 7.0
Development process for implementing annotation real-time collaboration
To implement annotation real-time collaboration, please refer to the steps below:
1) Initialize the Foxit PDF SDK for Web. Please refer to the step c) in the section “Integrate the simple UI demo to your project“.
2) Add the “annotation-add” events as below:
For ES6:
pdfViewer.eventEmitter.on('annotation-add', (annotations) => { // annotations : the newly added annotations let xmlHttp = new XMLHttpRequest(); let url = 'url/to/post/added/annots' xmlHttp.open('POST', url, true); let formData = new FormData(); let annotJsons = [] annotations.map(ele => { annotJsons.push(ele.exportToJSON()); }) formData.append('annots', annotJsons) xmlHttp.send(formData); // handle loaded event. })
For ES5:
pdfViewer.eventEmitter.on('annotation-add',function(annotations) { // annotations : the newly added annotations var xmlHttp = new XMLHttpRequest(); var url = 'url/to/post/added/annots'; xmlHttp.open('POST', url, true); var formData = new FormData(); var annotJsons = []; annotations.map(function(ele) { annotJsons.push(ele.exportToJSON()); }); formData.append('annots',annotJsons); xmlHttp.send(formData); // handle loaded event. });
3) Pull the server distribution event at a regular time.
For ES6:
setInterval(() => { let xmlHttp = new XMLHttpRequest(); let url = 'url/to/get/added/annots' xmlHttp.open('GET', url, true); xmlHttp.send(null); xmlHttp.onload = (e) => { if (xhr.readyState === 4) { if (xhr.status === 200) { // Assuming that directly returns the JSON data of the annotations. let annotsJson = xmlHttp.response; pdfViewer.getCurrentPDFDoc().getPageByIndex(annotsJson.pageIndex).then(page => { annotsJson.annots.map(annotJSON => { page.addAnnot(annotJSON); }) }) } } } }, 1000);
For ES5:
setInterval(function() { var xmlHttp = new XMLHttpRequest(); var url = 'url/to/get/added/annots'; xmlHttp.open('GET', url, true); xmlHttp.send(null); xmlHttp.onload = function(e) { if (xhr.readyState === 4) { if (xhr.status === 200) { // Assuming that directly returns the JSON data of the annotations. var annotsJson = xmlHttp.response; pdfViewer.getCurrentPDFDoc().getPageByIndex(annotsJson.pageIndex).then(function(page) { annotsJson.annots.map(function(annotJSON) { page.addAnnot(annotJSON); }) }) } } } }, 1000);
4) Restart the server, open a PDF document in two browsers, add an annotation event to one of the browser, then you will find that the event will be added synchronization to the other browser.
Technical Support
Reporting Problems
Foxit offers 24/7 support for its products and are fully supported by the PDF industry’s largest development team of support engineers. If you encounter any technical questions or bug issues when using Foxit PDF SDK for Web, please submit the problem report to the Foxit support team at https://www.foxit.com/support/ticket.html. In order to better help you solve the problem, please provide the following information:
• Contact details
• Foxit PDF SDK product and version
• Your Operating System and IDE version
• Detailed description of the problem
• Any other related information, such as log file or error screenshot
Contact Information
You can contact Foxit directly, please use the contact information as follows:
Foxit Support:
Sales contact phone number:
Phone: 1-866-680-3668
Support & General contact:
Phone: 1-866-MYFOXIT or 1-866-693-6948
Updated on December 18, 2023