- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-22-2020 03:47 AM
Hello,
We have a requirement to populate the right side of List collector referencing to Application table with respect to two Select box field choices.
Selectbox - Category : Customer , Selectbox - Category : Vendor
Selectbox - Type : Access Request , Selectbox - Type : Deletion Request
List Collector - Application : A, B , C, D , List Collector - Application : X, Y , Z
The Category and Type are mapped to Type and Category in CMDB application table , hence are pulling the choice values from there. Therefore whenever user chooses Type & Category in the Catalog for the respective mapped application should populate in the right side of list collector.
I have tried writing client script and Script include as follows but its not populating values somehow.
Please let me know where I need to make correction.
Script Include:
var getApplications = Class.create();
getApplications.prototype = Object.extendsObject(AbstractAjaxProcessor, {
selectAppl: function() {
var list = [];
var typ = this.getParameter('sysparm_type');
var ctg = this.getParameter('sysparm_category');
var parm = this.getParameter('sysparm_view');
var jsonArr = [];
var appl = new Gliderecord ('cmdb_ci_web_application');
appl.addQuery('u_type', typ);
appl.addQuery('u_category', ctg);
appl.query();
while(appl.next()){
if(parm == 'portal'){
list.push(appl.name);
}
else if(parm == 'native'){
var obj = {};
obj.name = appl.name;
obj.sys_id = appl.name.toString();
jsonArr.push(obj);
}
}
if(parm == 'portal')
return list.toString();
else
return JSON.stringify(jsonArr);
},
type: 'getApplications'
});
Onchange client script :
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue == '') {
return;
}
g_form.clearValue('select_appli_list');
var ctg = g_form.getValue('category');
var parm = '';
if (window === null)
parm = 'portal';
else
parm = 'native';
var ajax = new GlideAjax('getApplications');
ajax.addParam('sysparm_name', 'selectAppl');
ajax.addParam('sysparm_type', newValue);
ajax.addParam('sysparm_category', ctg);
ajax.addParam('sysparm_view', parm);
ajax.getXML(populateValues);
}
function populateValues(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
var arr = answer.split('||');
// give here the list collector variable name
if (window === null) {
g_form.setValue('select_appli_list', arr[0]); // Mobile/Portal Compatible
} else {
addItemstoList('select_appli_list', answer); // Native Compatible
}
}
function addItemstoList(listCollector, applList) {
var parser = JSON.parse(applList);
var arrSysId = [];
var arrName = [];
for(var i=0;i<parser.length;i++){
arrName.push(parser[i].name);
arrSysId.push(parser[i].sys_id.toString());
}
var varName = listCollector;
var leftBucket = gel(varName + '_select_0');
var rightBucket = gel(varName + '_select_1');
var rightOptions = leftBucket.options;
var rightIDs = [];
//Remove --None--
for (var k= 0; k < rightOptions.length; k++) {
var value = rightOptions[k].innerHTML;
if (value == '--None--') {
leftBucket.remove(0);
}
}
// Add new options
if (arrName.length > 0) {
var myCIArray = arrName.toString().split(',');
for (var j = 0; j < myCIArray.length; j++) {
addOption(rightBucket, arrSysId[j], myCIArray[j]);
moveSelectedOptions(rightOptions, leftBucket , rightBucket);
sortSelect(rightBucket);
leftBucket.onchange();
}
}
// sort the buckets
sortSelect(rightBucket);
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-22-2020 08:39 AM
There are a couple of different ways to do this, but going down the path you were on, these scripts will work in Service Portal and the Native UI for any number of records in the table. The same client script should be used onChange of Category and Type in case the requester populates them out of order. You can also add a reference qualifier on the List Collector variable so that onLoad, invalid Applications cannot be selected
javascript:"u_category=" + current.variables.category + "^u_type=" + current.variables.type
Client Script, with Isolate script box unchecked
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue == '') {
return;
}
g_form.clearValue('select_appli_list');
var ctg = g_form.getValue('category');
var typ = g_form.getValue('type');
if(ctg && typ){
var parm = '';
if (window === null)
parm = 'portal';
else
parm = 'native';
var varName = 'select_appli_list';// name of the list collector variable
var filterString = 'u_category=' + ctg + '^u_type=' + typ;
//first reset the filter (left side) based on the 2 variables
if(parm == 'portal'){
var myListCollector = g_list.get(varName);
myListCollector.reset();
myListCollector.setQuery(filterString);
}
else{
window[varName + 'g_filter'].reset();
window[varName + 'g_filter'].setQuery(filterString);
window[varName + 'acRequest'](null);
}
//now populate the Service Portal variable
if(parm == 'portal'){
var ajax = new GlideAjax('getApplications');
ajax.addParam('sysparm_name', 'selectAppl');
ajax.addParam('sysparm_type', typ);
ajax.addParam('sysparm_category', ctg);
ajax.getXML(populateValues);
function populateValues(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
var arr = answer.split('||');
//arr[1] has the sys_id of the applications
//arr[0] has the display name of the applications
g_form.setValue('select_appli_list', arr[1], arr[0]);
}
}
else{
//or move all selections from the left side to right side
//wrapped in a timeout to give the filter time to reset
//adjust the number (3000) lower if the move is waiting too long after the new choices are loaded, or higher if the move is attempted before the filter is done loading - so the incorrect values are moved to the right side
window.setTimeout(function(){
var leftBucket = gel(varName + '_select_0');
var rightBucket = gel(varName + '_select_1');
var selectedOptions = leftBucket.options;
var selectedIDs = new Array();
var index = 0;
for(var i = 0; i < selectedOptions.length; i++){
selectedIDs[index] = i;
index++;
}
rightBucket.options.length = '0';
moveSelectedOptions(selectedIDs, leftBucket, rightBucket);
sortSelect(rightBucket);
}, 3000);
}
}
}
Script Include, with Client callable box checked
var getApplications = Class.create();
getApplications.prototype = Object.extendsObject(AbstractAjaxProcessor, {
selectAppl: function() {
var name_arr = [];
var sys_id_arr = [];
var typ = this.getParameter('sysparm_type');
var ctg = this.getParameter('sysparm_category');
var appl = new GlideRecord ('cmdb_ci_web_application');
appl.addQuery('u_type', typ);
appl.addQuery('u_category', ctg);
appl.query();
while(appl.next()){
name_arr.push(appl.name.toString());
sys_id_arr.push(appl.sys_id.toString());
}
return name_arr.toString() + '||' + sys_id_arr.toString();
},
type: 'getApplications'
});
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-22-2020 04:07 AM
Are you using the Service Portal, native Service Catalog, or both? Change your object lines in the script include to
obj.name = appl.name.toString();
obj.sys_id = appl.toString();
This is assuming the List Collector variable also references the cmdb_ci_web_application table. The other important thing here is that the left side of the List must contain the choices to be moved to the right side before the move, and they have to be within the first results returned (default is 100). I can't immediately tell from your client script if you are resetting the filter before moving. Both scripts are a lot more complicated than they need to be if you're not using the Service Portal.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-22-2020 04:15 AM
Hello Brad,
Thanks for the quick reply.
Yes we will be using both Portal and native to submit the request. I have already tried the changes you had asked to but there is no changes I could observe therefore I was trying with this as my Name field in Application table is already a string field.
Thanks,
Shwetha Nair
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-22-2020 04:39 AM
It's best to use toString() when assigning objects just to be safe. Does the List Collector variable reference the cmdb_ci_web_application table? If not in your Script Include you have to query the table it does reference for the application names returned by the first query to return the sys_ids to the client script. In your client script alert on answer right after the var answer line to see if you are getting the results from the server script that you expect. Change the next line to
var arr = answer.split(',');
as the array will be comma-separated in both the portal and native paths. When testing this in native, do you have more than 100 values in this referenced table, and are the records in the answer shown in the left box without filtering or searching on anything?
The script include and client script need further changes, but I can't guide you on that until the above questions are answered.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-22-2020 04:48 AM
Does the List Collector variable reference the cmdb_ci_web_application table? - YES
When testing this in native, do you have more than 100 values in this referenced table, and are the records in the answer shown in the left box without filtering or searching on anything? - YES