logo

NJP

Async Validation in onSubmit Catalog Client Script in Service Portal and Synchronous Validation in Native UI

Import · Sep 10, 2022 · article

Although it is not recommended to perform validations in onSubmit() catalog client script but let's say you have a business requirement to perform some validation on the submission of a catalog item via Order Now button and for some reason you are bound to use GlideAjax in onSubmit() catalog client script.

The first approach which you might think of is to use getXMLWait() to restrict submission until validation is performed. Sounds good, right? but the problem which you will face is that it will only work in Native UI but not in Service Portal because as per my knowledge synchronous calls are not supported in service portal and you will get a browser console error stating "GlideAjax.getXMLWait is no longer supported". The next approach would be to use asynchronous call to perform validation but the problem here is that the request will be submitted before the validation.

To overcome this, one of the solutions which can be leveraged is to stop the submission on first click of Order Now button and then perform asynchronous validation via GlideAjax. After validation re-submit the order. Looks promising, right? For this approach g_scratchpad or NOW objects can be used to define global variable and control the submission.

For Native UI getXMLWait() will be used, and for Service Portal g_scratchpad or NOW will be used. So, two onSubmit() catalog client scripts will be required. Isolate script is true in these implementations.

Based on the complexity of your script include validation, there might be some performance related issues like latency in user experience etc. Anyways let's see how this works.

Use Case:

It is not a fit for this scenario but just an effort to demonstrate how the approach works. So, validation is to stop the submission if the selected user is not a member of 'Testing' group.

Script Include

var GroupMembership = Class.create();
GroupMembership.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    isMember: function(){
        var user_sysID = this.getParameter('sysparm_user_sysid');
        return gs.getUser().getUserByID(user_sysID).isMemberOf('Testing');
    },

    type: 'GroupMembership'
});

Note: For Service Portal either use the catalog client script with g_scratchpad or NOW

Catalog Client Script with g_scratchpad, UI Type = Mobile / Service Portal

function onSubmit() {

    g_form.hideFieldMsg('user');
    //alert('1 ' + g_scratchpad.isGroupMember);
    if (g_scratchpad.isGroupMember) {
        return true;
    }

    actionName = g_form.getActionName();

    var ga = new GlideAjax('global.GroupMembership');
    ga.addParam('sysparm_name', 'isMember');
    ga.addParam('sysparm_user_sysid', g_form.getValue('user'));
    ga.getXMLAnswer(callBack);

    function callBack(answer) {
        if (answer == 'false') {
            g_form.showFieldMsg('user', 'This user is not a member of Testing group.', 'error', true);
        } else {
            //alert('2 ' + g_scratchpad.isGroupMember);
            g_scratchpad.isGroupMember = true;
            //alert('3 ' + g_scratchpad.isGroupMember);
            g_form.submit(actionName);
            //alert('4 ' + g_scratchpad.isGroupMember);
            g_scratchpad.isGroupMember = false;
            //alert('5 ' + g_scratchpad.isGroupMember);
        }
    }

    return false;
}

Catalog Client Script with NOW, UI Type = Mobile / Service Portal

function onSubmit() {

    g_form.hideFieldMsg('user');
    //alert('1 ' + NOW.isGroupMember);
    if (NOW.isGroupMember) {
        return true;
    }

    actionName = g_form.getActionName();

    var ga = new GlideAjax('global.GroupMembership');
    ga.addParam('sysparm_name', 'isMember');
    ga.addParam('sysparm_user_sysid', g_form.getValue('user'));
    ga.getXMLAnswer(callBack);

    function callBack(answer) {
        if (answer == 'false') {
            g_form.showFieldMsg('user', 'This user is not a member of Testing group.', 'error', true);
        } else {
            //alert('2 ' + NOW.isGroupMember);
            NOW.isGroupMember = true;
            //alert('3 ' + NOW.isGroupMember);
            g_form.submit(actionName);
            //alert('4 ' + NOW.isGroupMember);
            NOW.isGroupMember = false;
            //alert('5 ' + NOW.isGroupMember);
        }
    }

    return false;
}

Catalog Client Script for Native UI, UI Type = Desktop

function onSubmit() {

    g_form.hideFieldMsg('user');

    var ga = new GlideAjax('global.GroupMembership');
    ga.addParam('sysparm_name', 'isMember');
    ga.addParam('sysparm_user_sysid', g_form.getValue('user'));
    ga.getXMLWait();

    var answer = ga.getAnswer();
    if(answer == 'false'){
        g_form.showFieldMsg('user', 'This user is not a member of Testing group.', 'error', true);
        return false;
    }

}

Results

Native UI

image

Service Portal

For user not member of specified group.

image

For user member of specified group.

image

You must be thinking that why not use only 1 catalog client script and utilize g_scratchpad or NOW.

Let me define what I have observed during different experiments.

  1. For g_scratchpad in Native UI I was getting "onSubmit script error: ReferenceError: g_scratchpad is not defined:
    function () { [native code] }"
  2. NOW works in both Native UI and Portal but the problem was "g_form.getActionName()" which was returning "undefined" rather than the name of recently/last clicked button in Native UI.
  3. Let's say somehow you managed to restrict the submission via "NOW" or "setClientData()/getClientData()", and you even managed to get the button name but there is one more challenge which you might face and that is g_form.submit()/g_form.save(). When you use this in Native UI then you migh get "The g_form.submit function has no meaning on a catlog item. Perhaps you mean g_form.addToCart() or g_form.orderNow() instead".

Some useful links to refer.

How to do async validation in an onsubmit client script | KB Article

How to validate before onSubmit in Mobile/Service Portal | KB Article

Next Experience client-side scripting global variables | NOW Object Docs

getXMLwait alternative for Service Portal | Community Article

g_scratchpad not defined : error coming onSubmit catalog client script | Community Thread

I want to determine the return value of "getXMLAnswer" in the catalog client script! ! | Community Thread

Interested in reading my other articles, go through the below link.

Useful Implementation for Service Portal and Native UI

Always open to learn new things.

Happy Learning

View original source

https://www.servicenow.com/community/developer-articles/async-validation-in-onsubmit-catalog-client-script-in-service/ta-p/2317699