Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Glideajax method is not working

suuriyas
Tera Contributor

HI Community,

 

I have a requirement, in a catalog item we have variables like name, type, target and table. when user fill the details and while submit the form , in sla definition table if we have records with same name, type , table and target then it should not submit the form it should throw an error.

for this i have tried client script and script include but form is getting submitted any how  not sure what is wrong in it.

client script;

function onSubmit() {
    if(g_form.submitted){
        return true;
    }
    var mrvsData = g_form.getValue('sla_configuration');
    if(!mrvsData) return true;
   
    var rows = JSON.parse(mrvsData);
    if(!rows || rows.length === 0){
        return true;
    }
    var name = rows[0].name;
    var type = rows[0].type;
    var target = rows[0].target;
    var table = rows[0].collection;

    var ga = new GlideAjax('SLAValidationUtils');
    ga.addParam('sysparam_name', 'checkDuplicate');
    ga.addParam('sysparam_name_val', name);
    ga.addParam('sysparam_type_val', type);
    ga.addParam('sysparam_target_val', target);
    ga.addParam('sysparam_table_val', table);

   ga.getXML(function(response){
    var answer = response.responseXML.documentElement.getAttribute("answer");

    if (answer == 'true') {
        g_form.addErrorMessage("SLA with same name, type, target and table already exists");
        return false;
    }
g_form.submitted = true;
g_form.submit();
   });
    return false;
    // alert ('onsubmit is running');
    // return false;
}
script include;
var SLAValidationUtils = Class.create();
SLAValidationUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
checkDuplicate: function(){
    var name = this.getParameter('sysparam_name_val');
    var type = this.getParameter('sysparam_type_val');
    var target = this.getParameter('sysparam_target_val');
    var table = this.getParameter('sysparam_table_val');

    var gr = new GlideRecord('contract_sla');
    gr.addQuery('name',name);
    gr.addQuery('type',type);
    gr.addQuery('target',target);
    gr.addQuery('collection',table);
    gr.query();

    if(gr.next()){
        return 'true';
    }
return 'false';
}
    //type: 'SLAValidationUtils'
});

 

2 REPLIES 2

palanikumar
Giga Sage
Giga Sage

Hi,

 

Is there a variable created with name "submitted"? Please ensure the MRVS variable has correct value. I possible share the sample value returned by  g_form.getValue('sla_configuration')

Note: Your script will pick only the first row from MRVS

 

Thank you,
Palani

Anupam1
Mega Guru

Hi @suuriyas ,

 

The issue is that your current approach mixes asynchronous GlideAjax with the synchronous onSubmit flow.

In ServiceNow, onSubmit must return true or false immediately. But ga.getXML() is asynchronous, so by the time your callback runs, the form has already been submitted. That’s why it “submits anyhow.”

Main Issues:-

  • onSubmit is synchronous, but GlideAjax is async. Returning false inside the callback doesn’t stop submission.
  • You’re calling g_form.submit() manually, which bypasses the natural onSubmit control.
  • g_form.submitted flag is unnecessary here and complicates logic.

 

Recommended Solution:-

Option 1: Use onSubmit with getXMLWait() (synchronous)

function onSubmit() {

    var mrvsData = g_form.getValue('sla_configuration');

    if (!mrvsData) return true;

 

    var rows = JSON.parse(mrvsData);

    if (!rows || rows.length === 0) return true;

 

    var name = rows[0].name;

    var type = rows[0].type;

    var target = rows[0].target;

    var table = rows[0].collection;

 

    var ga = new GlideAjax('SLAValidationUtils');

    ga.addParam('sysparm_name', 'checkDuplicate');

    ga.addParam('sysparam_name_val', name);

    ga.addParam('sysparam_type_val', type);

    ga.addParam('sysparam_target_val', target);

    ga.addParam('sysparam_table_val', table);

 

    var answer = ga.getXMLWait().documentElement.getAttribute("answer");

 

    if (answer == 'true') {

        g_form.addErrorMessage("SLA with same name, type, target and table already exists");

        return false; //  block submission

    }

 

    return true; //  allow submission

}

  • getXMLWait() makes the GlideAjax call synchronous, so onSubmit can properly return false before submission.
  • No need for g_form.submit() inside your script — ServiceNow handles submission if you return true.

 

Option 2: Use onChange or onBlur validation

Instead of blocking at submit, you can validate earlier:

  • Add client script onChange for MRVS fields.
  • Call GlideAjax async, show error message, and disable the submit button until corrected.

This improves UX because users see the error before clicking submit.

 

Script Include (your code is fine)

Just make sure it’s Client Callable:

var SLAValidationUtils = Class.create();

SLAValidationUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    checkDuplicate: function() {

        var name = this.getParameter('sysparam_name_val');

        var type = this.getParameter('sysparam_type_val');

        var target = this.getParameter('sysparam_target_val');

        var table = this.getParameter('sysparam_table_val');

 

        var gr = new GlideRecord('contract_sla');

        gr.addQuery('name', name);

        gr.addQuery('type', type);

        gr.addQuery('target', target);

        gr.addQuery('collection', table);

        gr.query();

 

        if (gr.next()) {

            return 'true';

        }

        return 'false';

    }

});

 

Best Practice:-

  • Use getXMLWait() only for submit blocking.
  • For better UX, validate earlier with async GlideAjax.
  • Avoid manual g_form.submit() — ServiceNow handles it.

 

If my response helped please mark it correct and close the thread so that it benefits future readers.

 

Best,

Anupam.