Ui Scripts - how to make it work?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
6 hours ago
Hello,
I just created an UI Script to standardize the popup in my portal.
The code will be something like:
var OER_ModalUtils = (function() {
/**
* @typedef {Object} PopupConfig
*
* @property {'info'|'confirm'} type
* - 'info' : single OK button, non-blocking by nature.
* - 'confirm' : OK and Cancel buttons.
*
* @property {string} messageIdBody
* sys_ui_message key for the popup body text (required).
* Resolved via getMessage; falls back to the raw key if no translation is found.
*
* @property {string} [messageIdTitle]
* sys_ui_message key for the popup title.
* Only rendered in backoffice — ignored on Service Portal.
*
* @property {string} [labelConfirm]
* sys_ui_message key for the confirm/OK button label. Defaults to getMessage('Confirm').
* Only rendered in backoffice — ignored on Service Portal.
*
* @property {string} [labelCancel]
* sys_ui_message key for the cancel button label. Defaults to getMessage('Cancel').
* Only rendered in backoffice (confirm type only) — ignored on Service Portal.
*
* @property {Function} [onConfirm]
* Optional callback invoked when the user clicks the confirm button.
* Receives no arguments. If omitted, the modal simply closes.
*
* @property {Function} [onCancel]
* Optional callback invoked when the user clicks Cancel or dismisses the modal.
* Use this to implement any blocking or reset logic (e.g. field reset, submit cancel).
* Receives no arguments.
*
* @property {string} [caller]
* Optional free-text identifier of the calling context (e.g. 'field_change', 'activate_button').
* Not used internally — available for logging or conditional logic in callbacks.
*/
/**
* Displays a popup according to the provided configuration.
* Delegates to spModal on Service Portal, GlideModal on backoffice.
*
* @memberof OER_ModalUtils
* @Param {PopupConfig} config - Declarative configuration object for the popup.
* @returns {void}
*/
function show(config) {
if (!config || !config.messageIdBody) {
console.error('[OER_ModalUtils] - show() called without a required messageIdBody.');
return;
}
if (config.type === 'confirm' && !config.onConfirm && !config.onCancel) {
console.warn('[OER_ModalUtils] - Confirmation popup without onConfirm or onCancel callback. Buttons will simply close the modal.');
}
var type = config.type === 'confirm' ? 'confirm' : 'info';
var bodyText = getMessage(config.messageIdBody);
if (typeof spModal !== 'undefined') {
_showSpModal(type, bodyText, config);
} else if (typeof GlideModal !== 'undefined') {
_showGlideModal(type, bodyText, config);
} else {
console.error('[OER_ModalUtils] - No supported modal API found in this context.');
}
}
/**
* Renders the popup using spModal (Service Portal context).
* Title and button labels are not supported by the standard spModal API and are omitted.
*
* @private
* @Param {'info'|'confirm'} type
* @Param {string} bodyText - Resolved body message.
* @Param {PopupConfig} config
* @returns {void}
*/
function _showSpModal(type, bodyText, config) {
if (type === 'info') {
spModal.alert(bodyText).then(function() {
if (typeof config.onConfirm === 'function') config.onConfirm();
});
} else {
spModal.confirm(bodyText).then(function(confirmed) {
if (confirmed) {
if (typeof config.onConfirm === 'function') config.onConfirm();
} else {
if (typeof config.onCancel === 'function') config.onCancel();
}
});
}
}
/**
* Renders the popup using GlideModal (backoffice context).
* Uses glide_modal_confirm for 'confirm' type, glide_modal_info for 'info' type.
*
* @private
* @Param {'info'|'confirm'} type
* @Param {string} bodyText - Resolved body message.
* @Param {PopupConfig} config
* @returns {void}
*/
function _showGlideModal(type, bodyText, config) {
var titleText = config.messageIdTitle ? getMessage(config.messageIdTitle) : '';
var confirmText = config.labelConfirm ? getMessage(config.labelConfirm) : getMessage('Confirm');
var cancelText = config.labelCancel ? getMessage(config.labelCancel) : getMessage('Cancel');
var modal = new GlideModal(type === 'confirm' ? 'glide_modal_confirm' : 'glide_modal_info');
if (titleText) modal.setTitle(titleText);
modal.setPreference('body', bodyText);
modal.setPreference('buttonLabelComplete', confirmText);
modal.setPreference('onPromptComplete', function() {
modal.destroy();
if (typeof config.onConfirm === 'function') config.onConfirm();
});
if (type === 'confirm') {
modal.setPreference('buttonLabelCancel', cancelText);
modal.setPreference('onPromptCancel', function() {
modal.destroy();
if (typeof config.onCancel === 'function') config.onCancel();
});
}
modal.render();
}
return {
show: show
};
})();
The script, configured with "ui type: desktop" and "global:true" was working perfectly in my backoffice though a "client script" and "Ui action" but now I need to activate it also in the service portal.
I changed the "ui type" to all and... everything stop to work.
The global option disappeared and in the backoffice I'll receive an error saying "ReferenceError: OER_ModalUtils is not defined"
I've tried everyting but nothing seems to work.
My ui action was:
const util = new global.OER_global_util();
const nri = current.u_procedural_code_number;
if (util.isFormatContractDuplicate(nri)) {
OER_ModalUtils.show({
type: 'confirm',
messageIdTitle: 'eba_formatContract_pupup_title',
messageIdBody: 'eba_formatContract_pupup_body_2',
labelConfirm: 'Confirm',
labelCancel: 'Cancel',
onConfirm: function() {
done();
},
onCancel: function() {
current.setAbortAction(true);
}
});
} else {
done();
}
function done() {
current.update();
action.setRedirectURL(current);
}
The client script, is (after thousand of try so probably now is not really good):
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
try {
if (isLoading || newValue === '') {
return;
}
const showPopup = function() {
OER_ModalUtils.show({
type: 'info',
messageIdTitle: 'eba_formatContract_pupup_title',
messageIdBody: 'eba_formatContract_pupup_body_2',
labelConfirm: 'Confirm',
onConfirm: function() {},
});
}
const util = new GlideAjax('OER_global_util');
util.addParam('sysparm_name', 'isFormatContractDuplicate_ajax');
util.addParam('sysparm_nri', newValue);
util.getXMLAnswer(function(res) {
try {
console.log("%c[HERE][res]", "color: pink", res)
if (res) {
if (!OER_ModalUtils && g_ui_scripts) {
g_ui_scripts.getUIScript('myUIScript').then(function(script) {
showPopup()
}, function() {
console.log('The script did not load');
});
} else {
showPopup()
}
console.log("%c[HERE][7]", "color: pink")
}
} catch (e) {
console.error("[EBA - FORMAT CONTRACT][GLIDE AJAX] - ", e)
}
})
} catch (e) {
console.error("[EBA - FORMAT CONTRACT] - ", e)
}
}
Any suggestion?
The documentation said to add the script as dependences but I really need to have it available everywhere and, also, the dependence field is never present.
I'm using Australia release.
Thanks