Copy RITM in portal - Variables not passing to new catalog item from UI Button widget

Earl Begley
Tera Guru

I have a requirement to allow a customer to:

  • copy a RITM to a new catalog item from the portal
  • Display the new catalog item in the portal
  • review and update the variables of the catalog item
  • Submit the catalog item with the updated variables

 

My script (see below) is opening the new cat_item and the URL is showing the variables, but the form fields are blank.
Any ideas? All help greatly appreciated.

(function() {

// Get table & sys_id
data.table = input.table || $sp.getParameter("table");
data.sys_id = input.sys_id || $sp.getParameter("sys_id");

// Validate table and sys_id
var gr = new GlideRecord(data.table);
if (!gr.isValid()) {
data.error = "Invalid table specified.";
return;
}

if (!gr.get(data.sys_id)) {
data.error = "Invalid sys_id or record not found.";
return;
}

try {
var catalogItem = gr.cat_item; // Get associated catalog item

// Handle cases where cat_item is blank
if (!catalogItem) {
data.error = "No associated catalog item found for this RITM.";
return;
}

// Prepare the base URL for the catalog item form
var url = "/ohd?id=sc_cat_item&sys_id=" + catalogItem;

// Add variables from the original RITM as a query string
var variables = gr.variables.getElements();
var sysparmQuery = [];
for (var i = 0; i < variables.length; i++) {
var question = variables[i].getQuestion();
var name = question.getName();
if (name) {
var value = gr.variables[name] ? gr.variables[name].toString() : ""; // Safely retrieve variable value
value = encodeURIComponent(value); // Encode the value for URL
sysparmQuery.push(name + "=" + value); // Append variable as a key-value pair
}
}

// Add sysparm_query to the URL
if (sysparmQuery.length > 0) {
url += "&sysparm_query=" + sysparmQuery.join("^");
}

// Return the constructed URL
data.url = url;
} catch (ex) {
gs.error("Error while copying RITM to catalog item: " + ex.message);
data.error = "An unexpected error occurred.";
}

})();

 

 

1 ACCEPTED SOLUTION

Earl Begley
Tera Guru

I have updated the server script code in the widget to
// Copy all variables from the original RITM to the new one
var originalVars = new GlideRecord('sc_item_option_mtom');
originalVars.addQuery('request_item', ritmSysId);
originalVars.query();
while (originalVars.next()) {
var newVar = new GlideRecord('sc_item_option_mtom');
newVar.initialize();
newVar.request_item = newRitmSysId;
newVar.sc_item_option = originalVars.sc_item_option;
newVar.item_option_new = originalVars.item_option_new;
newVar.value = originalVars.value;
newVar.insert();
}

All variables are now appearing

View solution in original post

5 REPLIES 5

jcmings
Mega Sage

Here is my recommendation:

  • On the "new" catalog item, create a variable that references the sc_req_item table. This is how the user will pick which RITM to copy info from. I'll call this Source RITM.
  • Create an onChange client script that triggers on the change of Source RITM. You'll use GlideAjax to contact a script include that retrieves all the values for you and then sets them on the catalog item.
  • Create a script include that does your look ups and returns an object with values.

 

OnChange client script with GlideAjax

 

var ga = new GlideAjax("script_include_name"); //update to your script include 
        ga.addParam("sysparm_name", 'your_function_name'); //update to function name from the script include
        ga.addParam("sysparm_ritm", newValue);
        ga.getXML(setFields);

    }

	function setFields(response) {
            //Receive response, format, and post
            var answer = response.responseXML.documentElement.getAttribute("answer");
            var obj = JSON.parse(answer);
			g_form.setValue('variable_name', obj.field_one); 
        }

 

 

Script Include code

 

    your_function_name: function() {
        var pos_sys_id = this.getParameter('sysparm_ritm');
        var gr = new GlideRecord('sc_req_item');
        gr.addEncodedQuery('sys_id=' + sysparm_ritm);
        gr.query();
        if (gr.next()) {
            var obj = {
                field_one: gr.getValue('field'), //field_one is what we're calling the value from the RITM
                field_two: gr.getValue('field'), 
            }; 
            //Send back the data
            return JSON.stringify(obj);
        } 

 

 Note that you may need to modify the second line of your script include record to include this extension statement:

 

.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {

 

 

 

Alternatively, look into this article on Setting Catalog Item Variables from URL Params.

Thanks for the info...I'll see if I can get this to work

@jcmings thanks for the info, but this the suggestion doesn't help. This all works fine in the classic UI backend and I have that working. The code above is part of the UI Button widget in the portal (server side script). I did edit my description to clarify what I'm trying to do.

Apologize as I am new to working with portal widgets and coding.

So just to confirm, you want to view a RITM in the Portal and click a button called "Copy" that takes you to a new catalog item with the same information pre-loaded?

 

If so, you'll still need to do everything I mentioned, including loading in the XML from the Setting Catalog Item Variables from URL Params page. You'll also still need to create the Source RITM variable on the new catalog item (it can be hidden, but must exist on the catalog item).

 

It sounds like your UI Action is already sending the user to the catalog item page, but the variable loading isn't working properly. The variable set included in the link I mentioned will help you achieve that; you'll just append to your URL something like &sysparm_variables={"source_ritm":"sys_id_grabbed_from_original_ritm_url_parameters"}