Get a first look at what's coming. The Developer Passport Australia Release Preview kicks off March 12. Dive in! 

Based condition should not onSubmit the form else onSubmit

sivananda80
Tera Expert

Hi Team,

I have a catalog item with an onSubmit client script that enforces some conditions. Currently:

  • The script enters the if block and shows the error message as expected.

  • However, when the conditions are not matched, the form does not submit as intended.

I have written the following script, but it’s not working properly. Could you please review and help fix it?

Thank you in advance for your support!

var allowSubmit = false; // declare globally

function onSubmit() {
    if (allowSubmit) {
        return true; // already validated, let submit continue
    }

    var locationSysId = g_form.getValue('current_work_location');
    var accessory = (g_form.getDisplayValue('choose_accessory') || '').toLowerCase();
    var hasYubikey = accessory.includes('yubikey');
    alert(hasYubikey);

    var ga = new GlideAjax('LocationSubmitValidator');
    ga.addParam('sysparm_name', 'getLocationData');
    ga.addParam('sysparm_location_id', locationSysId);

    ga.getXMLAnswer(function(answer) {
        var data;
        try {
            data = answer ? JSON.parse(answer) : null;
        } catch (e) {
            data = null;
        }

        // If no data, allow
        if (!data) {
            allowSubmit = true;
            g_form.submit();
            return;
        }

        // Block condition
        if (
            data.name && data.name.toLowerCase().includes('remote') &&
            (data.onsiteSupport == 0 || data.onsiteSupport === '0') &&
            (data.hardwareSelfService == 0 || data.hardwareSelfService === '0') &&
            !hasYubikey
        ) {
            g_form.addErrorMessage(
                'For Remote locations without onsite or hardware self-service support, a Yubikey request is mandatory.'
            );
            // do NOT call g_form.submit here
            return;
        }

        // Allow submit
        allowSubmit = true; // set before resubmitting
        g_form.submit();
    });

    return false; // always block original submit until callback finishes
}




Thank you
Siva
 
1 ACCEPTED SOLUTION

Mohammed8
Tera Sage

Hi @sivananda80 ,

 

I tried to replicate the your use case in PDI (async + onsubmit catalog script)

 

1) Created a simple client Ajax script as shown below:

 

Mohammed8_0-1766441993516.png

 

2) Used your similar script but unfortunately it never submitted as you pointed out in your script too

 

var allowSubmit = false;

function onSubmit() {

// SECOND submit → allow
if (allowSubmit) {
return true;
}

var ga = new GlideAjax('IncidentAssignmentCheck');
ga.addParam('sysparm_name', 'getIncidentCount');
ga.addParam('sysparm_user', g_user.userID);

ga.getXML(function(response) {

var answer = response.responseXML.documentElement.getAttribute('answer');
var count = parseInt(answer, 10) || 0;

if (count > 5) {
alert(
'You have ' + count +
' active incident(s) already created. Please wait before creating another one.'
);
return; // stop, do NOT submit
}

// allow submit
allowSubmit = true;
g_form.submit(g_form.getActionName());
});

// FIRST submit → always stop
return false;
}

 

3)  After reading articles, I modified the my above script  to use g_scratchpad and call g_form.submit(g_form.getActionName())

 

function onSubmit() {

if (g_scratchpad.allowSubmit) {
return true;
}

var ga = new GlideAjax('IncidentAssignmentCheck');
ga.addParam('sysparm_name', 'getIncidentCount');
ga.addParam('sysparm_user', g_user.userID);

ga.getXML(function(response) {

var answer = response.responseXML.documentElement.getAttribute('answer');
var count = parseInt(answer, 10) || 0;

if (count > 5) {
alert(
'You have ' + count +
' active incident(s) already created. Please wait before creating another one.'
);
return; // STOP here
}
alert('You have ' + count + 'only active accident , your request will  be submitted');
g_scratchpad.allowSubmit = true;
g_form.submit(g_form.getActionName());
});

return false;
}

 

4) Result verification: for if block condition

 

Mohammed8_1-1766442470907.png

 

5) Result verification: outside if condition and it submits

 

Mohammed8_2-1766442691018.png Mohammed8_3-1766442723533.png

 

Here is the Thread I referred :

https://www.servicenow.com/community/developer-blog/how-to-async-glideajax-in-an-onsubmit-script/ba-...

 

I modified your code you posted, you can try this or make changes as per your use-case 

 

function onSubmit() {

// allow second submit
if (g_scratchpad.allowSubmit) {
return true;
}

var locationSysId = g_form.getValue('current_work_location');
var accessory = (g_form.getDisplayValue('choose_accessory') || '').toLowerCase();
var hasYubikey = accessory.includes('yubikey');
alert(hasYubikey);

var ga = new GlideAjax('LocationSubmitValidator');
ga.addParam('sysparm_name', 'getLocationData');
ga.addParam('sysparm_location_id', locationSysId);

ga.getXMLAnswer(function(answer) {

var data;
try {
data = answer ? JSON.parse(answer) : null;
} catch (e) {
data = null;
}

// If no data, allow
if (!data) {
g_scratchpad.allowSubmit = true;
g_form.submit(g_form.getActionName());
return;
}

// Block condition
if (
data.name && data.name.toLowerCase().includes('remote') &&
(data.onsiteSupport == 0 || data.onsiteSupport === '0') &&
(data.hardwareSelfService == 0 || data.hardwareSelfService === '0') &&
!hasYubikey
) {
g_form.addErrorMessage(
'For Remote locations without onsite or hardware self-service support, a Yubikey request is mandatory.'
);
return;
}

// Allow submit
g_scratchpad.allowSubmit = true;
g_form.submit(g_form.getActionName());
});

return false; // always block original submit until callback finishes
}

 

If you find this answer useful, please mark it as helpful and solution accepted.

 

Thanks and Regards,

Mohammed Zakir

View solution in original post

7 REPLIES 7

VaishnaviK3009
Tera Guru

Hi @sivananda80 !!

This issue happens because onSubmit runs synchronously, but GlideAjax is asynchronous.
So the form returns false before the server response arrives.

Fix:

  • Always return false initially

  • Validate in the GlideAjax callback

  • If valid, set a global flag and re-submit the form

  • Allow submission on the second run using the flag

var allowSubmit = false;

function onSubmit() {

    // Allow submit after async validation
    if (allowSubmit) {
        return true;
    }

    var locationSysId = g_form.getValue('current_work_location');
    var accessory = (g_form.getDisplayValue('choose_accessory') || '').toLowerCase();
    var hasYubikey = accessory.indexOf('yubikey') > -1;

    var ga = new GlideAjax('LocationSubmitValidator');
    ga.addParam('sysparm_name', 'getLocationData');
    ga.addParam('sysparm_location_id', locationSysId);

    ga.getXMLAnswer(function(answer) {
        var data = answer ? JSON.parse(answer) : null;

        // Allow submit if no data
        if (!data) {
            allowSubmit = true;
            g_form.submit();
            return;
        }

        // Block condition
        if (
            data.name.toLowerCase().indexOf('remote') > -1 &&
            data.onsiteSupport == 0 &&
            data.hardwareSelfService == 0 &&
            !hasYubikey
        ) {
            g_form.addErrorMessage(
                'For Remote locations without onsite or hardware self-service support, a Yubikey request is mandatory.'
            );
            return;
        }

        // Allow submit
        allowSubmit = true;
        g_form.submit();
    });

    // Stop initial submit
    return false;
}

Mark it helpful if this helps you to understand. Accept solution if this give you the answer you're looking for.

Thank You

sivananda80
Tera Expert

@Mohammed8 @Sarthak Kashyap 

Can you please help me on it

 

sivananda80
Tera Expert

I Have updated script but still not works

// Global flag to prevent recursive submits
var allowSubmit = false;

function onSubmit() {
    // Already validated? Let the submit continue
    if (allowSubmit) return true;

    // Get form values
    var locationSysId = g_form.getValue('current_work_location');
    var accessory = (g_form.getDisplayValue('choose_accessory') || '').toLowerCase();
    var hasYubikey = accessory.includes('yubikey');

    // GlideAjax async call
    var ga = new GlideAjax('LocationSubmitValidator');
    ga.addParam('sysparm_name', 'getLocationData');
    ga.addParam('sysparm_location_id', locationSysId);

    ga.getXMLAnswer(function(answer) {
        var data = null;
        try {
            data = answer ? JSON.parse(answer) : null;
        } catch (e) {
            data = null;
        }

        // Check blocking condition
        if (
            data &&
            data.name &&
            data.name.toLowerCase().includes('remote') &&
            (data.onsiteSupport == 0 || data.onsiteSupport === '0') &&
            (data.hardwareSelfService == 0 || data.hardwareSelfService === '0') &&
            !hasYubikey
        ) {
            g_form.addErrorMessage(
                'For Remote locations without onsite or hardware self-service support, a Yubikey request is mandatory.'
            );
            return; // DO NOT submit
        }

        // Allow submit safely
        allowSubmit = true;

        // Use setTimeout to avoid recursive onSubmit problems in catalog forms
        setTimeout(function() {
            g_form.submit();
        }, 50); // 50ms delay is usually enough
    });

    // Stop original submit until async validation completes
    return false;
}

Hi @Mohammed8 
Thank you for response
I tried above script not works