- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-15-2016 01:49 AM
Hi all
So we are currently analyzing if we can replace our current service catalog (based on the standard ServiceNow interface and self-service module - no CMS) with the Service Portal.
We have a number of more advanced catalog items, where we use UI macro to display additional information to the user, that we are not able to achieve using the available variable types.
As UI Macros are not available in Service Portal we need a replacement. Here I have discovered a new "widget" field the catalog varaible form, where you can point to a portal widget and get it displayed on the catalog item.
But we need to be able to interact with the widget and affect what it is displaying based on the values selected in the variables on the catalog item.
Basically I want to write to the data in the widget's scope via a catalog client script.
The normal way of accessing an angular scope from the outside is using the syntax
var scope = angular.element($("#[element]")).scope();
So I have created a clone of the Hello World 1 widget and modified it so the input field has an ID
<div>
Enter your name:
<input id="helloWorld" type="text" ng-model="c.data.sometext" ng-change="c.display()"/>
<h1>{{ c.data.message }}</h1>
</div>
Then I try to access the scope from an onChange script in the catalog item
var scope = angular.element(document.getElementById('helloWorld')).scope();
scope.$apply(function(){
scope.data.sometext = newValue;
});
But i get an error in the console saying (g_env) [SCRIPT:EXEC] Error while running Client Script "onChange_name": TypeError: Cannot read property 'element' of null
So it looks like the catalog client scripts does not have access to the loaded angular in any way. I have tried some different thinks to try and be able to access angular but no avail.
If anybody has an idea I would appreciate any pointers - if we don't solve this, then the portal is not an option.
Regards
Lars
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-15-2016 04:33 AM
I found the solution my self.
You can read and write to the catalog variables using $scope.page.g_form. and then any of the g_form function like setValue and getValue.
Then I use the angular $watch feature to define a function to watch for changes in the catalog variable and then update my data in the widget scope.
It looks like this
HTML template
<div>
Data from catalog variable:
<h1>{{ c.data.message }}</h1>
</div>
Client Script Controller
function($scope) {
var c = this;
//Watch for changes in the name variable
$scope.$watch(function () {
return $scope.page.g_form.getValue('name');
}, function (value) {
//Update local data object with data from variable
c.data.message = value ? 'Content of name variable: ' + value : '';
});
}
Result - the text in the widget is updated when you change focus away from the catalog variable
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-22-2016 04:20 AM
Another approach can be seen this post Embedding widgets in Service Catalog - ServicePortal.io - Service Portal, CMS, and Custom Apps
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-08-2017 05:45 AM
Hi Lars,
I tried accessing the variable name using $scope.page.g_form.getValue('variable_name') in client controller.
Here on change of variable, I'm populating the variable based on client script in another variable , but when I use alert($scope.page.g_form.getValue('variable_name'));
I was getting error "Cannot read property 'getValue' of undefined".
Could you let me know if I'm missing something over here.
Thanks,
Bhavin
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-08-2017 06:06 AM
Did you include ($scope) in your initialization of the client controller?
function($scope) {
/* widget controller */
var c = this;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-08-2017 09:10 AM
Hi Lars,
Yes I have included $scope.
Below is the code i was trying from the example you shared above.
function ($scope, $http, spUtil, nowAttachmentHandler, $rootScope, $location,$window) {
var c = this;
$scope.$watch(function () {
alert($scope.page.g_form.getValue('hide'));
return $scope.page.hide.value;
}, function (value) {
// //Update local data object with data from variable
c.data.message = value ? 'Content of name variable: ' + value : '';
alert(c.data.message);
});
It threw error saying "Cannot read property 'getValue' of undefined"
Thanks,
Bhavin
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-08-2017 09:50 AM
Where do you run the code - it will not work within in widget editor. The page.g_form part is only available when the widget is run via a macro variable in a cataog item