Examples
- Displaying the user’s info
- Create a PDF file and upload it to My Files
- Querying the API
- Calling the Salesforce API through an iFrame
Displaying the user’s info
This example will display the user’s name in the application.
<!-- index.html -->
<html>
<head>
<!-- styles -->
</head>
<body>
<h1>Welcome <span id="name"></span></h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
<script src="main.es6.js"></script>
</body>
</html>
// main.es6.js
window.onShowpadLibLoaded = () => addUserName();
function addUserName () {
const userInfo = window.ShowpadLib.getUserInfo();
document.getElementById('name').innerHTML = userInfo.user_name;
}
Create a PDF file and upload it to My Files
<!-- index.html -->
<html>
<head></head>
<body>
<input type="button" onclick="createPdf()" id="create" value="Create PDF" disabled="disabled"/><br/>
<input type="button" onclick="uploadPdf()" id="upload" value="Upload PDF" disabled="disabled"/><br/>
<div id="output"></div>
<script src="node_modules/whatwg-fetch/fetch.js"></script>
<script src="jspdf.js"></script>
<script src="./main.es6.js"></script>
</body>
</html>
// main.es6.js
'use strict';
let apiConfig = null;
let pdfDocBlob = null;
window.onShowpadLibLoaded = () => window.ShowpadLib.getShowpadApi(onShowpadApiConfig);
function onShowpadApiConfig (config)
{
apiConfig = config;
document.getElementById('create').removeAttribute('disabled');
}
function createPdf()
{
if (pdfDocArray == null)
{
const doc = new jsPDF();
doc.ellipse(40, 20, 10, 5);
doc.setFillColor(0,0,255);
doc.ellipse(80, 20, 10, 5, 'F');
doc.setLineWidth(1);
doc.setDrawColor(0);
doc.setFillColor(255,0,0);
doc.circle(120, 20, 5, 'FD');
pdfDocBlob = doc.output('blob');
document.getElementById('output').innerHTML += 'PDF Created in memory<br/>';
document.getElementById('upload').disabled = false;
}
}
function uploadPdf()
{
const url = `${apiConfig.url}/api/v3/divisions/mine/assets.json`;
const formData = new FormData();
// The third argument needs to have the correct file-extension!
formData.append('file', pdfDocBlob, 'file.pdf');
formData.append('isPersonal', 'true');
var xhr = new XMLHttpRequest();
xhr.open('POST', url);
xhr.setRequestHeader('Authorization', `Bearer ${accessToken}`);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
const json = JSON.parse(xhr.responseText);
if (json.response && json.response.resourcetype === 'Ticket') {
pollTicket(json.response.id);
}
}
};
xhr.send(formData);
}
function pollTicket (id) {
const url = `${apiConfig.url}/api/v3/tickets/${id}.json`;
const config = {
headers: {
'Authorization': `Bearer ${apiConfig.accessToken}`
}
};
fetch(url, config)
.then(response => response.json())
.then(json => {
if (json.response.status) {
switch(json.response.status) {
case 'completed':
// File was processed
if (json.response.asset && json.response.asset.id) {
const assetId = json.response.asset.id;
console.log("file processed with asset id: " + assetId);
// File was processed
}
else {
// Something else failed
}
break;
case 'queued':
case 'processing':
// Still processing, poll again in 2 seconds
setTimeout(() => {
pollTicket(id);
}, 2000);
break;
case 'failed':
// File processing failed..
break;
}
}
});
}
Querying the API
This example will load 2 available tags for the logged in user and then load all the available assets which have been tagged with one of the previously loaded tags.
<!-- index.html -->
<html>
<head>
<!-- styles -->
</head>
<body>
<h1>Click one of your assets</h1>
<ul id="asset-list"></ul>
<script src="main.es6.js"></script>
</body>
</html>
// main.es6.js
const TAG_DEMO_1 = '3709662152eeb8467aa30';
const TAG_DEMO_2 = 'da31b6bcf30e98177d6c8';
const NODE_FIELDS = `id,label,icon,type,asset,slug,hideLabel,left,right,level,` +
`rootNode,parentNode,channel,humanReadablePath,path,url,createdAt`;
const NODE_EXPAND = `asset,icon,asset.tags`;
window.onShowpadLibLoaded = () => displayAssets();
function displayAssets () {
findChannelNodesWithTags([TAG_DEMO_1, TAG_DEMO_2], nodes => {
if (nodes !== null) {
document.getElementById('asset-list').innerHTML = nodes
.map(node => nodeDataToHtml(node))
.join('');
}
});
}
function findChannelNodesWithTags (tagIds, callbackFn) {
const endpoint = `channelnodes.json?assetTagIds=${tagIds.join('%2C')}&fields=${NODE_FIELDS}&expand=${NODE_EXPAND}`;
window.ShowpadLib.getShowpadApi(onShowpadApiConfig);
function onShowpadApiConfig (apiConfig) {
if (apiConfig !== null) {
getJson(endpoint, apiConfig, callbackFn);
}
else {
callbackFn(null);
}
}
}
function getJson (endpoint, apiConfig, callbackFn) {
const url = `${apiConfig.url}/api/v3/${endpoint}`;
const config = {
headers: {
Authorization: `Bearer ${apiConfig.accessToken}`
}
};
fetch(url, config)
.then(response => {
if (response.ok) {
return response
.json()
.then(data => callbackFn(data.response.items));
}
else {
callbackFn(null);
}
})
.catch(() => callback(null));
}
function nodeDataToHtml (node) {
return `
<li>
<a href="${node.asset.appLink}?modal=true">
<img src="${node.asset.previewDownloadLink}" />
<label>${node.label}</label>
</a>
</li>
`;
}
Calling the Salesforce API through an iFrame
<!-- index.html (in HTML Content) -->
<html>
<head></head>
<body>
<input type="button" value="Fetch Contacts" onclick="fetchContacts()" />
<iframe
height="0"
width="0"
src="https://my-whitelisted-domain.com/salesforce-iframe.html"
name="salesforce-iframe"
id="salesforce-iframe"
border="0"
></iframe>
<script src="./main.es6.js"></script>
</body>
</html>
// main.es6.js (in HTML Content)
const iframeElement = document.getElementById('salesforce-iframe');
const iframeHost = 'https://my-whitelisted-domain.com';
// Wait for ShowpadLib to be ready
window.onShowpadLibLoaded = () => getSalesforceInfo();
// Listen for message from the iFrame
window.addEventListener("message", onMessage, false);
// Fetch the Salesforce Info and post it to the iframe.
function getSalesforceInfo ()
{
window.ShowpadLib.getSalesforceApi(data => {
if (data.accessToken && data.url) {
data.type = 'info';
iframeElement.contentWindow.postMessage(data, iframeHost);
}
else {
// Can't call Salesforce, show error
}
});
}
// Do an API call
function fetchContacts ()
{
var q = encodeURIComponent('SELECT Id, LastName, FirstName FROM Contact LIMIT 50').replace(/%20/g, '+');
var data = {
type: 'call',
method: 'GET',
path: '/services/data/v33.0/query?q=' + q
};
iframeElement.contentWindow.postMessage(data, iframeHost);
}
function onMessage(event) {
// Handle the event here
console.log('Got Response in source: ' + event.data);
}
<!-- salesforce-iframe.html (Hosted on https://my-whitelisted-domain.com/) -->
<html>
<head></head>
<body>
<script src="./salesforce-iframe.es6.js"></script>
</body>
</html>
// salesforce-iframe.es6.js (Hosted on https://my-whitelisted-domain.com/)
const info = {
uri: null,
token: null
};
window.addEventListener("message", onMessage, false);
window.sfCall = sfCall;
function onMessage(event)
{
const data = event.data;
if (data.type === 'info')
{
info.uri = data.url;
info.token = data.accessToken;
}
else if (data.type === 'call') {
sfCall(data.method, data.path, function (response){
event.source.postMessage(response, '*');
});
}
}
/**
* @param {string} method GET,POST,...
* @param {string} path eg. '/services/data/v33.0/query?q=xxx'
* @return {Promise}
*/
function sfCall (method, path, callbackFn)
{
const url = info.uri + path;
const config = {
headers : {
Authorization: `Bearer ${info.token}`
}
};
fetch(url, config)
.then(checkStatus)
.then(response => {
callbackFn({
type: 'success',
response: response
});
})
.catch(error => {
callbackFn({
type: 'error',
response: response
});
});
}
function checkStatus (response)
{
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error();
error.statusCode = response.status;
throw error;
}