Ivan
Ivan

Reputation: 2481

Change event fired more than once when working with AJAX

I have some doctors in a <select id="doctors"> field.
On change, an AJAX request is triggered, pulling locations related to selected user.
These retrieved locations then populate a <select id="locations"> field.
Again, on change on this second <select> triggers an AJAX request to 'single-location.php' page to retrieve… well, single location's data.

In short, it's a version of the classic parent-children dropdown lists.

The problem is that changing the <select id="locations"> field triggers N AJAX requests, where N is the number of changes in the <select id="doctors"> field.

I.e., if I changed <select id="doctors"> field 3 times, when changing <select id="locations"> I have 3 AJAX requests to 'single-location.php'.

10 changes on doctors' field? Be sure that a change on locations field will trigger 10 AJAX requests to 'single-location.php'.

I made a fiddle example close to my real example, but the fiddle works as expected: when changing doctors field a couple of times and then changing locations field, the console shows that there is one request only, that is what I'd expect

My real example is just like the fiddle one, except that on doctors' <select> I have select2 plugin, and the AJAX request are real, of course.

Digging deeper, seems that the problem lies in the function:

$('#locations').on('change', function(){
    getLocationData();
});

Or, better, in the change event, that is fired more than once, and has nothing to do with the AJAX request itself. Indeed, if I change with:

$('#locations').on('change', function(){
    console.log('changed…');
});

The message is logged N times.

A workaround that I found is to add .off() method like this:

$('#locations').off().on('change', function(){
    getLocationData();
});

But the question is: why does it work like this? Why the change event is triggered N times depending on the changes on another field that shouldn't be directly related?

Thanks

Upvotes: 1

Views: 152

Answers (1)

Apps-n-Add-Ons
Apps-n-Add-Ons

Reputation: 2146

The code is doing just what you are telling it to do (funny thing about code - seems all the 'mystery' things that happen are related to coding mistakes... :)

These retrieved locations then populate a field.

This is triggering the 'on change' code - when you 'populate', that is a CHANGE....

Your workaround looks to be a good way to do what you want.

Another would be to only add the 'on change' when the ajax is complete. Something like......

$.post('link', function(){
    //populate the 'locations' select and add the .change
    $("#locations").add(NOTE: however you are populating it - you should show the code....)
        .change(function(){
        getLocationData();}
});

This is just quick example code (ie, it won't work....) as you didn't show enough for me to give you 'working' stuff, but it should give you some ideas on how to approach this - and where the 'problem' is.

Upvotes: 1

Related Questions