Filter a reference field in g modal in Workspace

Todor Apostolov
Tera Contributor

Hello guys, I read all articles regarding the subject of that question and I couldn't find an answer. Such basic functionality as filtering reference field should be possible, but it's a struggle. I have a requirement to click a button from Risk workspace>Risk mitigation task (open mitigation tasks) and select an issue (sn_grc_issue) to link. That's why I used g modal to show that field in Workspace, but cannot filter the list. The filter condition is issue type = Risk response type (18). Here's my code in Workspace client script in UI action:

 

var fields = [{
        type: 'reference',
        name: 'u_risk_mitigation_plan', //this custom field contains reference to issues table
        label: getMessage('Select an existing issue'),
        mandatory: true,
        reference: 'sn_grc_issue',
        referringTable: 'sn_risk_mitigation_task',
        referringRecordId: g_form.getUniqueValue(),
sysparm_query: 'issue_type=18'
    }];
 
    g_modal.showFields({
        title: "Select an existing issue",
        fields: fields,
        size: 'lg'
    }).then(function(fieldValues) {
        //g_form.setValue('work_notes', fieldValues.updatedFields[0].value);
       // g_form.setValue('caller_id', fieldValues.updatedFields[2].value);
       // g_form.save();
g_form.submit(g_form.getActionName());
 
So sysparm_query: 'issue_type=18' is not working for me. Any suggestions how can I filter this? As a workaround I tried to create custom UI page and show it with g modal.showFrame method and it worked, but in the ui page I cannot use g form in order to get risk object from current(risk mitigation task) from which I am clicking the button, in order to assign it to the already selected issue from the list.
4 REPLIES 4

Riya Verma
Kilo Sage
Kilo Sage

Hi @Todor Apostolov ,

 

Hope you are doing great.

 

Try using below script

var fields = [{
    type: 'reference',
    name: 'u_risk_mitigation_plan', // this custom field contains reference to issues table
    label: getMessage('Select an existing issue'),
    mandatory: true,
    reference: 'sn_grc_issue',
    referringTable: 'sn_risk_mitigation_task',
    referringRecordId: g_form.getUniqueValue()
}];

var ajax = new GlideAjax('YourScriptIncludeName');
ajax.addParam('sysparm_name', 'getFilteredIssues');
ajax.addParam('sysparm_issue_type', '18');
ajax.getXMLAnswer(function(response) {
    var options = JSON.parse(response);
    fields[0].choices = options;

    g_modal.showFields({
        title: 'Select an existing issue',
        fields: fields,
        size: 'lg'
    }).then(function(fieldValues) {
        g_form.submit(g_form.getActionName());
    });
});
Please mark the appropriate response as correct answer and helpful, This may help other community users to follow correct solution.
Regards,
Riya Verma

Thank you for your answer, but this is not working for me. Have you tested that? options var must be an array of sys ids right?

Todor Apostolov
Tera Contributor

I managed to fulfill the requirement by using the custom UI page and I passed the sys id of the risk mitigation object that I needed in the url parameters when showing the ui page:

 

 

g_modal.showFrame({
url: '/sn_grc_issue_reference_field.do?from_workspace=true&sysparm_id=' + g_form.getUniqueValue(),
title: 'Select an existing issue',
size: 'lg',
height: '150px',
callback: function(ret, data) {
if (ret)
updateData(data);
}
});

function updateData(data) {

}

 

and this is my UI page:

HTML

 

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<g:ui_form>
<g:ui_reference name="issues" id="issues" table="sn_grc_issue" completer="AJAXTableCompleter" query="issue_type=18" />

<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td align="right" nowrap="true"><br />
<button class="btn btn-secondary" id="btnClose" style="margin-right:2px;" data-dismiss="GlideModal" onclick="cancel()">${gs.getMessage('Cancel')}</button>
<button class="btn btn-primary" id="btnOK" data-dismiss="GlideModal" onclick="ok()">${gs.getMessage('Ok')}</button>
</td>
</tr>
</table>
</g:ui_form>
</j:jelly>

 

 
Client script:
 

 

(function() {
var gdw = GlideDialogWindow.get();
gel('issues').focus();
})();

function ok() {
var issueObject = gel('issues');
var rmtID = window.top.location.toString().split("sysparm_id=")[0].toString().split("/")[8].toString();

if(issueObject.getValue('sys_id').toString() != ''){
var grIssue = new GlideRecord('sn_grc_issue');
grIssue.get(issueObject.getValue('sys_id').toString());

var grRiskMitigationTask = new GlideRecord('sn_risk_mitigation_task');
grRiskMitigationTask.get(rmtID);

if(grIssue != '' && grRiskMitigationTask != ''){
grIssue.item = grRiskMitigationTask.risk;

var risk = new GlideRecord('sn_risk_risk');
risk.get(grRiskMitigationTask.risk);

grIssue.profile = risk.profile;
grIssue.update();
alert('Issue "' + grIssue.short_description + '" was successfully linked to the related Risk and Entity of the Risk Mitigation Task');
}
} else{
alert('No issue has been selected! Please select an issue from the list!');
}
}

function cancel() {
GlideDialogWindow.get().destroy();
    return false;
}

 

simonezini
Mega Sage

I know this is an old thread, but I've managed to do that using g_modal with "choices" field type, and using a GlidaAjax to retrieve the list of choices to display (with values and displayValues).

Here is my UI Action workspace script:

function onClick(g_form) {
	function createRequest() {

		var fields = [];
		fields.push({
			type: 'string',
			name: 'reason',
			label: "Reason:",
			mandatory: true
		});

		var query = 'install_status=6^substatus=available^';
		query += 'model_category=SYS_ID';


		var ga = new GlideAjax('GetChoicesForWorkspace');
		ga.addParam('sysparm_name', 'getFieldChoices');
		ga.addParam('sysparm_table', 'alm_hardware');
		ga.addParam('sysparm_query', query);
		ga.addParam('sysparm_value', 'model');
		ga.addParam('sysparm_displayValue', '');

		ga.getXMLAnswer(function (answer1) {
			var answer = JSON.parse(answer1);
			fields.push({
				type: 'choice',
				name: 'available_models',
				label: "List of available models:",
				choices: answer.choices,
				mandatory: true
			});

			g_modal.showFields({
				title: "Details for substitution of " + g_form.getDisplayValue('cmdb_ci'),
				fields: fields,
				size: 'lg'
			}).then(function (fieldValues) {
				//Do whatever you want: here I call another GLideAjax to create a request...

				var ga = new GlideAjax('CreateRequestSubstitution');
				ga.addParam("sysparm_name", "createRequest");
				ga.addParam("sysparm_sys_id", g_form.getUniqueValue());

				ga.addParam("sysparm_reason", fieldValues.updatedFields[1].value);
				ga.addParam("sysparm_model", fieldValues.updatedFields[2].value);

				ga.getXML(parseQueryResponse);

			});

		});
	}

	function parseQueryResponse(response) {
		var answer = response.responseXML.documentElement.getAttribute("answer");

		g_form.setValue('state', 6);
		g_form.setValue('close_code', 'Solved (Permanently)');
		g_form.setValue('close_notes', 'Opened request number ' + answer);
		g_form.setValue('work_notes', 'Opened request number ' + answer);
		g_form.save();

		alert("Opened request number " + answer);
	}

	createRequest();
}




And here is my Script Include:

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

	getFieldChoices: function () {

		var tableName = this.getParameter('sysparm_table');
		var tableQuery = this.getParameter('sysparm_query');

		var recordValue = this.getParameter('sysparm_value');
		var recordDisplayValue = this.getParameter('sysparm_displayValue');

		var arr = [];
		// use this to add None if you wish to show when choices you are adding doesn't have it
		arr.push({
			"value": "",
			"displayValue": "-- None --"
		});


		var grQueryChoice = new GlideRecord(tableName);
		grQueryChoice.addEncodedQuery(tableQuery);
		grQueryChoice.query();
		while (grQueryChoice.next()) {
			var obj = {};

			obj["value"] = grQueryChoice[recordValue].toString();

			//If specified a field to use as display value, use it; otherwise, choose the display value of the field passed as value
			if (recordDisplayValue) {
				obj["displayValue"] = grQueryChoice[recordDisplayValue].toString();
			} else {
				obj["displayValue"] = grQueryChoice.getDisplayValue(recordValue).toString();
			}

			arr.push(obj);
		}

		//Remove duplicates from array
		var arrayNoDuplicates = arr.filter((object, index, array) => {
			var indexFirst = array.findIndex(item => item.value === object.value);
			return indexFirst === index;
		});

		var result = {};
		result["choices"] = arrayNoDuplicates;

		return JSON.stringify(result);
	},

	type: 'GetChoicesForWorkspace'
});