The CreatorCon Call for Content is officially open! Get started here.

ui macro working on onLoad but not on onchange

revathy murugan
Tera Contributor

Hi,

 

I am new to UI macro, my requirement is to show a field message beside a field on RITM form. I achieved that by creating a ui macro and added that formatter to the form layout of RITM form and its working fine.

The next requirement is to show that message only for particular value on the field. This is not working.I need to show the message only when value is "Pending" on Validation status field. when i change the value to"accepted" the message(macro) is getting disappeared(working fine) but when i change it back to pending its not showing up again.

 

UI MACRO:

macro name : validation_pending

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">

<html>
<p id="demo"
style="position: absolute;
width: 150px;
right: 5px;
top: 70px;
margin-bottom: -40px;
padding: 5px;
padding-top: 5px;
padding-right: 5px;
padding-bottom: 5px;
padding-left: 5px
font-size: 4rem;
color: red;">
</p>
<body onload = "myFunction()" onchange = "checkDetails()">

<script>
var myFunction = function(){
if(g_form.getValue('u_validation_status') === 'Pending'){
document.getElementById("demo").innerHTML = "Please validate by selecting Accepted or Not Accepted in the Validation status field";
}else
document.getElementById("demo").style.display = "none";
}


var checkDetails = function(){
if(g_form.getValue('u_validation_status') === 'Pending'){
alert('onchange : '+g_form.getValue('u_validation_status'));
document.getElementById("demo").innerHTML = "Please validate by selecting Accepted or Not Accepted in the Validation status field";
}else
document.getElementById("demo").style.display = "none";
}

</script>
</body>
</html>
</j:jelly>

 

 

OnChange client script:

 

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
checkDetails();
var state = g_form.getValue('state');
var stage = g_form.getValue('stage');
var field = g_form.getControl('u_validation_status');

if (state == '8' && stage == 'validation') { // state Pending Validation and stage validation
if (newValue == 'Pending') {
checkDetails();

}
}
}

 

FORM View:

 

working fine on onload:

revathymurugan_0-1675845731732.png

Working fine if i change the value to "Accepted"

revathymurugan_1-1675845786905.png

 

Not Working when i change it back to "pending". (Message(macro) is not coming up)

revathymurugan_2-1675845848200.png

Please help me out to fix this.

3 REPLIES 3

-O-
Kilo Patron

UI Macros don't run neither on load nor on change.

UI Macros are HTML source generator (modules).

They just generate HTML (server side, of course).

 

That said, the reason why it is not working is because after setting the style to display = none, you never reset it to display = <something else then none>.

 

Also hiding and showing the paragraph element can also be done using the instructions:

jQuery(document.getElementById("demo")).hide();
jQuery(document.getElementById("demo")).show();

 

That said, SN has the option to show and hide field messages:

g_form.showFieldMsg()
g_form.hideFieldMsg()
g_form.hideAllFieldMsgs()

It's better to use those as those integrate well into the form and are upgrade safe.

 

While what you done works, it is very fragile, all it takes for SN or someone else to use the global function names myFunction or checkDetails and the functionality goes out the window.

I believe a better approach is something like this:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
	<script type="text/javascript">

(function () {
	addRenderEvent(addOnChangeHandling);

	function addOnChangeHandling () {
		var eventHandler = new GlideEventHandler('onChange', onChange, '${ref}');

		g_event_handlers.push(eventHandler);
	}

	function onChange (control, oldValue, newValue, isLoading, isTemplate) {
		console.log(oldValue, newValue, isLoading, isTemplate);
	}
})();

	</script>
</j:jelly>

Where the functions are "hidden" from global scope and will not interfere with any other stuff. In this case the functionality in the client script would be moved into function onChange in the UI Macro.

Hi,

Thanks for that, since i am very new to Macros please help me out on the below changes i made to my ui macro.

 

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">

<html>

<body onload = "myFunction()" >
<script type="text/javascript">

(function () {

addRenderEvent(addOnChangeHandling);

function addOnChangeHandling () {
var eventHandler = new GlideEventHandler('onChange', onChange, '${ref}');
g_event_handlers.push(eventHandler);
}

function onChange (control, oldValue, newValue, isLoading, isTemplate) {
console.log(oldValue, newValue, isLoading, isTemplate);
alert('a');
var state = g_form.getValue('state');
var stage = g_form.getValue('stage');
var field = g_form.getControl('u_validation_status');
alert('field : +field);
if (field == 'Pending') {
checkDetails();
}
}
})();



var myFunction = function(){
if(g_form.getValue('u_validation_status') === 'Pending'){
document.getElementById("demo").innerHTML = "Please validate by selecting Accepted or Not Accepted in the Validation status field";
}
else
document.getElementById("demo").style.display = "none";
}

var checkDetails = function(){
if(g_form.getValue('u_validation_status') === 'Pending'){
document.getElementById("demo").innerHTML = "Please validate by selecting Accepted or Not Accepted in the Validation status field";
}
else{
document.getElementById("demo").style.display = "none";
}
}

</script>

</body>
</html>
</j:jelly>

 

when used this script during onload itself my message didn't come up.

You are still not resetting the display style. Just setting innerHTML will not magically reset display. You need to explicitly set it:

document.getElementById("demo").innerHTML = "Please validate by selecting Accepted or Not Accepted in the Validation status field";
// You need to add something like below.
// It may be that inline-block is not what you need, but maybe "inline"
document.getElementById("demo").style.display = "inline-block";