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'
});

 

13 REPLIES 13

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.

 

suuriyas
Tera Contributor

HI @Anupam1 ,

 

Thanks for replying 

initially i tried will XMLWait but it did not work so shifted like this and i also implemented your script and checked still it is not working 

getting annotation like this in client script page

New client-scripts are run in strict mode, with direct DOM access disabled. Access to jQuery, prototype and the window object are likewise disabled. To disable this on a per-script basis, configure this form and add the "Isolate script" field. To disable this feature for all new globally-scoped client-side scripts set the system property "glide.script.block.client.globals" to false.

 

also tried onchange clint script still it did not work same annotation

 

function onChange(control,oldValue, newValue){
//  if(newValue == oldValue){
//      return;
//  }
//  var fieldName = g_form.getFieldName(control);
//  if (fieldName == 'name'){
//      g_form.setValue('type', '');
//      g_form.setValue('target', '');
//      g_form.setValue('collection','');
//  }
// if (fieldName == 'type'){
//      g_form.setValue('target', '');
//      g_form.setValue('collection','');
//  }
// if (fieldName == 'target'){
//      g_form.setValue('collection','');
//  }


   var name = g_form.getValue('name');
   var type = g_form.getValue('type');
   var target = g_form.getValue('target');
   var table = g_form.getValue('collection');
   if(!name || !type || !target || !table){
    return;
   }
   var ga = new GlideAjax('SLAValidationUtils');
   ga.addParam('sysparm_name','checkDuplicate');
   ga.addParam('sysparm_name_val',name);
   ga.addParam('sysparm_type_val',type);
   ga.addParam('sysparm_target_val',target);
   ga.addParam('sysparm_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");

//    var response = ga.getXMLWait();
//    var result = response.documentElement.getAttribute("answer");
//    if (result == 'true'){
//  g_form.addErrorMessage("SLA with same name, type, target and table already exists");
//  return false;
   }

   });
}
 
One more thing i observe is that it seems script include is not running or not sure i have added the log there but i don't see them in log table

 

Deepak Shaerma
Mega Sage
Mega Sage

Hi @suuriyas 

As i see mainly there is typo mistakes in your code, 
Wrong: ga.addParam('sysparam_name', ...)
Right: ga.addParam('sysparm_name', ...) (Note the missing 'a' in parm).
Also your current code only checks rows[0] (the first row). If a user adds three rows to the MRVS, and the third one is a duplicate, your current script will miss it. It is better to pass the entire JSON to the Script Include and let the server loop through all rows.
catalog client script onsubmit

function onSubmit() {
    // 1. Check if we have already validated and are re-submitting
    if (g_form.submitted) {
        return true;
    }

    // 2. Get the MRVS data
    var mrvsData = g_form.getValue('sla_configuration');
    
    // If empty, let it submit
    if (!mrvsData || mrvsData == '[]') {
        return true;
    }

    // 3. Call GlideAjax
    var ga = new GlideAjax('SLAValidationUtils');
    // FIX: Changed sysparam to sysparm
    ga.addParam('sysparm_name', 'checkDuplicate'); 
    // Optimization: Pass the whole JSON string to server
    ga.addParam('sysparm_mrvs_data', mrvsData); 

    ga.getXMLAnswer(function(answer) {
        // If we get a message back, it means a duplicate was found
        if (answer) {
            g_form.addErrorMessage(answer);
            // We do NOT call submit here, effectively stopping the process
        } else {
            // No duplicates found, proceed with submission
            g_form.submitted = true;
            g_form.submit();
        }
    });

    // 4. Always return false initially to pause for the Ajax check
    return false;
}


Script includee:

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

    checkDuplicate: function() {
        // Get the JSON string
        var mrvsString = this.getParameter('sysparm_mrvs_data');
        var rows = [];
        
        try {
            rows = JSON.parse(mrvsString);
        } catch (e) {
            return "Error parsing row data";
        }

        // Iterate through ALL rows in the MRVS
        for (var i = 0; i < rows.length; i++) {
            var name = rows[i].name;
            var type = rows[i].type;
            var target = rows[i].target;
            var table = rows[i].collection; // Ensure variable name is 'collection' in MRVS

            var gr = new GlideRecord('contract_sla');
            gr.addQuery('name', name);
            gr.addQuery('type', type);
            gr.addQuery('target', target);
            gr.addQuery('collection', table);
            gr.setLimit(1); // Performance optimization
            gr.query();

            if (gr.hasNext()) {
                // Return an error message identifying which row failed
                return "Row " + (i + 1) + ": SLA with name '" + name + "' already exists.";
            }
        }

        // Return empty string if no duplicates found
        return "";
    },

    type: 'SLAValidationUtils'
});

Happy to help! If this resolved your issue, kindly mark it as the correct answer and Helpful and close the thread so others can benefit too.

Warm Regards,

Deepak Sharma

Community Rising Star 2025