Some PDIs are currently unavailable, and PDI actions are paused. View the latest updates here. Read More

Onsubmit script not works

sivananda80
Tera Expert

Hi team

I have used client and script include.Client is in " Asset Management Common". script include in Global scope
and client callable and applies on all scope

based on some condition i don't want smbit the form and alert msg or error msg. i tired many ways not works. getting getting java console error while submitting . can you please help me on that

script inculde

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

    validateAssetTerritories: function() {

        var assetIds = this.getParameter('sysparm_asset_ids');
        if (!assetIds)
            return JSON.stringify({
                success: true
            });

        var assetArr = assetIds.split(',');
        var companyMap = {};

        var assetGR = new GlideRecord('alm_asset');
        assetGR.addQuery('sys_id', 'IN', assetArr);
        assetGR.query();

        while (assetGR.next()) {

            var company = assetGR.getValue('company');

            if (!company)
                continue;

            if (!companyMap[company])
                companyMap[company] = [];

            companyMap[company].push(assetGR.getDisplayValue());
        }

        var invalidAssets = [];

        for (var companyId in companyMap) {

            var procGR = new GlideRecord('sn_hamp_territory_procurement');
            procGR.addQuery('u_company', companyId);
            procGR.query();

            var optIn = false;

            if (procGR.next()) {
                optIn = procGR.getValue('u_opt_in') == '1' ||
                         procGR.getValue('u_opt_in') == 'true';
            }

            if (!optIn) {
                invalidAssets = invalidAssets.concat(companyMap[companyId]);
            }
        }

        if (invalidAssets.length > 0) {
            return JSON.stringify({
                success: false,
                message: 'Territory is not Opt-In for asset(s): ' +
                         invalidAssets.join(', ')
            });
        }

        return JSON.stringify({
            success: true
        });
    },

    type: 'AssetTerritoryUtils'
});


// var AssetTerritoryUtils = Class.create();

// AssetTerritoryUtils.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {

//     validateAssetTerritories: function() {
//         return JSON.stringify({
//             success: true
//         });
//     },

//     type: 'AssetTerritoryUtils'
// });



// var AssetTerritoryUtils = Class.create();

// AssetTerritoryUtils.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
 
//     validateAssetTerritories: function() {
 
//         var assetIds = this.getParameter('sysparm_asset_ids');
 
//         if (!assetIds) {

//             return JSON.stringify({ success: true });

//         }
 
//         var assetArr = assetIds.split(',');

//         var companyMap = {};

//         var noCompanyAssets = [];
 
//         var assetGR = new GlideRecord('alm_asset');

//         assetGR.addQuery('sys_id', 'IN', assetArr);

//         assetGR.query();
 
//         while (assetGR.next()) {
 
//             var company = assetGR.getValue('company');

//             var displayName = assetGR.getDisplayValue();
 
//             // FIX: don't silently skip assets with no company —

//             // flag them as invalid instead of letting them pass unvalidated

//             if (!company) {

//                 noCompanyAssets.push(displayName);

//                 continue;

//             }
 
//             if (!companyMap[company]) {

//                 companyMap[company] = [];

//             }

//             companyMap[company].push(displayName);

//         }
 
//         var invalidAssets = [];
 
//         for (var companyId in companyMap) {
 
//             var procGR = new GlideRecord('sn_hamp_territory_procurement');

//             procGR.addQuery('u_company', companyId);

//             procGR.query();
 
//             // FIX: check ALL procurement records for this company, not just the first.

//             // Company is opt-in only if AT LEAST ONE matching record is opt-in true.

//             // (Flip this logic to "ALL must be true" instead if that's the actual business rule.)

//             var optIn = false;
 
//             while (procGR.next()) {

//                 var val = procGR.getValue('u_opt_in');

//                 if (val == '1' || val == 'true') {

//                     optIn = true;

//                     break;

//                 }

//             }
 
//             if (!optIn) {

//                 invalidAssets = invalidAssets.concat(companyMap[companyId]);

//             }

//         }
 
//         // FIX: assets with no company are always treated as invalid/unvalidated

//         if (noCompanyAssets.length > 0) {

//             invalidAssets = invalidAssets.concat(noCompanyAssets);

//         }
 
//         if (invalidAssets.length > 0) {

//             return JSON.stringify({

//                 success: false,

//                 message: 'Territory is not Opt-In for asset(s): ' +

//                     invalidAssets.join(', ')

//             });

//         }
 
//         return JSON.stringify({ success: true });

//     },
 
//     type: 'AssetTerritoryUtils'

// });
 
client script
var validated = false;

function onSubmit() {

    if (validated) {
        return true;
    }

    var ga = new GlideAjax('global.AssetTerritoryUtils');

    ga.addParam('sysparm_name', 'validateAssetTerritories');
    ga.addParam('sysparm_asset_ids', g_form.getValue('assets'));

    ga.getXMLAnswer(function(answer) {

        var result = JSON.parse(answer);

        if (result.success === true) {

            validated = true;

            // Trigger submit again
            $('.btn-primary:contains("Submit")').click();

        } else {

            g_form.addErrorMessage(
                result.message || 'Territory is not Opt-In'
            );
        }
    });

    return false;
}









4 REPLIES 4

Tanushree Maiti
Tera Patron

Hi @sivananda80 

 

Share the error message or error screen shot.

 

 

Please Accept the solution if it assisted you with your question & Mark this response as Helpful.
Regards
Tanushree Maiti
ServiceNow Technical Architect
LinkedIn: https://www.linkedin.com/in/tanushreemaiti

Sandeep Rajput
Tera Patron

@sivananda80 Please refer to this article https://www.servicenow.com/community/developer-blog/how-to-async-glideajax-in-an-onsubmit-script/ba-... to know the steps to call GlideAjax in an onSubmit client script.

 

Also,  the following piece of code might be causing an issue in your client script.

 // Trigger submit again
            $('.btn-primary:contains("Submit")').click();

 

In order to submit the form automatically I recommend using g_form.submit('action name'); Please refer to the article shared above for the more information.

GlideEdward
Tera Contributor

I am concerned about this line in your client script:

 


@sivananda80 wrote:

client script
var validated = false;

function onSubmit() {
  
if (validated) {
        return true;
    }
...
It is outside of the onSubmit function and also not part of any other function that gets called from onSubmit.
 
Therefore, I don't think that line ever gets executed.
 
Which means that your console error is likely to be "validated is undefined" when it hits the if condition shown.

NityaB161013953
Mega Patron

Hi @sivananda80 

The issue is that onSubmit() is asynchronous, but ServiceNow expects it to return true or false immediately. By the time your GlideAjax.getXMLAnswer() callback executes, the original submit has already been cancelled. Triggering $('.btn-primary').click() from inside the callback often causes JavaScript errors or recursive submits, especially in Workspace or newer UI.

Solution (Recommended)

  • Keep return false; in onSubmit().

  • In the callback, instead of clicking the button, resubmit the form using ServiceNow APIs:

    validated = true;
    g_form.submit(); // or gsftSubmit(null, g_form.getFormElement(), g_form.getActionName()) in classic UI
  • If validation fails:

    g_form.addErrorMessage(result.message);
    return;

If g_form.submit() still doesn't work

It usually means the form is in Workspace, where asynchronous validation in onSubmit is not supported reliably.

In that case, the best approach is to:

  • Perform the GlideAjax validation before the user submits (e.g., onChange or when the Submit UI Action is clicked), or

  • Move the validation to a Before Business Rule/Script Include invoked server-side, abort the action with:

    current.setAbortAction(true);
    gs.addErrorMessage('Territory is not Opt-In...');

    This is the most reliable approach because it cannot be bypassed.

In short: Don't use $('.btn-primary').click() to resubmit. Use g_form.submit()/gsftSubmit() if you're in Classic UI, or move the validation server-side if you're in Workspace.