Update a List Collector field dynamically on the Service Portal based on another field

stephera
Tera Contributor

Hi All,

I'm seeking assistance with a requirement I have which is to to populate a list collector field based on what is entered in another field.

So basically if a name is entered into a field called comparable_user the list collector field called group_names will populate the groups that user is a member of. 

The comparable_user field is referencing the sys_user table and the group_names field is referencing the sys_user_group table. 

I have tried numerous examples posted here in the community forums but for some reason I can't get this to work. Below is what I have so far. 

 

Script Include

var ajaxGetUserGroups = Class.create();
ajaxGetUserGroups.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    getGroups: function() {
        var user = this.getParameter('sysparm_user');
        var rel = new GlideRecord('sys_user_grmember');
        rel.addQuery('user', user);
        rel.query();

        var group_arr = [];
        var sys_id_arr = [];

        while (rel.next()) {
            group_arr.push(rel.group_names.name.toString());
            sys_id_arr.push(rel.group_names.toString());
        }
        return group_arr.toString() + '||' + sys_id_arr.toString();
    },

});

OnChange Catalog Script

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }

    //Type appropriate comment here, and begin script below
    var compUser = g_form.getValue('comparable_user');
	
    var ajax = new GlideAjax('ajaxGetUserGroups');
    ga.addParam('sysparm_name', 'getGroups');
    ga.addParam('sysparm_name_user', 'compUser');
    ga.getXML(doSomething);

    function doSomething(response) {
        var answer = response.responseXML.documentElement.getAttribute('answer');
        var arr = answer.split('||');

        if (window === null)
            g_form.setValue('group_names', arr[1], arr[0]);
        else
            addItemstoList('group_names', arr[1], arr[0]);
    }

    function addItemstoList(listCollector, sysid, display_value) {

        var varName = listCollector;
        var leftBucket = gel(varName + '_select_0');
        var rightBucket = gel(varName + '_select_1');
        var selectedOptionsIDs = [];

        rightBucket.options.length = 0;

        if (sysid != '') {
            var myCIArray = sysid.split(',');
            var displayvalue = display_value.split(',');

            for (i = 0; i < myCIArray.length; i++) {
                var option = document.createElement('option');
                option.value = myCIArray[i];
                option.text = displayvalue[i];
                // add the option to the bucket 
                rightBucket.add(option);
            }
        }
        // sort the buckets 
        sortSelect(rightBucket);
        moveSelectedOptions(selectedOptionsIDs, leftBucket, rightBucket, '--None--');

    }
}

 Thanks!

4 REPLIES 4

Ankur Bawiskar
Tera Patron
Tera Patron

@stephera 

I have written a detailed blog for the same few years ago

have a look

Dynamically set list collector on change of variable 

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
✨ Certified Technical Architect  ||  ✨ 9x ServiceNow MVP  ||  ✨ ServiceNow Community Leader

@Ankur Bawiskar 

Thank you for assisting. I used your example and it works in the native view but not in the service portal view. Any suggestions? My code is below. 

 

Script Include

var getAssignGroups = Class.create();
getAssignGroups.prototype = Object.extendsObject(AbstractAjaxProcessor, {

	getUserGroups: function(){

		var listGroup = [];
		var user = this.getParameter('sysparm_comparable_user');
		var parm = this.getParameter('sysparm_view');

		var jsonArr = [];

		var recGrp = new GlideRecord('sys_user_grmember');
		recGrp.addQuery('user', user);
		recGrp.query();
		while (recGrp.next()) {

			if(parm == 'portal'){
				listGroup.push(recGrp.group.toString());
			}
			else if(parm == 'native'){
				var obj = {};
				obj.name = recGrp.group.name.toString();
				obj.sys_id = recGrp.group.toString();
				jsonArr.push(obj); 
			}

		}

		if(parm == 'portal')
			return listGroup.toString();
		else
			return JSON.stringify(jsonArr);

	},

	type: 'getAssignGroups'
});

 

 OnChange Catalog Script

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }

    // give here the list collector variable name
    g_form.clearValue('group_names');

    var parm = '';
    if (window === null)
        parm = 'portal';
    else
        parm = 'native';

    var ajax = new GlideAjax('getAssignGroups');
    ajax.addParam('sysparm_name', 'getUserGroups');
    ajax.addParam('sysparm_comparable_user', newValue);
    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('group_names', arr[0]); // Mobile/Portal Compatible

    } else {
        addItemstoList('group_names', answer); // Native Compatible
    }
}

function addItemstoList(listCollector, groupList) {

    var parser = JSON.parse(groupList);

    var arrSysId = [];
    var arrName = [];
    for (var i = 0; i < parser.length; i++) {
        arrName.push(parser[i].name.toString());
        arrSysId.push(parser[i].sys_id.toString());
    }

    var varName = listCollector;
    var leftBucket = gel(varName + '_select_0');
    var rightBucket = gel(varName + '_select_1');
    var rightOptions = rightBucket.options;
    var rightIDs = [];

    //Remove --None--
    for (var k = 0; k < rightOptions.length; k++) {
        var value = rightOptions[k].innerHTML;
        if (value == '--None--') {
            rightBucket.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]);
            sortSelect(rightBucket);
            leftBucket.onchange();
        }
    }

    // sort the buckets
    sortSelect(rightBucket);
}

 

@stephera 

you want the list collector to be populated based on another field

then in native why to set the left bucket; directly set the right bucket value

You didn't check my complete code of client script

please modify as per it and it will work fine

Regards,
Ankur
✨ Certified Technical Architect  ||  ✨ 9x ServiceNow MVP  ||  ✨ ServiceNow Community Leader

i have seen that you have added values to right bucket.

how can we add options (sys_id's )to left bucket so that they will be visible as drop down so that user can select