UI Action + Prompt for user input + Script Include

apjohn2
Mega Sage

Hi everyone. Gist: Looking for help w/ a UI Action (form link preferably) on the User [sys_user] table. I am struggling to understand all of the possible ways of doing this and the way I tried is not working as expected.

 

The basic idea is to automate the linking of records from one user to another (all incidents, requests, etc.) so that the duplicate user can be deleted.

 

When I click the link in a user record, I do get prompted for a sys_id value, but when I submit that, I get another alert that just says "null".

apjohn2_0-1722888468259.png

 

 

Currently have this UI Action script:

 

// Name: Prep for Deletion
// Table: User [sys_user]
// Action name: prep_for_deletion
// Active: true
// Show insert: false
// Show update: true
// Client: true
// Form link: true
// Onclick: relinkRecords();
// Condition: gs.hasRole("admin")

function relinkRecords() {
    var currentUserSysId = g_user.sys_id; // Current user's sys_id
    var targetUserSysId = prompt("Enter the sys_id of the primary user:");

    if (targetUserSysId) {
        // Call server-side script to update incidents
        var ga = new GlideAjax('UserRecordRelink');
        ga.addParam('sys_id', currentUserSysId);
        ga.addParam('primary_user_sys_id', targetUserSysId);
        ga.getXMLAnswer(function(response) {
            alert(response);
            if (response === 'success') {
                gs.addInfoMessage('Records relinked successfully.');
            } else {
                gs.addErrorMessage('Failed to relink records: ' + response);
            }
        });
    }
}

 

 

 

 

And this is the Script Include:

 

// Note: Client callable = true
// Also: For simplicity's sake I've taken out all the other tables and am showing just the update to Incidents

var UserRecordRelink = Class.create();
UserRecordRelink.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	relinkRecords: function() {
		var dupeUser = this.getParameter('sys_id');
		var primaryUser = this.getParameter('primary_user_sys_id');

		if (!dupeUser || !primaryUser) {
			return 'Missing sys_id parameters.';
		}

        // incident
        var inc = new GlideRecord('incident');
        inc.addEncodedQuery('caller_id=' + dupeUser + '^ORu_reported_by=' + dupeUser + '^ORopened_by=' + dupeUser);
        inc.query();
        while (inc.next()) {
            if (inc.caller_id == dupeUser) {
                inc.caller_id = primaryUser;
            }
            if (inc.u_reported_by == dupeUser) {
                inc.u_reported_by = primaryUser;
            }
            if (inc.opened_by == dupeUser) {
                inc.opened_by = primaryUser;
            }
            inc.setWorkflow(false);
            inc.autoSysFields(false);
            inc.update();
        }

	},
    type: 'UserRecordRelink'
});

 

 

 

Any advice would be much appreciated. Thank you!

1 ACCEPTED SOLUTION

I suggest you look at existing OOB client scripts and script includes. A simple example of an 'ohChange' client script getting a string value from a script include follows.

 

Client Script code:

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

	if (oldValue == newValue) {
		return;
	}

	//Type appropriate comment here, and begin script below
	var ga = new GlideAjax('XUserDetailsAjax');
	ga.addParam('sysparm_name','getCompany'); // function in the script include we're calling
	var usr = g_form.getValue('submitter');
	ga.addParam('sysparm_user_id', usr);

	/* Call function with user set and use the callback function getResponse() to return the result when ready */
	ga.getXMLAnswer(getResponse);  		
}

// callback function for returning the result from the script include
function getResponse(response) {
//	alert(response);
	g_form.setValue('u_company', response);
}

Script Include named 'xGetUserDetails' with Client Callable checked:

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

	getCompany: function() {
        var userID = this.getParameter("sysparm_user_id");
		var result = "";
 
		var user = new GlideRecord('sys_user');
		user.addQuery('sys_id', userID);
		user.setLimit(1);
		user.query();
		if (user.next()) {
			result = user.company.toString();
		}
		else {
			result = "Unknown";
		}
		return result;
    },

    type: 'XUserDetailsAjax'
});

Good luck.

View solution in original post

6 REPLIES 6

I suggest you look at existing OOB client scripts and script includes. A simple example of an 'ohChange' client script getting a string value from a script include follows.

 

Client Script code:

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

	if (oldValue == newValue) {
		return;
	}

	//Type appropriate comment here, and begin script below
	var ga = new GlideAjax('XUserDetailsAjax');
	ga.addParam('sysparm_name','getCompany'); // function in the script include we're calling
	var usr = g_form.getValue('submitter');
	ga.addParam('sysparm_user_id', usr);

	/* Call function with user set and use the callback function getResponse() to return the result when ready */
	ga.getXMLAnswer(getResponse);  		
}

// callback function for returning the result from the script include
function getResponse(response) {
//	alert(response);
	g_form.setValue('u_company', response);
}

Script Include named 'xGetUserDetails' with Client Callable checked:

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

	getCompany: function() {
        var userID = this.getParameter("sysparm_user_id");
		var result = "";
 
		var user = new GlideRecord('sys_user');
		user.addQuery('sys_id', userID);
		user.setLimit(1);
		user.query();
		if (user.next()) {
			result = user.company.toString();
		}
		else {
			result = "Unknown";
		}
		return result;
    },

    type: 'XUserDetailsAjax'
});

Good luck.

I will use this same logic but will use a different UI Action and a UI Page for inspiration. The thought to reuse what others have built was really what I needed to hear; for that I'm accepting your solution. 😁 Thanks @Bert_c1!