
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
In Service Portal, when you have the Service Catalog Cart enabled you may have found that while it populates the user ordering the items in the Cart view, the "Deliver to" address is empty. This happens even when the user has an address against their user profile.
I received a question recently asking if a user's deliver to address in the cart can be populated automatically with an order. While support doesn't normally provide customizations, I saw this as a good opportunity to improve my knowledge of the Service Portal. So I jumped in to see how easy it is to populate a field on the form using the new Service Portal configuration interface.
How to do record and field lookups in Service Portal
For this task I wanted to have the field populated automatically when the cart loads, and also for the "Deliver to" address to change if I change the user in the "Requested for" field.
By clicking "Ctrl + Right Click" on the widget I was able to get straight to the configuration page I needed to modify via the link "Widget in Editor". See Configure widget instances.
To populate the user's address, we will need to update both the Client Script and the Server Script.
Updating the Client Script to populate the user's address
Service Portal uses the AngularJS framework, and upon changing a field an event is broadcast on the root scope called `field.change`. We can listen for that event to be broadcast with the following code:
$scope.$on("field.change", function(evt, parms) {
   if (parms.field.name == 'field_name' {
   // your code here
   }
});
You can find the variable name of the field you want to update by inspecting the element using your browsers developer tools to find the ng-modal attribute:
Initially in the out of the box client script the "Deliver to" field is set to an empty string. You must first set the "Deliver to" location on the initial page load, so you can reference the server script location variable (that we will create later in this article) to update the Client Script from:
c.deliverTo = "";
to:
c.deliverTo = c.data.location;
The next step is to call the Server Script when the client script "hears" the field change to obtain and populate the new location from the server:
$scope.$on("field.change", function(evt, parms) {
  if (parms.field.name == 'requested_for') { //detects that requestor name has changed
   c.deliverTo = '';
   c.server.get({ //send the server the new user ID & action is to update the location
    userID: parms.newValue,
    action: "get_user_location"
   }).then(function(response) { //update the location displayed on the form
    c.deliverTo = response.data.location;
   });
   }
});
Note: When the field.change event is broadcast, the callback function is supplied with a "parms" parameter which contains the old and new values for the field that changed. Above we are setting userID to the "newValue" to be sent to the server along with the action to perform. The "c.deliverTo" value is taking the data returned from the server side call to populate that field.
Updating the Server Script to look up the user's address
First we will create the function that looks up the address based on the userID passed to the function:
function getUserLocation(userSysID) {
  var sysUserGR = new GlideRecord("sys_user");
  sysUserGR.get(userSysID);
  var newLocation = sysUserGR.getElement("location");
  return newLocation.getDisplayValue();
}
In the client script, we are using the c.server.get function which creates on the server an input object containing the userID and action (get_user_location) to perform. The code below is only run when the "Requested for" value changes and triggers the c.server.get function as this supplies the correct parameters for the if statement.
if (input && input.action === "get_user_location") {
  userID = input.userID;
}
The userID variable is already populated near the beginning of the server script. The above is used if "Requested for" changes to override the initial user ID with the new value.
You need to place the line below to populate the location variable to be supplied to the client (both when the form loads and when the value changes).
data.location = getUserLocation(userID);
I've included a screenshot below showing exactly where I've added this code below:
With the updates above, the "Deliver To" address is populated when the cart form is loaded and when the "Requested for" user is changed.
One catch I found from going through this exercise was my server side function "getUserLocation" was towards the end of the server script. For some reason it did not work until I moved it toward the top of the server script. I am still working on finding the cause for this.
If you find any function appears to not be running ensure it is towards the top of the server script like my screenshot above.
Another handy tip is clicking "Ctrl + Right Click" on the widget then click "Log to console: $scope.data." This displays all of the content in the data object passed from the server script to the client script in the browser developer tools javascript console:
The screenshot below shows a sample of the data logged, and you can see the "data.location" contents that we obtained above in this output:
There is also "Log to console: $scope" as an option, this provides all data contained in the $scope object including "$scope.data" and can provide extra information for your developing purposes beyond that stored in the data object.
If you have any tips or improvements on my implementation above, I look forward to hearing them in the comments for this article. This is only scraping the surface of what is possible in the Servicenow Service Portal.
Other sources:
- 5,627 Views
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.