Convert UI Macro to Widget

Suryansh Verma
Tera Contributor

Hello Community,

 

I have created a UI Macro which is being used to upload data into MRVS from an attachment at the click of a button.

That is working fine in native view but I would like to use it on Portal as well.

 

Could someone point me in the right direction on how to implement this?

 

UI MACRO:

 

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<input type="button" onclick="applyVariables()" value="Apply Data"/>

<script>

function applyVariables(reference) {
var cartID = g_form.getParameter("sysparm_item_guid");
var ga = new GlideAjax('global.MRVDataUtils');
ga.addParam('sysparm_name','getCSVData');
ga.addParam('sysparm_cart_id', cartID);
ga.getXML(processResponse);
}

function processResponse(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer);
g_form.setValue('list_of_participants',answer);
}

</script>
</j:jelly>

1 ACCEPTED SOLUTION

Well, I have recreated the solution with the information provided an it did not work for me either, until I have modified the function that creates the data source by adding line:

 

		grDs.csv_delimiter = ',';

 

Without that line the system would not load the data correctly.

Here's the test CSV I have used:

Name employee,Type of employee
"Alejandro Mascall","Type 1"
"Bridget Knightly","Type 2"
"Charles Beckley","Type 1"

And here's the working result:

2023-01-05-5.png

View solution in original post

9 REPLIES 9

-O-
Kilo Patron
Kilo Patron

Is this for a variable of type Macro or Macro with Label (later Custom or Custom with Label)?

Thanks for your response.

It is for the variable type custom with label.

Here's how you could do it:

Body HTML template:

 

 

<div>
	<div><label>c.server.get</label>&nbsp;<input ng-click="c.applyVariables()" type="button" value="${Apply Data}" /></div>
	<div><label>GlideAjax</label>&nbsp;<input ng-click="c.applyVariablesAjax()" type="button" value="${Apply Data}" /></div>
</div>

 

 

Of course in the final solution you would pick one and you would remove the label element(s).

Server script:

 

 

(function ($sp, data, input) {
	if (input.action == 'get-CSV-data')
		data.list_of_participants = new global.MRVDataUtils().getCSVData(input.cartID);
})($sp, data, input);

 

 

Here I am assuming that function getCSVData can be used both when calling it through GlideAjax and directly, as a regular Script Include method. But this is highly unlikely, so very likely you need to adapt this part.

Client controller:

 

 

api.controller = function ($scope) {
	var c = this;

	c.applyVariables = applyVariables;
	c.applyVariablesAjax = applyVariablesAjax;

	console.log('getCartID', getCartID());

	function applyVariables () {
		var cartID = getCartID();

		c.server.get({
			'action': 'get-CSV-data',
			'cartID': cartID,
		}).then(receiveCSVData);
	}

	function applyVariablesAjax () {
		var cartID = getCartID();

		var ga = new GlideAjax('global.MRVDataUtils');

		ga.addParam('sysparm_name', 'getCSVData');
		ga.addParam('sysparm_cart_id', cartID);

		ga.getXML(processResponse);
	}

	function getCartID () {
		return getTableIdOrParentScope($scope);
	}

	function getTableIdOrParentScope (scope) {
		return typeof scope.attachmentHandler != 'undefined' ?
			scope.attachmentHandler.tableId :
			typeof scope.$parent != 'undefined' ? getTableIdOrParentScope(scope.$parent) : '';
	}

	function processResponse (response) {
		var answer = response.responseXML.documentElement.getAttribute('answer');

		console.log('list_of_participants', answer);
		$scope.page.g_form.setValue('list_of_participants', answer);
	}

	function receiveCSVData (response) {
		console.log('list_of_participants', response.data.list_of_participants);
		$scope.page.g_form.setValue('list_of_participants', response.data.list_of_participants);
	}
};

 

 

Here too you can remove one set of functions and keep either only the "native" implementation (using c.server.get: applyVariables + receiveCSVData) or the GlideAjax based one (applyVariablesAjax + receiveCSVData). Of course you need to keep what you kept in the HTML template.

I suppose the key is function getCartID (and function getTableIdOrParentScope) that replaces

 

 

g_form.getParameter("sysparm_item_guid");

 

 

from the original implementation, cause g_form.getParameter() does not exist in Portal.

Finally, I am not sure that this method of deducing the cart ID is version agnostic. It would be good to know which version of SN are you on.

Also I'm sure you have figured it out by now, in Widget based variables g_form is accessed through $scope.page.g_form.

Thank you for your response and detailed explanation.

 

I tried implementing the above solution using the GlideAjax-based one (applyVariablesAjax + receiveCSVData) but unfortunately, it returns blank output on the portal.

 

HTML:

 

<div>

<div><label>GlideAjax</label>&nbsp;<input ng-click="c.applyVariablesAjax()" type="button" value="${Apply Data}" /></div>
</div>

 

Client Controller:

 

api.controller = function ($scope) {
var c = this;

// c.applyVariables = applyVariables;
c.applyVariablesAjax = applyVariablesAjax;

console.log('getCartID', getCartID());

// function applyVariables () {
// var cartID = getCartID();

// c.server.get({
// 'action': 'get-CSV-data',
// 'cartID': cartID,
// }).then(receiveCSVData);
// }

function applyVariablesAjax () {
var cartID = getCartID();

var ga = new GlideAjax('global.MRVDataUtils');

ga.addParam('sysparm_name', 'getCSVData');
ga.addParam('sysparm_cart_id', cartID);

ga.getXML(processResponse);
}

function getCartID () {
return getTableIdOrParentScope($scope);
}

function getTableIdOrParentScope (scope) {
return typeof scope.attachmentHandler != 'undefined' ?
scope.attachmentHandler.tableId :
typeof scope.$parent != 'undefined' ? getTableIdOrParentScope(scope.$parent) : '';
}

function processResponse (response) {
var answer = response.responseXML.documentElement.getAttribute('answer');

console.log('list_of_participants', answer);
$scope.page.g_form.setValue('list_of_participants', answer);
}

function receiveCSVData (response) {
console.log('list_of_participants', response.data.list_of_participants);
$scope.page.g_form.setValue('list_of_participants', response.data.list_of_participants);
}
};

 

 

OUTPUT:

 

list_of_participants []