OnChange client script going in loop

Hafsa1
Mega Sage

I have onChange client script to call 2 fields using script include based on field "Region".

If I select "Region", then location1 and location2 populates correctly and then I save the form.

But if I select "Region", then both location value populate correctly but I didn't save the form, and then select different "Region" again. value of region,location1 and location2 keeps changes/shuffle between selected values. It's going in loop. below is my script

...................................

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading || newValue === '' || newValue == oldValue) {
        return;
    }
    //Type appropriate comment here, and begin script below

    var Region = g_form.getDisplayValue('u_region');

    var gr = new GlideAjax('RegionHubUtils');
    gr .addParam('sysparm_name', 'getArea1Hub');
    gr .addParam('sysparm_location1', Region);
    gr .getXMLAnswer(function(answer) {
        g_form.setValue('u_location_1', answer);
    });
    var gr1 = new GlideAjax('RegionHubUtils');
    gr1 .addParam('sysparm_name', 'getArea2Hub');
    gr1 .addParam('sysparm_location2', Region);
    gr1 .getXMLAnswer(function(answer1) {
        g_form.setValue('u_location_2', answer1);
    });
...............................................
1 ACCEPTED SOLUTION

vaishali231
Kilo Sage

Hey @Hafsa1 

Your issue is happening because multiple asynchronous GlideAjax calls are returning out of order. 

Use ONE GlideAjax call and return both values together.

Client Script:

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
   if (isLoading || !newValue || newValue == oldValue) {
       return;
   }
   // Clear existing values immediately
   g_form.clearValue('u_location_1');
   g_form.clearValue('u_location_2');
   // Store current selected region
   var selectedRegion = newValue;
   var ga = new GlideAjax('RegionHubUtils');
   ga.addParam('sysparm_name', 'getLocations');
   ga.addParam('sysparm_region', selectedRegion);
   ga.getXMLAnswer(function(response) {
       // Prevent old async response from overwriting latest selection
       if (g_form.getValue('u_region') != selectedRegion) {
           return;
       }
       if (response) {
           var data = JSON.parse(response);
           g_form.setValue('u_location_1', data.location1 || '');
           g_form.setValue('u_location_2', data.location2 || '');
       }
   });
}

Script Include:

var RegionHubUtils = Class.create();
RegionHubUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
   getLocations: function() {
       var region = this.getParameter('sysparm_region');
       var result = {
           location1: '',
           location2: ''
       };
       var gr = new GlideRecord('sn_customerservice_location_hub');
       gr.addQuery('u_region', region);
       gr.query();
       if (gr.next()) {
           result.location1 = gr.getValue('u_location1');
           result.location2 = gr.getValue('u_location2');
       }
       return JSON.stringify(result);
   },
   type: 'RegionHubUtils'

});

****************************************************************************

If this response helps, please mark it as Accept as Solution and Helpful.

Doing so helps others in the community and encourages me to keep contributing.

Regards

Vaishali Singh

Servicenow Developer
Linkedin - https://www.linkedin.com/in/vaishali-singh-2273361bb












View solution in original post

9 REPLIES 9

Tanushree Maiti
Tera Patron

Hi @Hafsa1 

 

Can you share your script include. is the location 1 and location 2 getting fetched from 2 different table?

Why are you calling glideajax twice? Can it not be done by one call?

 

 

 

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

Nilesh Pol
Kilo Sage

@Hafsa1 The "looping" behavior you're seeing happens because GlideAjax is asynchronous.

Instead of two separate calls, modify your Script Include to return a single JSON object containing both values. This ensures both fields update simultaneously and reduces server load.
Modified Client Script:

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
// Clear fields if Region is wiped
if (newValue === '') {
g_form.clearValue('u_location_1');
g_form.clearValue('u_location_2');
}
return;
}

// 1. Clear values immediately to prevent "shuffling" feedback
g_form.clearValue('u_location_1');
g_form.clearValue('u_location_2');

var region = newValue;

var gr = new GlideAjax('RegionHubUtils');
gr.addParam('sysparm_name', 'getArea1Hub');
gr.addParam('sysparm_location1', region);
gr.getXMLAnswer(function(answer) {
// Only set if the region hasn't changed again while waiting
if(g_form.getValue('u_region') == region) {
g_form.setValue('u_location_1', answer);
}
});

var gr1 = new GlideAjax('RegionHubUtils');
gr1.addParam('sysparm_name', 'getArea2Hub');
gr1.addParam('sysparm_location2', region);
gr1.getXMLAnswer(function(answer1) {
if(g_form.getValue('u_region') == region) {
g_form.setValue('u_location_2', answer1);
}
});
}

 

Hafsa1
Mega Sage

@Nilesh Pol @Tanushree Maiti  script include

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

    getDeliveryHub: function() {
        var AreaID = this.getParameter('sysparm_location1');
        var gr = new GlideRecord('sn_customerservice_location_hub');
        gr.addQuery("u_region", AreaID);
        gr.query();
        if (gr.next()) {
            return gr.getValue('u_location1');
        }
        return '';
    },
    getDeliveryPillar: function() {
        var AreaID = this.getParameter('sysparm_location2');
        var gr = new GlideRecord('sn_customerservice_location_hub');
        gr.addQuery("u_region_new", AreaID);
        gr.query();
       if (gr.next()) {
            return gr.getValue('u_location2');
        }
        return '';
    },

    type: 'RegionHubUtils'
});

Hi @Hafsa1 

 

Add this onChangeClient script in your  sn_customerservice_location_hub table.

 

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
g_form.setValue('location1', '');  //update your field name
g_form.setValue('location2', '');
return;
}

g_form.getReference('u_region', callBackMethod);

function callBackMethod(regionRecord) {
if (regionRecord) {
g_form.setValue('location1', regionRecord.u_location1);
g_form.setValue('location2', regionRecord.u_location2);
}
}
}

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