Based condition should not onSubmit the form else onSubmit

Siva82
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 @Siva82 ,

 

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

VaishnaviK43271
Tera Contributor

Hi @Siva82 !!

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

Siva82
Tera Expert

@Mohammed8 @Sarthak Kashyap 

Can you please help me on it

 

Siva82
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