Catalog client script not working for ess users

Brendan Hallida
Kilo Guru

Hi friends,

I have an onChange catalog client script which auto populates Login Name, Title, Location, Department when a user is chosen (from sys_user)

function onChange(control, oldValue, newValue, isLoading) {

userObject = g_form.getReference('mavis_access_employee_name',setUserInfo);

}

function setUserInfo(userObject){

g_form.setValue('mavis_access_employee_login_name', userObject.user_name);

g_form.setValue('mavis_access_users_title', userObject.title);

g_form.setValue('mavis_access_please_select_office_locati', userObject.location);

g_form.setValue('mavis_access_please_select_department', userObject.department);

}

Now this script runs fine when running as an admin or as an ITIL user, however nothing populates when an ess user attempts to run it.

Now I found the below thread when searching for an answer, and they suggest creating a read only ACL rule on the sys_user table for all users, and this does work, however this creates a problem for us.

https://community.servicenow.com/thread/234140?q=Client%20catalog%20script%20not%20working%20for%20e...

With the ACL read only rule enabled, when a user clicks on the i (as shown below) they now have access to see other users details, which is a no no for our company

find_real_file.png

I also found another thread which had the same solution, and goranlundqvist suggested that the script should be using a GlideAjax call, and I am not sure that I am?   I am still very new to JavaScript, and was able to work this code out from others that I found and I sort of understand it.

https://community.servicenow.com/thread/234179?q=Client%20catalog%20script%20not%20working%20for%20e...

I really curious how to are fetching that. How does your client scripts look like? If it is with a GlideAjax call, which I hope it is, then it shouldn't be a ACL problem.

//Göran

Does anyone have any suggestions?

Thanks in Advance,

Brendan

1 ACCEPTED SOLUTION

Geoffrey2
ServiceNow Employee
ServiceNow Employee

Yes, you should definitely learn how to use GlideAjax.


GlideAjax - ServiceNow Wiki


Client Script Best Practices - ServiceNow Wiki



The Client Script would look something like this:


var ga = new GlideAjax('UserUtils');


ga.addParam('sysparm_name', 'getUserDetails');


ga.addParam('sysparm_user_id', g_form.getValue('mavis_access_employee_name'));


ga.getXMLAnswer(function(answer) {


      console.log('answer: ' + answer);


      if (!answer)


              return;


      try {


              var userObject = JSON.parse(answer);


              g_form.setValue('mavis_access_employee_login_name', userObject.user_name);


            g_form.setValue('mavis_access_users_title', userObject.title);


              g_form.setValue('mavis_access_please_select_office_locati', userObject.location.sys_id, userObject.location.name);


              g_form.setValue('mavis_access_please_select_department', userObject.department.sys_id, userObject.department.name);


      } catch (err) {


              console.log(err);


      }


});



This is calling a Script Includes that would look something like this:


Assume the Script Include is named UserUtils and is Client Callable


var UserUtils = Class.create();


UserUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {



    getUserDetails:function() {


          var sys_id = this.getParameter('sysparm_user_id');



          var user = new GlideRecord('sys_user');


          if (user.get(sys_id)) {


                  var userObject = {


                          "user_name": String(user.user_name),


                          "title": String(user.title),


                          "location": {


                                  "sys_id": String(user.location),


                                  "name": String(user.location.getDisplayValue())


                            },


                            "department": {


                                    "sys_id": String(user.department),


                                    "name": String(user.department.getDisplayValue())


                            }


                  };


                  return JSON.stringify(userObject);


          }


          return false;


  },



  type: 'UserUtils'


});



I'm assuming that the location and department fields are Reference fields, so I'm returning the sys_id and display values. Then you use


g_form.setValue('reference_field_name', 'sys_id', 'display_value');


This prevents a synchronous AJAX call from looking up the display value if you only pass it the sys_id.



There are many ways to pass back data from a Script Includes. I personally prefer using JSON.   You can of course use any other method you choose.


You may need to learn about JavaScript Objects: JavaScript Objects, and JSON: JSON Tutorial



For the User record ACL, try copying the script from the default Write ACL into the Read ACL:


answer = gs.getUserID() == current.sys_id || gs.getUser().hasRoles();


View solution in original post

8 REPLIES 8

While we are at it, I have another catalog client script for an Incident record producer.



Essentially - the onChange catalog client script is for category and subcategory.   When a user selected the category, the client script selected only the subcategories that are associated with the category.



function onChange(control, oldValue, newValue, isLoading) {  


  if(newValue == oldValue){  


  return;  


  }  


  //remove all items from subcat drop down to start  


  // Used the g_form.clearOptions() function instead of g_form.removeOption() function  


  g_form.clearOptions('subcategory');  


 


  //build a new list of dependent options  


  var gp = new GlideRecord('sys_choice');  


  gp.addQuery('name', 'incident');  


  gp.addQuery('dependent_value', newValue);  


  gp.addQuery('element', 'subcategory');  


  gp.addQuery('inactive', 'false');  


  gp.query(function(gp) {  


  while(gp.next())  


  g_form.addOption('subcategory', gp.value, gp.label);  


  });  


 


}



The script works, however when an ESS user runs the record producer via the service portal, when the mandatory subcategory is selected, the form does not recognize that anything is entered.   When I make variable non mandatory, a user can select a subcategory, however it is not actually entered into the incident.   and Yes - the variable is mapped and it works for Admin and ITIL users.



find_real_file.png



Interestingly, when an ess user runs it via the service now side, it does select the subcategory



find_real_file.png



Do you guys know why this could be happening?


I haven't done anything with the Service Portal yet, so I wouldn't know.   You'd be better off posting this in a new thread so someone with Service Portal experience can help.


Cheers Geoff, that is a good idea!


Goran WitchDoc
ServiceNow Employee
ServiceNow Employee

Happy you got this solved while I was sleeping



Community FTW!



If you got any time over, take a look here. I've written down a few cases that might help you understand what you can do within ServiceNow:


Community Blogs



And of course there are a lot of others writing really good stuff there as well.



//Göran