Jon Barnes
Kilo Sage

As you probably already know, the only way to use GlideAjax in an onSubmit client script is to use getXMLWait and make a synchronous call to the server.

As you may also know, getXMLWait is flat-out not supported in Service Portal.

And so we have a problem. Many of us have use cases for checking something on the server when the user submits a form (or catalog request). But the above mutually exclusive facts have made it very difficult to create onSubmit scripts that do this and work for both native UI and Service Portal.

I am going to show you a fairly simple method for accomplishing this in a single script that works on both native and SP.

The idea is to hold a property in a persistent object on the client side that tells our submit script if the GlideAjax function has completed and is successful. So here is a simple script that you can use to accomplish this using GlideAjax and g_scratchpad:

function onSubmit() {
  if (g_scratchpad._ajaxChecked) {
    // We have run our Ajax Checks, so we can continue on
    // and let our form submission continue
    g_scratchpad._ajaxChecked = null;
    return true;
  }
  // use this line below if you want to store the specific action name
  g_scratchpad._action = g_form.getActionName();
  g_scratchpad._ajaxChecked = false;
  var ga = new GlideAjax('MyAjaxScriptInclude');
  ga.addParam('sysparm_name', 'myAjaxFunction');
  ga.getXMLAnswer(function(answer) {
    // I made this a simple check of a true/false result
    // but you can change this to check whatever suits your business case
    // and base it on what gets returned from your script include
    if (answer == "false") {
      // we didn't pass our checks, so alert the user and quit
      alert("didn't work");
      return;
    }
    // it worked! now we can resubmit the form with the 
    // property in place to allow us to continue
    // so once we resubmit, it will re-run this function but will return true
    // at line 5 of this script
    g_scratchpad._ajaxChecked = true;
    if (typeof g_form.orderNow != 'undefined') {
      // this is a catalog item
      g_form.orderNow();
    } else {
      // this will resubmit the form using the saved 
      // ui action that was originally clicked
      g_form.submit(g_scratchpad._action);
    }
  });
  // always return false if we get to this point
  return false;
}

Let me know if any questions!

13 Comments
Shalu04
Giga Explorer

Hello @Jon Barnes ,

 

I am working on a similar requirement, Can you help me with the script include that you are using in this script?

 

LAXMI TODAKAR2
Tera Contributor

Hi @Shalu04 ,

 

Below solution is worked for me, please find the link below.

https://www.servicenow.com/community/developer-forum/using-return-false-in-glide-ajax/m-p/1567135 

hrawat738405662
Tera Contributor

EDITED :- I Got An Alternative Way 


@Jon Barnes @LAXMI TODAKAR2 @Shalu04 @Al-jhon @Atchamma D 


Amazing and a very clever way of marking the async operation completion , it worked for me !! , thanks a lot @Jon Barnes . However my question to everyone is can this be done using Promises as promises also can indicate the completion of an async operation , however i think we cant use .then .catch promise chaining yet or async await also . Anyone please let me know if the above solution can also be done via promise. 

EDITED :- Below is my approach for above scenario which can work for both portal as well as native view.

However i also had the same issue that others are having in the native view , its not able to find the g_scratchpad and even if you decide to write a display business rule we know that display Business Rules on the catalog item view do not exist - https://www.servicenow.com/community/service-management-forum/g-scratchpad-not-working-on-native-ui-...

so to tackle that we need another kind of marker that can run on both service portal as well as on the native view , here is the alternate solution without using g_scratchpad and without using display business rule :-

 

Use a Checkbox Field Instead of g_scratchpad

You can replace use of g_scratchpad with a checkbox field on the form. This will work in both the native UI and Service Portal.

Step 1: Create a Checkbox Field

Create a checkbox field on your catalog item form, for example, u_ajax_checked or any other name.


Step 2: Update Your onSubmit Script

Modify your script to use the checkbox field instead of g_scratchpad. 

My original plan was to hide this field but the script wont work if this field is hidden.  

hrawat738405662_0-1725955383031.png

Although in my case  If you uncheck all the options the to make it visible the script will not work correctly , the from submission will not proceed , however when i again checked all the above option and renamed my variable's display name the field is now hidden and the script also works perfectly for me , maybe its a glitch , however even if you don't want to do it from variables properties you can still hide the field from the script also and that will work too.

 

 

 

 

 

function onSubmit() {
    // If we've already run the GlideAjax check, allow the form to submit
    if (g_form.getValue('u_ajax_checked') === 'true') {
        g_form.setValue('u_ajax_checked', 'false'); // Reset the flag for future submissions
        return true;
    }

    // Set the action name for later use and initialize the check flag
    var action = g_form.getActionName();
    g_form.setValue('u_ajax_checked', 'false');

    var requestedFor = g_form.getValue('u_requestedfor');
    var ga = new GlideAjax('GetAssetDetails');
    ga.addParam('sysparm_name', 'getAssetInfo');
    ga.addParam('sysparm_sys_id', requestedFor);

    // Make the asynchronous GlideAjax call
    ga.getXMLAnswer(function(response) {
        if (response === 'true') {
            g_form.setVisible('u_justification', true);
            g_form.setMandatory('u_justification', true);

            var justification = g_form.getValue('u_justification');
            if (!justification) {
                g_form.addErrorMessage('Please provide a reason for requesting a new laptop during the warranty period.');
                return; // Stop here, do not proceed with submission
            }
        }

        // Set the flag indicating the check passed, and re-trigger form submission
        g_form.setValue('u_ajax_checked', 'true');
        if (typeof g_form.orderNow != 'undefined') {
            // For catalog items
            g_form.orderNow();
        } else {
            // For standard forms, re-submit with the saved action
            g_form.submit(action);
        }
    });

    // Prevent immediate form submission, as we are handling it asynchronously
    return false;
}

 

 

 

This way in my opinion the above solution will work both for Service portal as well as for the native view.
Let me know if it works for you !!