- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-08-2019 07:09 AM
Hello,
We are deploying a few service catalog items in service portals and are having issues with catalog client scripts in service portal. They work fine i platform UI, com.glideapp.servicecatalog_cat_item_view.do, but not in service portal. Below is an example of an onChange catalog client script that we are having issues with. We are asking the user if they are the main point of contact for the request. If so, the client script auto populates the the contact name, email and phone number from the current loged in user. The first name and last name are populating correctly, but the email and phone number are not. Any help here is very much appreciated! Catalog client script below.
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue == '') {
return;
}
var choice = g_form.getValue('main_contact_question');
var user = new GlideRecord('sys_user');
user.get(g_user.userID);
var useremail = user.email;
var usernumber = user.phone;
if (choice == 'yes'){
var add1 = g_user.firstName;
var add2 = g_user.lastName;
var add3 = add1 + " " + add2;
g_form.setValue('contact_name', add3);
g_form.setValue('contact_email', useremail);
g_form.setValue('contact_phone_number', usernumber);
}
if (choice == 'no'){
g_form.setValue('contact_name', '');
g_form.setValue('contact_email', '');
g_form.setValue('contact_phone_number', '');
}
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-08-2019 11:23 AM
Hi Tyler
As discussed in your previous thread, you should be using async GlideAjax to return the user details from the server.
GlideAjax has two components, client-side call and a script include on the server side. I've broken your example into the relevant components below:
onChange Client Script
Code:
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
var choice = g_form.getValue('main_contact_question'); //get users answer to whether they are the main contact
var fields = "name,email,phone"; //comma separated list of required field names.
if (choice == "yes"){
var ga = new GlideAjax("userUtils"); //name of script include
ga.addParam("sysparm_name","userAjaxHandler"); //name of function
ga.addParam("sysparm_usersysid",g_user.userID); //user sys_id
ga.addParam("sysparm_fields", fields); //comma separated list of required field names.
ga.getXMLAnswer(callBack); //name of call back function
}
//clear values if choice is not "yes".
else {
g_form.setValue('contact_name', '');
g_form.setValue('contact_email', '');
g_form.setValue('contact_phone_number', '');
}
function callBack(answer) {
if (answer) {
//g_form.addInfoMessage("User details: " + answer);
var user = JSON.parse(answer); //convert answer string into JSON object
/*set the required fields*/
g_form.setValue('contact_name', user.name);
g_form.setValue('contact_email', user.email);
g_form.setValue('contact_phone_number', user.phone);
}
}
}
Client Callable Script Include
Script Include Configuration:
Code:
var userUtils = Class.create();
userUtils.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
userAjaxHandler: function() {
/*extract parameters from client script call */
var userSysId = this.getParameter("sysparm_usersysid");
var fields = this.getParameter("sysparm_fields");
/*create an array from the comma separated listed you have passed*/
var fieldsArray = fields.split(",");
/*call helper function to return the user details based on the required fields*/
var answer = this.userDetails(userSysId,fieldsArray);
return JSON.stringify(answer);
},
userDetails: function(userSysId, fields) {
//gs.info(gs.getMessage("BLS userDetails: userSysId: {0} - fields: {1}",[userSysId,fields]));
var details = {}; //create object to store results
var user = new GlideRecord("sys_user"); //query sys_user table
if (user.get(userSysId)) { //since we have the users sys_id we can use "get" to return the GlideRecord
/*cycle through the fields array*/
for (var i=0; i< fields.length; i++) {
var field = fields[i]; //extract field name from array
var fieldValue = user.getValue(field); //extrat field value based on field name
//gs.info(gs.getMessage("BLS: field: {0} - field value: {1}",[field,user.getValue(field)]));
if (fieldValue) {
details[field] = fieldValue; //if the field has a value then add to object
}
else {
details[field] = ""; //if the field is empty then return blank.
}
}
}
return details;
},
type: 'userUtils'
});
I haven't been able to fully test this but it should be pretty close. Let me know if it worked for you.
Brent
P.S. If my suggestion helped then please mark as helpful and/or correct so other community members can benefit from this information.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-08-2019 07:35 AM
First of all, you shouldn't be using glide records in the client, you're returning the whole record when all you need is one or two fields. Best practice is to use GlideAjax to call a server side script include. This link gives a really good guide to writing glide ajax, you can also check out TechNow episode 33.
I think the issue in your script is that you've populated your email and number variables with a pointer to a glide object rather than the actual value, try changing to the below and it should work (and, of course, write a glide ajax call to go it on the server :))
var useremail = user.getValue('email');
var usernumber = user.getValue('phone');
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-08-2019 08:09 AM
Using GlideAjax for this is probably your best solution, but you may be able to get it working if you change your GlideRecord to async using a callback function instead. Something like:
var user = new GlideRecord('sys_user');
user.addQuery('sys_id', g_user.userID);
user.query(userCallBack);
function userCallBack(user) {
if(user.next()) {
g_form.setValue('contact_email', user.email);
g_form.setValue('contact_phone_number', user.phone);
}
}
For anything more complicated I'd strongly recommend GlideAjax.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-08-2019 11:23 AM
Hi Tyler
As discussed in your previous thread, you should be using async GlideAjax to return the user details from the server.
GlideAjax has two components, client-side call and a script include on the server side. I've broken your example into the relevant components below:
onChange Client Script
Code:
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
var choice = g_form.getValue('main_contact_question'); //get users answer to whether they are the main contact
var fields = "name,email,phone"; //comma separated list of required field names.
if (choice == "yes"){
var ga = new GlideAjax("userUtils"); //name of script include
ga.addParam("sysparm_name","userAjaxHandler"); //name of function
ga.addParam("sysparm_usersysid",g_user.userID); //user sys_id
ga.addParam("sysparm_fields", fields); //comma separated list of required field names.
ga.getXMLAnswer(callBack); //name of call back function
}
//clear values if choice is not "yes".
else {
g_form.setValue('contact_name', '');
g_form.setValue('contact_email', '');
g_form.setValue('contact_phone_number', '');
}
function callBack(answer) {
if (answer) {
//g_form.addInfoMessage("User details: " + answer);
var user = JSON.parse(answer); //convert answer string into JSON object
/*set the required fields*/
g_form.setValue('contact_name', user.name);
g_form.setValue('contact_email', user.email);
g_form.setValue('contact_phone_number', user.phone);
}
}
}
Client Callable Script Include
Script Include Configuration:
Code:
var userUtils = Class.create();
userUtils.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
userAjaxHandler: function() {
/*extract parameters from client script call */
var userSysId = this.getParameter("sysparm_usersysid");
var fields = this.getParameter("sysparm_fields");
/*create an array from the comma separated listed you have passed*/
var fieldsArray = fields.split(",");
/*call helper function to return the user details based on the required fields*/
var answer = this.userDetails(userSysId,fieldsArray);
return JSON.stringify(answer);
},
userDetails: function(userSysId, fields) {
//gs.info(gs.getMessage("BLS userDetails: userSysId: {0} - fields: {1}",[userSysId,fields]));
var details = {}; //create object to store results
var user = new GlideRecord("sys_user"); //query sys_user table
if (user.get(userSysId)) { //since we have the users sys_id we can use "get" to return the GlideRecord
/*cycle through the fields array*/
for (var i=0; i< fields.length; i++) {
var field = fields[i]; //extract field name from array
var fieldValue = user.getValue(field); //extrat field value based on field name
//gs.info(gs.getMessage("BLS: field: {0} - field value: {1}",[field,user.getValue(field)]));
if (fieldValue) {
details[field] = fieldValue; //if the field has a value then add to object
}
else {
details[field] = ""; //if the field is empty then return blank.
}
}
}
return details;
},
type: 'userUtils'
});
I haven't been able to fully test this but it should be pretty close. Let me know if it worked for you.
Brent
P.S. If my suggestion helped then please mark as helpful and/or correct so other community members can benefit from this information.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-11-2019 12:57 AM
This is a good example of making your script includes reusable but you can make it even more reusable by passing in the table name as well:
var u_FieldUtils = Class.create();
u_FieldUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
fieldAjaxHandler: function() {
/*extract parameters from client script call */
var sysId = this.getParameter("sysparm_sysid");
var table = this.getParameter("sysparm_table");
var fields = this.getParameter("sysparm_fields");
/*create an array from the comma separated listed you have passed*/
var fieldsArray = fields.split(",");
/*call helper function to return the user details based on the required fields*/
var answer = this.fieldDetails(table,sysId,fieldsArray);
return JSON.stringify(answer);
},
fieldDetails: function(tableName, recordSysId, fields) {
//gs.info(gs.getMessage("BLS fieldDetails: table: {0} - sysId: {1} - fields: {2}",[tableName,recordSysId,fields]));
var details = {}; //create object to store results
var gr = new GlideRecord(tableName); //query table
if (gr.get(recordSysId)) { //since we have the sys_id we can use "get" to return the GlideRecord
/*iterate through the fields array*/
for (var i=0; i< fields.length; i++) {
var field = fields[i]; //extract field name from array
var fieldValue = gr.getValue(field); //extract field value based on field name
//gs.info(gs.getMessage("BLS: field: {0} - field value: {1}",[field,gr.getValue(field)]));
if (fieldValue) {
details[field] = fieldValue; //if the field has a value then add to object
}
else {
details[field] = ""; //if the field is empty then return blank.
}
}
}
return details;
},
type: 'u_FieldUtils'
});