Hi everyone,
i have this third party software which i would like to connect with thingworx so my first test is that i have app.js, index.html and this javascript library which worked well locally in my computer and now i would like to do same thing in mashup.
i am using valueDisplay widget in mashup and would like to render it in mashup. now my html is rendered properly and i can see it in mashup but i feel like i am unable to get app.js file and library js file in html.. I have uploaded all three files in the file repository.. i feel i am not accessing it right with repo link ....
Anyone has some feedback, i would be happy to hear..
https://github.com/dymosoftware/dymo-connect-framework?tab=readme-ov-file
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>DYMO Connect Framework – ThingWorx</title>
<style>
body { font-family: system-ui, Arial, sans-serif; margin: 24px; }
button { margin-right: 8px; }
#log { white-space: pre-wrap; font-family: ui-monospace, Consolas, monospace; }
#preview { max-height: 180px; display: block; margin-top: 12px; }
</style>
</head>
<body>
<h2>DYMO Connect Framework – Test</h2>
<div>
<button id="btnEnv">Check Environment</button>
<button id="btnList">List Printers</button>
<button id="btnPreview">Render Preview</button>
<button id="btnPrint">Print</button>
</div>
<img id="preview" alt="Label preview will appear here" />
<h3>Log</h3>
<div id="log"></div>
<!-- External scripts only -->
<script src="/Thingworx/FileRepositories/TestBench.Repository/downLoadPicturesWithTimeRange/dymo.connect.framework.js"></script>
<script src="/Thingworx/FileRepositories/TestBench.Repository/downLoadPicturesWithTimeRange/app.js"></script>
</body>
</html>
My vs code implementation is
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>DYMO Connect Framework – Local Test</title>
<style>
body { font-family: system-ui, Arial, sans-serif; margin: 24px; }
button { margin-right: 8px; }
#log { white-space: pre-wrap; font-family: ui-monospace, Consolas, monospace; }
#preview { max-height: 180px; display: block; margin-top: 12px; }
</style>
</head>
<body>
<h2>DYMO Connect Framework – Test</h2>
<div>
<button id="btnEnv">Check Environment</button>
<button id="btnList">List Printers</button>
<button id="btnPreview">Render Preview</button>
<button id="btnPrint">Print</button>
</div>
<img id="preview" alt="Label preview will appear here" />
<h3>Log</h3>
<div id="log"></div>
<script src="./dymo.connect.framework.js"></script>
<script src="./app.js"></script>
</body>
</html>
app.js
const $ = (sel) => document.querySelector(sel);
const log = (msg) => { console.log(msg); $('#log').textContent += msg + '\n'; };
(async function main() {
try {
await dymo.label.framework.init();
log('Framework initialized');
$('#btnEnv').addEventListener('click', () => {
try {
const env = dymo.label.framework.checkEnvironment();
log('Environment:\n' + JSON.stringify(env, null, 2));
} catch (e) { log('checkEnvironment error: ' + e); }
});
$('#btnList').addEventListener('click', async () => {
try {
const printers = await dymo.label.framework.getPrinters();
log('Printers:\n' + JSON.stringify(printers, null, 2));
} catch (e) { log('getPrinters error: ' + e); }
});
// A tiny sample label (Address 30252); adjust to match your label stock
const sampleLabelXml = `
<DieCutLabel Version="8.0" Units="twips">
<PaperOrientation>Landscape</PaperOrientation>
<Id>Address</Id>
<PaperName>30252 Address</PaperName>
<DrawCommands/>
<ObjectInfo>
<TextObject>
<Name>TEXT</Name>
<ForeColor Alpha="255" Red="0" Green="0" Blue="0"/>
<BackColor Alpha="0" Red="255" Green="255" Blue="255"/>
<LinkedObjectName/>
<Rotation>Rotation0</Rotation>
<IsMirrored>False</IsMirrored>
<IsVariable>True</IsVariable>
<Text>DYMO Test\nHello World</Text>
<HorizontalAlignment>Center</HorizontalAlignment>
<VerticalAlignment>Middle</VerticalAlignment>
<TextFitMode>AlwaysFit</TextFitMode>
</TextObject>
<Bounds X="180" Y="120" Width="3060" Height="540"/>
</ObjectInfo>
</DieCutLabel>`.trim();
let label = null;
$('#btnPreview').addEventListener('click', async () => {
try {
label = dymo.label.framework.openLabelXml(sampleLabelXml);
const png = await dymo.label.framework.renderLabel(sampleLabelXml, null, null);
$('#preview').src='data:image/png;base64,' + png;
log('Preview rendered');
} catch (e) { log('renderLabel error: ' + e); }
});
$('#btnPrint').addEventListener('click', async () => {
try {
if (!label) label = dymo.label.framework.openLabelXml(sampleLabelXml);
const printers = await dymo.label.framework.getPrinters();
if (!printers.length) return log('No DYMO printers found');
const printerName = printers[0].name;
await dymo.label.framework.printLabel(printerName, null, sampleLabelXml, null);
log('Printed on: ' + printerName);
} catch (e) { log('printLabel error: ' + e); }
});
} catch (e) {
log('Framework init failed. Is DYMO Connect running? ' + e);
}
})();
Solved! Go to Solution.
Thingworx Extension for Software Dymo Connect Framework:-
The sentence "i am using valueDisplay widget in mashup and would like to render it in mashup" does not make sense to me.
There are two ways to render HTML: HTMLAreaWidget or WebFrame.
WebFrame is just an IFrame to some other location.
HTMLAreaWidget will not run javascript. It has a limited support for HTML tags and attributes, this was recently discussed in the forum.
You will have to use a custom widget rendering a script tag to add the library (and app.js) to the page.
Thanks for your reply. ValueDisplay widget let you also render your html in mashup. you can select property valueFormat and then can select there HTML. as you can see below
yes about htmlAreaWidget and WebFrame you are right. But just curious about valueDisplay widget that why it did not work ..may be also because of limited support.... i will give it a shot with custom widget in mashup.
Oh, the HTML render function, didn't think of that.
Maybe check the mashup debug console and the browser console to see
-what is finally rendered
-if the files are loading (F12->Network)
-which errors are thrown
So for testing i have made a simple html file and when u open it in browser and click button it gives you output on screen. Its working in browser but in thingworx it shows me html but it does not work. nothing is showing in console.log or network when i click the button..
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>DYMO Mini Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body { font-family: system-ui, Arial, sans-serif; margin: 16px; }
button { padding: 6px 10px; }
pre { margin-top: 12px; font-size: 12px; white-space: pre-wrap; }
</style>
</head>
<body>
<h3>DYMO Mini Test</h3>
<button id="btnInit">Init & Check</button>
<pre id="out">Click “Init & Check”.</pre>
<script>
const SDK_src="https://qajavascriptsdktests.azurewebsites.net/JavaScript/dymo.connect.framework.js";
function log(msg){ console.log("[DYMO]", msg); document.getElementById('out').textContent = String(msg); }
function append(obj){
const pre = document.getElementById('out');
pre.textContent += "\n" + (typeof obj === "string" ? obj : JSON.stringify(obj, null, 2));
}
function loadSdkOnce(src){
return new Promise(function(resolve, reject){
if (window.dymo && dymo.label && dymo.label.framework) { resolve(); return; }
const s = document.createElement("script");
s.src=src;
s.onload = resolve;
s.onerror = (e) => reject(new Error("DYMO SDK load failed: " + src));
document.head.appendChild(s);
});
}
async function initAndCheck(){
await loadSdkOnce(SDK_SRC);
log("SDK loaded. Calling init()…");
await dymo.label.framework.init();
const env = dymo.label.framework.checkEnvironment();
append("\ncheckEnvironment():");
append(env);
const printers = (dymo.label.framework.getPrinters() || []).map(p => p.name);
append("\nPrinters:");
append(printers.length ? printers : "(none)");
}
document.getElementById("btnInit").addEventListener("click", async () => {
console.log("testing testing ");
try { await initAndCheck(); }
catch (e) { log("Error: " + e.message); }
});
</script>
</body>
</html>
But you can see that the dymo.js is not fetched, so in the end you will have to create a widget to pull the script into the page context.
so i tried now with inline JS and not <script> tag then it shows me results in console.log everytime i click
<button onclick="(async()=>{try{
if(!(window.dymo && dymo.label && dymo.label.framework)){
await new Promise((res,rej)=>{
const s=document.createElement('script');
s.src='https://qajavascriptsdktests.azurewebsites.net/JavaScript/dymo.connect.framework.js';
s.onload=res; s.onerror=()=>rej(new Error('SDK load failed'));
document.head.appendChild(s);
});
}
await dymo.label.framework.init();
const env = dymo.label.framework.checkEnvironment();
const out = document.getElementById('out');
if(out) out.textContent = 'Init OK\n' + JSON.stringify(env, null, 2);
console.log('DYMO env:', env);
} catch(e){
alert('Error: ' + e.message);
console.error(e);
}})()">Init & Check</button>
<pre id="out" style="white-space:pre-wrap;font:12px system-ui"></pre>
output in console.log
so finally it worked now in mashup with Valuedisplay widget..
<div id="dymoBox">
<button type="button" onclick="(async function(btn){try{
if(!(window.dymo && dymo.label && dymo.label.framework)){
await new Promise((res,rej)=>{
const s=document.createElement('script');
s.src='https://qajavascriptsdktests.azurewebsites.net/JavaScript/dymo.connect.framework.js';
s.onload=res; s.onerror=()=>rej(new Error('SDK load failed'));
document.head.appendChild(s);
});
}
await dymo.label.framework.init();
const env = dymo.label.framework.checkEnvironment();
// get or create the output <pre>
var out = document.getElementById('out');
if(!out){
out = document.createElement('pre');
out.id = 'out';
out.style.cssText = 'white-space:pre-wrap;font:12px system-ui;margin-top:8px;color:#111;';
btn.parentNode.appendChild(out); // append right under the button
}
out.textContent = 'Init OK\n' + JSON.stringify(env, null, 2);
console.log('DYMO env:', env);
}catch(e){
alert('Error: ' + e.message);
console.error(e);
}})(this); return false;">Init & Check</button>
</div>
Mashup (when i click button- i get the expected output)
browser console.log
IMPORTANT: the ValueDisplay widget sanitizes <script> tags, so they don’t run. my inline onclick works because the click handler is allowed and executes in the page context.
Hello @MA8731174,
It looks like you have some responses from some community members. If any of these replies helped you solve your question please mark the appropriate reply as the Accepted Solution.
Of course, if you have more to share on your issue, please let the Community know so other community members can continue to help you.
Thanks,
Vivek N.
Community Moderation Team.
second experiment:
<button onclick="(async()=>{try{
if(!(window.dymo&&dymo.label&&dymo.label.framework)){
await new Promise((res,rej)=>{
var s=document.createElement('script');
s.src='https://qajavascriptsdktests.azurewebsites.net/JavaScript/dymo.connect.framework.js';
s.onload=res; s.onerror=()=>rej(new Error('SDK load failed'));
document.head.appendChild(s);
});
}
await dymo.label.framework.init();
var env=dymo.label.framework.checkEnvironment();
var out=document.getElementById('out'); if(out){ out.textContent='Init OK\n'+JSON.stringify(env,null,2); }
console.log('DYMO env:', env);
})().catch(e=>{ alert('Error: '+e.message); console.error(e); })">Init & Check</button>
<pre id="out" style="margin-top:12px;font-size:12px;white-space:pre-wrap;"></pre>
in network tab.. bad request 400
Hello,
You probably want to wrap it in a ThingWorx UI extension, since you now have a working example you made for opening/closing popups.
You can expose those DYMO methods like checkEnvironment, getPrinters, printLabel and renderLabel through your widget's Services -- this way you can make it all ThingWorx-native and implement configurable logic based on Expressions, ThingWorx backend services, etc., instead of hacking HTML.
/ Constantine
Thanks for your suggestion and that was also my thought and i am pretty close now to finish it. I have one query regarding it. I have a .dymo label file stored in a ThingWorx File Repository. To read it, I created the following service:
The service returns the file content as a string.
When I directly paste this string content into my widget property (type = String), everything works fine.
However, when I bind the service output to the same property (also of type String), the property value in my widget becomes undefined in the logs.
Am I missing something in the binding or service configuration that could explain this behavior?
This service which returns this string of file get executed when onmashup load and output i have also bind to one textfield just to test that either it returns string expected output. everything is fine but still it makes this property undefined in logs which i bind it.
ah! i found out same issue created in the past and it has resolved my issue
Thingworx Extension for Software Dymo Connect Framework:-
Hi @MA8731174
If a response to this post allowed you to find a solution, please mark the appropriate one as the Accepted Solution for the benefit of others in the community.
Regards.
--Sharon