- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-24-2018 06:11 AM
Hi All,
To give a bit of background on my question, I have successfully used Cabrillo in my Service Portal custom widgets to invoke the camera for scanning the barcodes. However, service portal is not working in the mobile app in the Android 4.4 devices.
Because of this reason, and to get the same look and feel of the Service Portal pages in the Platform view I'm trying to use UI Pages with AngularJS. As part of my POC, I'm trying to use barcode scanning functionality of Cabrillo in the platform UI Page.
I have created an Angular controller in the UI page and passed Cabrillo in the parameters as below. But getting injector error in the console.
Controller function outline in the Client Script of UI Page:
sampleApps.controller('mainCtrl', ['$scope', 'cabrillo',function($scope, cabrillo){
cabrillo.camera.getBarcode().then(function(barcode) {
if (barcode) {
alert(barcode);
console.log('Scanned barcode.', barcode);
} else {
console.log('User cancelled scanning barcode.');
}
}, function(error) {
console.log('Failed to scan barcode.', error);
});
}]);
Error in the console:
Error: [$injector:unpr] http://errors.angularjs.org/1.2.20/$injector/unpr?p0=cabrilloProvider%20%3C-%20cabrillo
My questions are
- how to use Cabrillo in the platform UI Page.
- If using Cabrillo in the platform UI Page is not possible, is there any other way to invoke barcode scanning functionality from the UI Page. ( I know we can use barcode field attribute in the back end view. But I'm trying to use UI Pages).
Any help on this is very much appreciated.
Thanks!
Karteek
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-27-2019 10:01 PM
ServiceNow HI support confirmed that Calibro js plugin was inbuilt into the portal, and there is no available mechanism to use it into UI Pages.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-24-2018 06:40 AM
How are you including angularjs in the ui page and where are instantiating the angular app? You'll have to do those types of thing manually in a ui page compared to Service Portal. I would start here and use this as a template: Introduction to AngularJS Apps in ServiceNow
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-24-2018 07:27 AM
Hi Brad,
Thanks for the quick reply.
I'm including angularjs and initiating angular app also. As a matter of fact, I took OOTB "example_apps_list" UI Page and just added the piece of Cabrillo code as shown in the question. I have already developed few AngularJS UI Pages so I have no difficulty in making an AngularJS UI Page.
My doubt is, is it possible to use Cabrillo in UI pages if yes how, if not is there any other way.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-24-2018 07:33 AM
It should be possible to include cabrillo as there are not really many limitations to what frameworks, etc. you can include in ui pages. It's hard to tell what is causing the error based on the code snippet you've provided other than possibly the way that you've included cabrillo. Could you post the entire ui page and how you're including all of your angular resources, etc?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-24-2018 04:00 PM
As I told its the ootb UI page "example_apps_list", I'm just adding Cabrillo code in the controller to invoke camera on page load. To be clear content of this page is displaying, no issue in that. The issue is with injecting Cabrillo.
However, below is the complete code of the UI Page(its ootb UI page). I also attached XML of UI page and the output page in the attachments.
I'm doing this in my personal instance and the version is London.
Html:
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<j:if test="${gs.hasRole('rest_api_explorer')}">
<g:inline template="rest_api_explorer_client_compatibility.xml" />
<j2:if test="$[jvar_compatibility != 'block']">
<g:evaluate var="jvar_prefix" jelly="true">
gs.getProperty('glide.rest.client_app_prefix', 'example-restclient-');
</g:evaluate>
<g:evaluate var="jvar_repoUrl" jelly="true">
gs.getProperty('glide.rest.client_app_repo_url', 'https://api.github.com/orgs/ServiceNow/repos');
</g:evaluate>
<g:requires name="scripts/restapi/lib/js_includes_explorer.js" includes="true" />
<input type="HIDDEN" name="prefix" id="prefix" value="${jvar_prefix}"/>
<input type="HIDDEN" name="repo_url" id="repo_url" value="${jvar_repoUrl}"/>
<div data-doctype="true" ng-app="sn_sampleApps">
<div>
<div ng-controller="mainCtrl" ng-init="getGitRepos()">
<div id="top_of_page" tabindex="-1" aria-describedby="description">
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<h1 style="display: inline-block;" class="form-header navbar-title">
<span>${gs.getMessage('Example REST API Client Applications')}</span>
</h1>
</div>
</div>
</nav>
</div>
<table style="width: 100%;">
<tbody>
<tr data-annotation-type="Section Details" class="annotation-row" style="display: table-row;">
<td colspan="99" data-annotation-type="Section Details" class="annotation">
<div class="annotation-wrapper" style="direction:ltr; padding: 10px;">
<p tabindex="-1" id="description">${gs.getMessage('These are example REST API client applications built for teaching, demoing, and reference purposes. Play with them, fork them, or even reuse some of the code in your projects. Click on an application to see their full source on GitHub as well as additional documentation.')}</p>
</div>
</td>
</tr>
</tbody>
</table>
<div>
<div class="panel panel-default">
<div class="panel-body">
<div class="container-fluid" ng-show="error">
<div class="row">
<div tabindex="0" class="col-sm-12 notification notification-warning">
<h4>${gs.getMessage('Unable to retrieve example client applications')}</h4>
<h4><span><a href="${jvar_repoUrl}" target="_blank">
<b>${gs.getMessage('Git Hub Repositories')}</b>
</a></span>
</h4>
</div>
</div>
</div>
<div class="container-fluid" ng-repeat="app in repos" ng-show="!error">
<div class="row">
<div class="col-sm-12">
<h4>
<span>
<a href="{{app.html_url}}" target="_blank"
aria-label="{{app.name}} {{app.description}} View project on Git Hub.">
<b>
{{app.name}}
</b>
</a>
</span>
</h4>
</div>
</div>
<div class="row">
<div class="col-sm-12">
{{app.description}}
</div>
</div>
<hr>
</hr>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</j2:if>
</j:if>
</j:jelly>
Client Script:
var sampleApps = angular.module('sn_sampleApps', []);
// I have included cabrillo in the params list
sampleApps.controller('mainCtrl', ['$scope', 'cabrillo',function($scope, cabrillo){
// Code added by me-start
cabrillo.camera.getBarcode().then(function(barcode) {
if (barcode) {
alert(barcode);
console.log('Scanned barcode.', barcode);
} else {
console.log('User cancelled scanning barcode.');
}
}, function(error) {
console.log('Failed to scan barcode.', error);
});
// Code added by me-end
$scope.getGitRepos = function(){
var github_servicenow_url = gel('repo_url').value;
if(window.XDomainRequest){
$scope.populateResponseForIE9(github_servicenow_url);
}else{
jQuery.get(github_servicenow_url, function(response){
$scope.populateResponse(response);
}).fail(function(error){
$scope.error = true;
}).always(function(){
$scope.$apply();
});
}
};
$scope.populateResponseForIE9 = function(github_servicenow_url) {
var xdr = new XDomainRequest();
xdr.open("get", github_servicenow_url);
xdr.onerror = function () {
$scope.error = true;
$scope.$apply();
};
xdr.onload = function() {
var responseString = xdr.responseText;
var response = JSON.parse(responseString);
$scope.populateResponse(response);
$scope.$apply();
};
setTimeout(function () {
xdr.send();
}, 0);
};
$scope.populateResponse = function(response) {
if($scope.verifyGHResponse(response)){
var apps = [];
var app_prefix = gel('prefix').value;
for(var i=0; i < response.length; i++){
var application = response[i];
// only show apps with specific prefix
if(application.name.indexOf(app_prefix) == 0)
apps.push(application);
}
$scope.repos = apps;
} else {
$scope.error =true;
}
};
$scope.verifyGHResponse = function(ghResponse) {
if(ghResponse && ghResponse[0]){
if(ghResponse[0].name && ghResponse[0].description){
return true;
}
}
return false;
};
}]);
document.addEventListener("DOMContentLoaded", function(){
document.getElementById('top_of_page').focus();
});
Output page with error in the console: