Layer component ​
The Layer component is a floating panel typically used for dialogs, tooltips, context menus, and other UI that must appear above other elements.
Code example ​
Getting started ​
html
<html>
<template id="layout-template">
<webpdf>
<div class="flex-container">
<xbutton action="show-layer" @controller="custom:ShowHideLayerController">Click to show layer</xbutton>
<xbutton action="hide-layer" @controller="custom:ShowHideLayerController">Click to hide layer</xbutton>
</div>
<div class="fv__ui-body">
<viewer></viewer>
</div>
<template>
<layer name="my-layer" class="center">
<text>Hello! I'm a layer component!</text>
</layer>
</template>
</webpdf>
</template>
</html>
<style>
.flex-container {
display: flex;
justify-content: space-between;
}
</style>
<script>
UIExtension.PDFUI.module('custom', [])
.controller('ShowHideLayerController', {
handle: function() {
const layer = this.getComponentByName('my-layer');
const action = this.component.getAttribute('action');
switch(action) {
case 'show-layer':
layer.show();
break;
case 'hide-layer':
layer.hide();
break;
}
}
});
var CustomAppearance = UIExtension.appearances.Appearance.extend({
getLayoutTemplate: function() {
return document.getElementById('layout-template').innerHTML;
},
disableAll: function(){}
});
var libPath = window.top.location.origin + '/lib';
var pdfui = new UIExtension.PDFUI({
viewerOptions: {
libPath: libPath,
jr: {
licenseSN: licenseSN,
licenseKey: licenseKey
}
},
renderTo: document.body,
appearance: CustomAppearance,
addons: []
});
</script>Dialog with title and close button ​
html
<html>
<template id="layout-template">
<webpdf>
<div class="flex-container">
<xbutton target-layer="my-layer" @controller="custom:ShowLayerController">Click to show layer</xbutton>
<xbutton target-layer="my-layer-2" @controller="custom:ShowLayerController">Click to show layer with custom
header
</xbutton>
</div>
<div class="fv__ui-body">
<viewer></viewer>
</div>
<template>
<layer name="my-layer" class="center my-layer">
<layer-header title="Layer Title" icon-class="fv__icon-toolbar-print"></layer-header>
</layer>
<layer name="my-layer-2" class="center my-layer">
<div class="my-custom-layer-header">
<i class="fv__icon-toolbar-print"></i>
<h2>Custom layer header</h2>
</div>
</layer>
</template>
</webpdf>
</template>
</html>
<style>
.my-layer {
width: 400px;
height: 300px;
}
.my-custom-layer-header {
display: flex;
align-items: center;
}
.my-custom-layer-header i {
display: inline-block;
width: 32px;
height: 32px;
}
.my-custom-layer-header h2 {
flex: 1;
margin: 0 0 0 1em;
}
.flex-container {
display: flex;
justify-content: space-between;
}
</style>
<script>
UIExtension.PDFUI.module('custom', [])
.controller('ShowLayerController', {
handle: function () {
const layerName = this.component.getAttribute('target-layer')
const layer = this.getComponentByName(layerName);
layer.show();
}
});
var CustomAppearance = UIExtension.appearances.Appearance.extend({
getLayoutTemplate: function () {
return document.getElementById('layout-template').innerHTML;
},
disableAll: function () {
}
});
var libPath = window.top.location.origin + '/lib';
var pdfui = new UIExtension.PDFUI({
viewerOptions: {
libPath: libPath,
jr: {
licenseSN: licenseSN,
licenseKey: licenseKey
}
},
renderTo: document.body,
appearance: CustomAppearance,
addons: []
});
</script>json
{
"iframeOptions": {
"style": "height: 500px"
}
}Draggable dialog ​
html
<html>
<template id="layout-template">
<webpdf>
<div class="fv__ui-body">
<viewer></viewer>
</div>
<template>
<layer name="my-layer1" class="center my-layer" visible>
<layer-header @draggable="{type:'parent'}" title="Click header area to drag" icon-class="fv__icon-toolbar-print"></layer-header>
</layer>
<layer name="my-layer2" class="center my-layer" @draggable visible>
<layer-header title="Click anywhere on the box to drag" icon-class="fv__icon-toolbar-print"></layer-header>
</layer>
</template>
</webpdf>
</template>
</html>
<style>
.my-layer {
width: 400px;
height: 300px;
}
.flex-container {
display: flex;
justify-content: space-between;
}
</style>
<script>
var CustomAppearance = UIExtension.appearances.Appearance.extend({
getLayoutTemplate: function() {
return document.getElementById('layout-template').innerHTML;
},
disableAll: function(){}
});
var libPath = window.top.location.origin + '/lib';
var pdfui = new UIExtension.PDFUI({
viewerOptions: {
libPath: libPath,
jr: {
licenseSN: licenseSN,
licenseKey: licenseKey
}
},
renderTo: document.body,
appearance: CustomAppearance,
addons: []
});
</script>json
{
"iframeOptions": {
"style": "height: 500px"
}
}Modal dialog ​
html
<html>
<template id="layout-template">
<webpdf>
<div class="flex-container">
<xbutton @controller="custom:ShowLayer1Controller">Click to show modal layer 1</xbutton>
<xbutton @controller="custom:ShowLayer2Controller">Click to show modal layer 2</xbutton>
</div>
<div class="fv__ui-body">
<viewer></viewer>
</div>
<template>
<layer name="my-layer-1" class="center my-layer" modal backdrop>
<layer-header title="Modal layer with backdrop" icon-class="fv__icon-toolbar-print"></layer-header>
</layer>
<layer name="my-layer-2" class="center my-layer" modal>
<layer-header title="Modal layer without backdrop" icon-class="fv__icon-toolbar-print"></layer-header>
</layer>
</template>
</webpdf>
</template>
</html>
<style>
.my-layer {
width: 400px;
height: 300px;
}
.flex-container {
display: flex;
justify-content: space-between;
}
</style>
<script>
UIExtension.PDFUI.module('custom', [])
.controller('ShowLayer1Controller', {
handle: function() {
const layer = this.getComponentByName('my-layer-1');
layer.show();
}
})
.controller('ShowLayer2Controller', {
handle: function() {
const layer = this.getComponentByName('my-layer-2');
layer.show();
}
});
var CustomAppearance = UIExtension.appearances.Appearance.extend({
getLayoutTemplate: function() {
return document.getElementById('layout-template').innerHTML;
},
disableAll: function(){}
});
var libPath = window.top.location.origin + '/lib';
var pdfui = new UIExtension.PDFUI({
viewerOptions: {
libPath: libPath,
jr: {
licenseSN: licenseSN,
licenseKey: licenseKey
}
},
renderTo: document.body,
appearance: CustomAppearance,
addons: []
});
</script>json
{
"iframeOptions": {
"style": "height: 500px"
}
}Specify a parent node for the layer ​
By default, the layer DOM node is appended to the end of the root component. In some cases this can cause incorrect stacking. To avoid that, pass the insertion target when calling show(). Example:
html
<html>
<template id="layout-template">
<webpdf>
<div class="flex-container">
<xbutton action="show-layer" @controller="custom:ShowHideLayerController">Click to show layer</xbutton>
<xbutton action="hide-layer" @controller="custom:ShowHideLayerController">Click to hide layer</xbutton>
</div>
<div class="fv__ui-body">
<viewer></viewer>
</div>
<template>
<layer name="my-layer" class="center">
<text>Hello! I'm a layer component!</text>
</layer>
</template>
</webpdf>
</template>
</html>
<style>
.flex-container {
display: flex;
justify-content: space-between;
}
</style>
<script>
UIExtension.PDFUI.module('custom', [])
.controller('ShowHideLayerController', {
handle: function() {
const layer = this.getComponentByName('my-layer');
const action = this.component.getAttribute('action');
switch(action) {
case 'show-layer':
layer.show(document.body); / The layer will be appended to `document.body` when it is displayed.
break;
case 'hide-layer':
layer.hide();
break;
}
}
});
var CustomAppearance = UIExtension.appearances.Appearance.extend({
getLayoutTemplate: function() {
return document.getElementById('layout-template').innerHTML;
},
disableAll: function(){}
});
var libPath = window.top.location.origin + '/lib';
var pdfui = new UIExtension.PDFUI({
viewerOptions: {
libPath: libPath,
jr: {
licenseSN: licenseSN,
licenseKey: licenseKey
}
},
renderTo: document.body,
appearance: CustomAppearance,
addons: []
});
</script>API ​
Layer component template ​
Template example:
html
<layer class="center" visible modal backdrop>
<layer-header title="" icon-class="fv__icon-toolbar-print"></layer-header>
</layer><layer> template attributes:
| Property | Description | Type | Default | Version |
|---|---|---|---|---|
| visible | Whether the layer is visible | boolean | false | 7.0.0 |
| modal | Whether this is a modal dialog | boolean | false | 7.0.0 |
| backdrop | Whether the modal uses a semi-transparent backdrop; enabling this also enables modal | boolean | false | 7.0.0 |
| class="center" | Center the layer | -- | -- | 7.0.0 |
| class="centerv" | Center the layer vertically | -- | -- | 7.0.0 |
| class="centerh" | Center the layer horizontally | -- | -- | 7.0.0 |
| class="left" | Show the layer on the left | -- | -- | 7.0.0 |
| class="right" | Show the layer on the right | -- | -- | 7.0.0 |
| class="top" | Show the layer at the top | -- | -- | 7.0.0 |
| class="bottom" | Show the layer at the bottom | -- | -- | 7.0.0 |
<layer-header> template attributes:
| Property | Description | Type | Default | Version |
|---|---|---|---|---|
| title | Title text | string | '' | 7.0.0 |
| icon-class | Title icon | string | '' | 7.0.0 |
Methods ​
| Method | Description | Version |
|---|---|---|
| show(appendTo: HTMLElement): void | Append the layer to the given DOM node and show it | 7.0.0 |
| open(appendTo: HTMLElement): void | Same as show() | 7.0.0 |
| hide(): void | Hide the layer | 7.0.0 |
| close(): void | Hide and destroy the layer | 7.0.0 |
Events ​
| Name | Description | Example | Version |
|---|---|---|---|
| shown | Fired after the layer is shown | layer.on('shown', () => void) | 7.0.0 |
| hidden | Fired after the layer is hidden | layer.on('hidden', () => void) | 7.0.0 |
| closed | Fired after the layer is hidden and destroyed | layer.on('closed', () => void) | 7.0.0 |