UI Script (UI type: all) calling issue

Mainak1
Tera Contributor

I have a UI Script of type all as following:

(function() {
	if (typeof g_ui_scripts !== 'undefined') return CincValidatorUtils;
})();

function CincValidatorUtils() {
    return {
        fieldNAValidator: function(g_form, field, fieldValue) {
            // some logic using g_form
        }
    };
}

I am able to call it with g_ui_scripts as follows:

function onLoad() {
    var fieldsToWatch = [
        'u_comments',
        'u_issue_summary'
    ];
    var validator;
    if (typeof g_ui_scripts !== 'undefined') {
        g_ui_scripts.getUIScript('CincValidatorUtils').then(script => {
            validator = script();
        });
    }

    var handler = function(fieldName, originalValue, newValue) {
        if (typeof g_ui_scripts !== 'undefined') {
            if (fieldsToWatch.indexOf(fieldName) > -1) {
                validator.fieldNAValidator(g_form, fieldName, newValue);
            }
        }
    }
    g_form.onUserChangeValue(handler);
}

But unable to call it with ScriptLoader:

function onSubmit() {
    var fieldsToWatch = [
        'u_comments',
        'u_issue_summary'
    ];
    var isValid = false;
    if (g_scratchpad.isFormValid) {
        return true;
    }

	ScriptLoader.getScripts(['CincValidatorUtils.jsdbx'], function() {
		g_form.addInfoMessage("script loaded");
		var validator = CincValidatorUtils();
		g_form.addInfoMessage("validator loaded");
		for (var elem of fieldsToWatch) {
            if (validator.fieldNAValidator(g_form, elem, g_form.getValue(elem).toString())) {
                isValid = false;
            }
        }
	})
    if (isValid) {
        g_scratchpad.isFormValid = true;
        g_form.submit(g_form.getActionName());
    }
    return false;
}

I want to call it from all the UIs like classic and ServicePortal without any globalThis or window object. Is it possible to do?

3 REPLIES 3

yashkamde
Mega Sage

Hello @Mainak1 ,

 

To call it on service portal after creating UI Script,

1. goto -> Service Portal -> Dependency-> New

    1. check "include page on load"

    2. select the page to load

2. add the JS Includes -> new and your UI script here.

3. Go to the widget which is included in your page.

    1. go to the related list " Dependencies"

    2. click "Edit"

    3. Add the JS includes added in step 3.

 

If my response helped mark as helpful and accept the solution.

lauri457
Tera Sage

 

What is the problem with passing reference to global? With scriptloader you are just adding a <script> tag and any top level function declaration will be a property of global

(function() {
	if (typeof g_ui_scripts !== 'undefined') return CincValidatorUtils;
})();

function CincValidatorUtils() {
    return {
        fieldNAValidator: function(g_form, field, fieldValue) {
            // some logic using g_form
        }
    };
}

/*
window.CincValidatorUtils === CincValidatorUtils //true
*/
(function () {
	if (typeof g_ui_scripts !== 'undefined') return CincValidatorUtils;
})();

(function (g) {
	g.CincValidatorUtils = function () {
		return {
			fieldNAValidator: function (g_form, field, fieldValue) {
				console.log('asd')
				// some logic using g_form
			}
		};
	}
})(globalThis)

/*
window.CincValidatorUtils === CincValidatorUtils //true
*/

Have you read this article? https://sn-nerd.com/2023/11/28/how-to-convert-ui-scripts-to-run-in-configurable-workspaces/

 

Scriptloader is asynchronous and it seems your example script is an onsubmit client script which is probably why it's not working as expected. Also as yashkamde wrote you should load portal dependencies through the portal theme or widgets.

Ankur Bawiskar
Tera Patron

@Mainak1 

check this link

How to make UI Scripts work in all User Interfaces 

💡 If my response helped, please mark it as correct and close the thread 🔒— this helps future readers find the solution faster! 🙏

Regards,
Ankur
Certified Technical Architect  ||  10x ServiceNow MVP  ||  ServiceNow Community Leader