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

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());
    });
});

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
Giga 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'
});