Customize UI ​
Starting in version 7.0, the SDK ships with a built-in UI framework that includes functional modules, packaged in UIExtension.js. The SDK also exposes APIs so you can customize the look and feel of the web viewer.
The UIExtension interface has two parts: template and fragments.
- Template extends HTML: controls in the template are declared with tags. Use templates to define non-interactive UI layout (CSS, icons, text, and so on).
- Fragments are UI snippets used to customize configuration and interaction for controls in the template. Each snippet has an action type (
action) that controls how it is applied (append,prepend,before,after,ext,replace,insert, andremove; default isext). With these actions you can insert, remove, replace, and modify controls in the template.
Customize UI layout with template ​
Templates mainly define the UI layout of controls. The examples below use the template approach. All sample code builds on the Integrate with the complete viewer section in the integration guide.
Create a simple template ​
A minimal template looks like this:
js
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.Appearance.extend({
getLayoutTemplate: function () {
return [
'<webpdf>',
' <viewer></viewer>',
'</webpdf>'
].join('');
}
})
});- The
<webpdf>tag listens for document open and close events and calls the Appearance object’s enableAll and disableAll methods to enable or disable related UI components. - The
<viewer>tag renders PDF content. Every template must include a<viewer>tag. You can place it anywhere; see the later examples.
Refresh the browser (http://127.0.0.1:8080/index.html) to see a minimal web PDF viewer with no other UI components.
Add a toolbar ​
Use the <toolbar> tag to add toolbar controls.
js
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.Appearance.extend({
getLayoutTemplate: function () {
return [
'<webpdf>',
' <toolbar>',
' <open-file-dropdown></open-file-dropdown>',
' </toolbar>',
' <viewer></viewer>',
'</webpdf>'
].join('')
}
})
});Refresh the browser (http://127.0.0.1:8080/index.html) to see the new toolbar control.
Add tabs ​
Use <tabs> and <tab> (or <gtab>) tags to add tabs.
js
var CustomAppearance = UIExtension.appearances.Appearance.extend({
getLayoutTemplate: function () {
return [
'<webpdf>',
' <toolbar>',
' <gtab group="custom-tabs" text="Home" body="home-tab-body">',
' </gtab>',
' <gtab group="custom-tabs" text="Comment" body="comment-tab-body">',
' </gtab>',
' </toolbar>',
' <div class="tab-bodies">',
' <div name="home-tab-body">',
' <open-file-dropdown></open-file-dropdown>',
' </div>',
' <div name="comment-tab-body" 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>',
' </div>',
' <viewer></viewer>',
'</webpdf>'
].join('')
}
})
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: CustomAppearance
});Refresh the browser (http://127.0.0.1:8080/index.html) to see the new tabs.
Add a sidebar ​
Use the <sidebar> tag to add a sidebar.
js
var CustomAppearance = UIExtension.appearances.Appearance.extend({
getLayoutTemplate: function () {
return [
'<webpdf>',
' <toolbar>',
' <gtab group="custom-tabs" text="Home" body="home-tab-body">',
' </gtab>',
' <gtab group="custom-tabs" text="Comment" body="comment-tab-body">',
' </gtab>',
' </toolbar>',
' <div class="tab-bodies">',
' <div name="home-tab-body">',
' <open-file-dropdown></open-file-dropdown>',
' </div>',
' <div name="comment-tab-body" 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>',
' </div>',
' <div class="flex-row">',
' <sidebar>',
' <bookmark-sidebar-panel></bookmark-sidebar-panel>',
' </sidebar>',
' <viewer></viewer>',
' </div>',
'</webpdf>'
].join('')
}
})
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: CustomAppearance
});Refresh the browser (http://127.0.0.1:8080/index.html) to see the bookmark sidebar.
Built-in layout templates ​
Built-in layout templates are under \examples\UIExtension\layout_templates inside the package. For desktop, see built-in-pc-layout-template.tpl; for mobile, see built-in-mobile-layout-template.tpl. You can edit these templates directly to customize the UI.
Under \examples\UIExtension\custom_appearance, Foxit PDF SDK for Web includes two custom template samples. adaptive-to-the-device.html adapts to desktop and mobile; not-adaptive-to-the-device.html is desktop-only.
Customize UI with fragments ​
Fragments are UI snippets used to customize configuration and interaction for controls in the template.
Create a dropdown ​
The example below creates a dropdown with two dropdown buttons and appends it to the end of the home-tab-group-hand component’s children.
To find a target component name (for widget components), right-click the control in the browser, choose Inspect, and read the component-name attribute on the matching <a> tag. For container components such as target: "home-tab-group-hand", inspect a child control and read component-name on the related <div> tag.
js
const customModule = UIExtension.PDFUI.module('custom', []);
customModule.controller('CustomController', {
mounted: function () {
console.info(this.component, 'mounted');
},
handle: function (selectedFile) {
alert(selectedFile.name);
}
});
var CustomController = customModule.getControllerClass('CustomController');
var CustomAppearance = UIExtension.appearances.RibbonAppearance.extend({
getDefaultFragments: function () {
return [{
// 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
}]
}]
}
})
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: CustomAppearance
});Refresh the browser (http://127.0.0.1:8080/index.html) to see the new dropdown.
Remove an existing toolbar button ​
Removing a toolbar button with a fragment is straightforward. To remove the hand tool, add an object like this to your fragments (based on the example above):
js
{
target: 'hand-tool',
action: UIExtension.UIConsts.FRAGMENT_ACTION.REMOVE
}Refresh the browser (http://127.0.0.1:8080/index.html) and the hand tool is gone.
Modify an existing toolbar button ​
Modifying a toolbar button is similar to removing a toolbar button: add another fragment object.
Change the button icon ​
To change the hand tool icon, add:
json
{
"target": "hand-tool",
"config": {
"iconCls": "fv__icon-toolbar-note"
}
}Refresh the browser (http://127.0.0.1:8080/index.html) to see the new icon.
Change the button tooltip ​
To change the hand tool tooltip, add:
json
{
"target": "hand-tool",
"config": {
"tooltip": {
"title": "your custom tooltip"
}
}
}Refresh the browser (http://127.0.0.1:8080/index.html); the tooltip should read your custom tooltip.
Change button events ​
You can change button behavior in two ways:
Override the built-in handler, for example:
javascript{ target: 'hand-tool', config: { callback: function () { alert('your click event handler'); } } }Wrap the built-in handler and add custom behavior:
javascript
{
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, handleMethodArguments);
}
}
}
}More examples ​
For additional samples, see the \examples\UIExtension\fragment_usage inside the package .
Modularization ​
To avoid clashes between built-in and custom components, UIExtension supports modules: register components in separate modules and prefix the module name when declaring them in templates.
Create a custom module ​
If you need a custom component with the same tag name as a built-in one, create a custom module and register your component there.
For example, a built-in dropdown already exists. To define your own dropdown, follow this pattern:
Create a module named my-widgets and register your component:
javascript
// 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);Use a module prefix to distinguish built-in and custom components:
html
<!-- built-in dropdown -->
<dropdown></dropdown>
<!-- user-defined dropdown -->
<my-widgets:dropdown></my-widgets:dropdown>Example that uses the custom dropdown in a fragment:
javascript
var pdfui = new UIExtension.PDFUI({
// Omit other parameters.
appearance: UIExtension.appearances.RibbonAppearance.extend({
getDefautFragments: function () {
return [{
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.
}];
}
})
});