Help converting example JS to UI-Builder

I am looking to implement Zebra’s Browser Print. They have an example, but I’m unsure how to make it work in UI Builder. I’ve put the JS script into the included script section and the main chunk of JS into a custom code block on page enter.

> <script type="text/javascript" src="BrowserPrint-3.1.250.min.js"></script>
> <script type="text/javascript">
> var selected_device;
> var devices = [];
> function setup()
> {
> 	//Get the default device from the application as a first step. Discovery takes longer to complete.
> 	BrowserPrint.getDefaultDevice("printer", function(device)
> 			{
> 		
> 				//Add device to list of devices and to html select element
> 				selected_device = device;
> 				devices.push(device);
> 				var html_select = document.getElementById("selected_device");
> 				var option = document.createElement("option");
> 				option.text = device.name;
> 				html_select.add(option);
> 				
> 				//Discover any other devices available to the application
> 				BrowserPrint.getLocalDevices(function(device_list){
> 					for(var i = 0; i < device_list.length; i++)
> 					{
> 						//Add device to list of devices and to html select element
> 						var device = device_list[i];
> 						if(!selected_device || device.uid != selected_device.uid)
> 						{
> 							devices.push(device);
> 							var option = document.createElement("option");
> 							option.text = device.name;
> 							option.value = device.uid;
> 							html_select.add(option);
> 						}
> 					}
> 					
> 				}, function(){alert("Error getting local devices")},"printer");
> 				
> 			}, function(error){
> 				alert(error);
> 			})
> }
> function getConfig(){
> 	BrowserPrint.getApplicationConfiguration(function(config){
> 		alert(JSON.stringify(config))
> 	}, function(error){
> 		alert(JSON.stringify(new BrowserPrint.ApplicationConfiguration()));
> 	})
> }
> function writeToSelectedPrinter(dataToWrite)
> {
> 	selected_device.send(dataToWrite, undefined, errorCallback);
> }
> var readCallback = function(readData) {
> 	if(readData === undefined || readData === null || readData === "")
> 	{
> 		alert("No Response from Device");
> 	}
> 	else
> 	{
> 		alert(readData);
> 	}
> 	
> }
> var errorCallback = function(errorMessage){
> 	alert("Error: " + errorMessage);	
> }
> function readFromSelectedPrinter()
> {
> 
> 	selected_device.read(readCallback, errorCallback);
> 	
> }
> function getDeviceCallback(deviceList)
> {
> 	alert("Devices: \n" + JSON.stringify(deviceList, null, 4))
> }
> 
> function sendImage(imageUrl)
> {
> 	url = window.location.href.substring(0, window.location.href.lastIndexOf("/"));
> 	url = url + "/" + imageUrl;
> 	selected_device.convertAndSendFile(url, undefined, errorCallback)
> }
> function sendFile(fileUrl){
>     //url = window.location.href.substring(0, window.location.href.lastIndexOf("/"));
>     //url = url + "/" + fileUrl;
> 	url = fileUrl;
>     selected_device.sendFile(url, undefined, errorCallback)
> }
> function onDeviceSelected(selected)
> {
> 	for(var i = 0; i < devices.length; ++i){
> 		if(selected.value == devices[i].uid)
> 		{
> 			selected_device = devices[i];
> 			return;
> 		}
> 	}
> }
> window.onload = setup;
> </script>

This is the custom code block in my test UI Builder page -

And the HTML that interacts with the JS -

> <input type="button" value="Send File" onclick="sendFile('https://magicaljelly.backendless.app/api/files/label.zpl');">

In UI Builder I created a test page with a button. The on click for the button has custom code with a call to the sendFile function -

When I click the button, I get an error in the browser

ReferenceError: sendFile is not defined

If the function is in the JS on page load, why isn’t it available for the on click?

Thanks,
Tim

Hi @Tim_Jones

Could you please provide:

  • your appId
  • the UI container name

Regards,
Vlad

Thanks @vladimir-upirov!

AppId: EEE25B20-17FA-97DD-FF29-EC45A5072A00
UI Container: default
Page: testBrowserPrint

Tim

It’s because in their example you need to paste the code into an HTML file, and in that way, such functions as sendFile will be placed into the global JS scope window

since you put it into the CustomCode block all this code (variables/functions) are not visible outside the custom code block code

In order to make such functions visible from any place you need to assign it to window

Thanks @vladimir-upirov,

Thank you for the help! Can you explain why the functions aren’t available anywhere without assigning them to the window?

I thought a custom code block was basically on the page.

If I put that entire chunk of JS into a .js file and include it External Libraries would that make the functions available from any place?

Thank you for the help with this. I really appreciate it.

Tim

sure:

A custom code block generates a JS function and then runs it, so in the code your custom code look like the following

// some codeless block code
function yourCustomCode(xArgument, yArgument, nArgument){
// here is the code you added in the custom code block dialog
}

yourCustomCode(1,2,3,...) // it runs your custom code block
// some codeless block code

you can read more about JS Scope, see the doc below

yes, it should, since it loads/executes the JS file on the top

Thanks for the details, @vladimir-upirov. I did not realize (I should have looked) that a custom code block was a function wrapper. Thank you for explaining that to me; I completely get it now. I made a false assumption that was the root of my confusion.

Have a great day,
Tim

1 Like