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!

14 Comments
RAHUL Khanna1
Mega Guru

Great, Thanks for the Blog. Can you suggest any way whhere I want to create a function to call the server call and use that function in main in submit function.

Exe: 

function onSubmit()

{

if (a== b)

ServerCall(obj1)

if(a==c)

ServerCall(obj2)

}

function ServerCall(obj)

{

YOUR GLIDE AJAX CALL.

}

Ramiro Rincon B
Tera Contributor

Hi @Jon Barnes, thanks for the blog post.

Are you using g_scratchpad without defining the variables in a Display Business Rule?

And it worked for you?

Because it didn't work for me. I'm trying to use your example for a Catalog Client Script, and here is the error message displayed at the top of the page:

find_real_file.png

The CCS is set to work only on Desktop.

Can you help me?

Thanks in advance!

Patrick Boutet
Mega Expert

Thanks,

This is very useful. 

In my case, I use Ajax call to verify cat item form consistency. 
And I would like to allow end user to correct data and resubmit with new values.


Your script doesn't handle this case because g_scratchpad._ajaxChecked is set to true after the first check (with incorrect result).
We need to 'forget' the first ajax call when data are changed and Order button is pressed again

Any idea to do this ? 

Jon Barnes
Kilo Sage

sorry for the delay. yes you are correct, I left out one part. I edited the code above to add g_scratchpad._ajaxChecked = null before returning true. this will reset it for the next submission.

Jon Barnes
Kilo Sage

Yes, sorry should have clarified this code will not work on catalog. there are 2 issues to overcome, 1 is that g_scratchpad doesn't exist, so need to select another persistent object. you may try g_form instead, but that gets reset after loading of the form. in theory this should be ok, but may want to confirm. 2 is that g_form.submit() doesn't work in catalog. there is another function they run to submit the form and there may be a little more complexity around how that works. I haven't looked at it closely enough to edit the above script, but presumably, somebody could look at the inner workings of submitting a catalog item and get it working.

Mrman
Tera Guru

Hi @Ramiro Rincon Barraza 

 

I have tried the script and getting the same error , could you please let me know what was done for this to work on a Record producer/ Catalog item.

 

find_real_file.png

Jack Zheng3
ServiceNow Employee

This post a very helpful. 

However,  I couldn't get g_form.OrderNow() to work on Service Portal and g_form.getControl('order_now_button').click() mentioned in another community article doesn't work either.

This article will shows how to use g_form.getActionName() and g_form.submit('name_of_action') to get it working as of the Rome release:

https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0779964

 

The code above happens to work because typeof g_form.orderNow will always return undefined in Service Portal

Hope this will save someone else lots of time searching like I had to do today to finally get everything working.

ctsmith
Mega Sage

So helpful!  I had a different way of doing this but I was at a different company and I lost my update set that had the code in it!  I have no idea what I did to make it work 4 years ago. Ha! So, lifesaver here.

Question: Why the undefined "return;"?  Any different in setting that one to return false;?

I used this to check an onSubmit if the incident state is resolved only.  If it returns false it resets the state back to the previous state via onDisplay BR with scratchpad sending over the state. Another addition if someone is doing something similar and if the user changes his/her mind and decides to save the form not in the resolved state is to add a return true; outside the condition if it's not being save/submitted in the resolved state (or any other condition your checking against). Otherwise, I noticed the save/submit option doesn't work.

Thanks again!

PS--This does also work as is in workspace views.

Atchamma D
Tera Contributor

Hi @Mrman 

Did you get solution to the above script, Please share even iam also facing same issue

Al-JhonV
Kilo Sage

Hello @Jon Barnes 

I'm facing this kind of issue where I am using Glide Ajax in onSubmit.

Here's my code:

function onSubmit() {
//Type appropriate comment here, and begin script below

 


var gStage = new GlideAjax('VSHMandatoryVariablesAJAX');

gStage.addParam('sysparm_name', 'getStage');
gStage.addParam('sysparm_item', g_form.getValue('request_item'));
gStage.getXMLAnswer(_response);



function _response(response){
var answer = response;
g_form.addInfoMessage("Stage is :" + answer);



if(g_form.getValue('state') == 3){//close complete

if((g_form.getValue('what_needs_to_be_changed') == 'Name') && (answer == 'fulfillment')){

if((g_form.getValue('new_userid') == '') && ('new_cn') == ''){//if new user form is empty or blank it will give error message


g_form.setMandatory('new_userid', true); //set the variable for new user form mandatory
g_form.setMandatory('new_cn', true); //set the variable for new user form mandatory

alert('Please input the New Userid and CN');
return false;

}
}
}
}
}

the return false is not working and let the form to submit even it meets the condition.

I have no idea where to put your solution. Can you please help?