WaiverForever Waiver Widget
Adding a waiver widget to your website to allow participants to sign without leaving the page.
Usage
- Choose the preferred waiver templates from your templates.
- Go to Template Settings page -> Waiver Widget tab.
- Enable the widgets and configure them.
- Keep the
templateId
s for the next steps. - There are multiple ways of embedding our waiver widget into your website:
Easy route: reference the widget script from CDN:
We can load the widget automatically or manually.
For automatically loading, append the following HTML snippet into the body
tag of your website:
<script src="https://cdn.waiverforever.com/qs3/ew.js?templateId=${templateId1,templateId2}"></script>
- Widget with its trigger button will be mounted as soon as the script is loaded. It exposes the
widget instance
as a global JavaScript variable named waiverWidget
(note: its initial letter is lowercase) and WF_EMBED_WAIVER
(for backward compatibility). - If you need multiple waivers be signed one by one, you can set multiple template IDs by join them with comma.
- The widget instance has a hook method
.onReady
, which you can use to perform extra operations if needed. - If you don't like the default triggering button and want to create your own way to trigger the waiver modal, simply adding a query
sdkMode=yes
to disable it:
<script src="https://cdn.waiverforever.com/qs3/ew.js?templateId=${templateId1,templateId2}&sdkMode=yes"></script>
For manually loading, append the following HTML snippet into the body
tag of your website:
<script src="https://cdn.waiverforever.com/qs3/ew.js"></script>
- If the script's
src
doesn't contain a specified templateId
, the script exposes the widget constructor
as a global JavaScript variable named WaiverWidget
(note: its initial letter is uppercase). - You could manually initialize the
widget instance
on demand. Please make sure performing any extra operations after the .onReady
hook is triggered.
You could also load the widget script dynamically, e.g. The AMD way:
require(['https://cdn.waiverforever.com/qs3/ew.js'], function (WaiverWidget) {
const widget = new WaiverWidget({
templateId: `${templateId}`,
sdkMode: true
})
widget.onReady(function(){
myCustomButton.addEventListener('click', function () {
widget.toggle()
})
})
})
})
Importing the widget into the module system
Install the widget by npm
or yarn
:
npm i --save @waiverforever/waiver-widget
yarn add @waiverforever/waiver-widget
const WaiverWidget = require('@waiverforever/waiver-widget')
const widget = new WaiverWidget()
- TypeScript is fully supported.
- Definitions bring TS/JS users the better developing experience.
- Could be used in ES modules or CommonJS standards systems.
- Could be dynamically loaded by third-party bundler's code splitting feature.
Reference
Terms
- widget constructor: In manually loading or dynamically loading scenarios, the script exposes a constructor named
WaiverWidget
as a global variable. In a module system, we could require
or import
it directly. - widget instance: Instance of widget constructor. We could register events to its hooks and manipulate the instance through its methods.
- SDK mode: Widget without the default triggering button, you need to programmatically trigger the waiver modal.
- window mode: When enabled, instead of showing waiver modal, a new waiver page will be opened. If you passed multiple waiver template ID the window mode will be turn off.
- embed mode: When enabled, the waiver modal will be embedded into the current page and mounted to the target element.
API
WaiverWidget constructor
interface WidgetOption {
templateId: string | string[];
sdkMode?: boolean;
windowMode?: boolean;
stylesheetURL?: string;
embed?: boolean;
embedTargetId?: string;
}
type WaiverWidgetConstructor = new (option?: WidgetOption): IWidget;
usage:
const widget = new WaiverWidget({
templateId: `${templateId}`,
})
WaiverWidget instance
interface IWidget {
closeEmbedWaiverModal: () => void;
show: () => void;
close: () => void;
toggle: () => void;
destroy: () => void;
onShowed: (callback: () => void) => void;
onReady: (callback: (widget: IWidget) => void) => void;
onLoad: (callback: (signedCount: number) => void) => void;
onSigned: (callback: (signedCount: number) => void) => void;
onClosed: (callback: (signedCount: number) => void) => void;
onDestroyed: (callback: () => void) => void;
}
Protips
If you get bored of using the callback style .onReady
hook and others, and the async/await
syntax is available in your runtime, here are some tips for you.
All of the widget APIs are thenable/awaitable
! It means you can use the widget instance
, instance methods
and event hooks
in a synchronous-like way.
Thenable/awaitable instance
Awaiting the response of the widget instance, we get a ready state (fully-interactive) instance.
async function appDidMount () {
const widget = await new WaiverWidget({
templateId: `${templateId}`,
})
widget.show()
}
Thenable/awaitable instance methods
Awaiting a response of a widget method, we receive the callback payload of the method's corresponding event hook.
async function appShowWaiverInstruction () {
await widget.show()
sendLog('waiver showed')
}
async function appCloseWaiverInstruction () {
const signedCount = await widget.close()
sendLog('waiver closed, with signed count: ' + signedCount)
}
Thenable/awaitable event hooks
A registered event handler will be triggered whenever the event occurs. An awaited event hook will only respond to the event payload for once.
async function appDidMount () {
widget.onSigned(async function () {
const signedCount = await widget.onClosed
sendLog('waiver closed, with signed count: ' + signedCount)
})
}
Actually, awaiting a response of a event hook is rarely used.