My ajax request is sent once, then twice, then 4 times and the doubling continues

I have tabs with the following and previous buttons at the bottom, when I first upload the page ajaxloads data to tab one, when I click the next form, which will fine, but if I click the previous one after clicking the next, another ajax to fill the first dive so same as I did when loading, but when I click next to submit the form, the ajax request is doubled and sent twice, then 4 times 8, etc., how can I stop this from happeing ... my jquery is on one from my pages, which is the same on all:

$(document).on("click",".previous", function() { $.ajax({ url: '<?php echo Config::get('URL'); ?>wizzard/personal_information', type: 'GET', success: function(data){ $('#tab2').html(''); $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab1').html(data); $('#tab1').addClass('active'); $('.tab_1').addClass('active'); } }); }); $(document).on("click",".next", function() { $('#update_contact_information').on("submit", function() { $.ajax({ url: $(this).attr('action'), type: $(this).attr('method'), dataType: 'json', data: $(this).serialize(), success: function(data){ if(!data.success){ $.notify(data.error,{ className:'error', clickToHide: true, autoHide: true, globalPosition: 'bottom right' }); $.ajax({ url: '<?php echo Config::get('URL'); ?>wizzard/employment_history', type: 'GET', success: function(data){ $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab2').html(''); $('#tab3').html(data); $('#tab3').addClass('active'); $('.tab_3').addClass('active'); } }); }else{ $.notify(data.success,{ className:'success', clickToHide: true, autoHide: true, globalPosition: 'bottom right' }); $.ajax({ url: '<?php echo Config::get('URL'); ?>wizzard/employment_history', type: 'GET', success: function(data){ $('#tab2').html(''); $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab3').html(data); $('#tab3').addClass('active'); $('.tab_3').addClass('active'); } }); } } }); return false; }); $('#update_contact_information').trigger('submit'); }); 

my tabs:

  <div class="panel-body"> <div id="rootwizard"> <div class="navbar"> <div class="navbar-inner"> <div class="container"> <ul class="nav nav-pills"> <li class="active tab_1"><a href="#tab1" data-toggle="tab"><?php echo System::translate("Personal information"); ?></a></li> <li class="tab_2"><a href="#tab2" data-toggle="tab"><?php echo System::translate("Contact information"); ?></a></li> <li class="tab_3"><a href="#tab3" data-toggle="tab"><?php echo System::translate("Employment history"); ?></a></li> <li class="tab_4"><a href="#tab4" data-toggle="tab"><?php echo System::translate("Qualification history"); ?></a></li> <li class="tab_5"><a href="#tab5" data-toggle="tab"><?php echo System::translate("Avatar"); ?></a></li> </ul> </div> </div> </div> <div class="tab-content"> <div class="tab-pane active" id="tab1"> </div> <div class="tab-pane" id="tab2"> </div> <div class="tab-pane" id="tab3"> </div> <div class="tab-pane" id="tab4"> </div> <div class="tab-pane" id="tab5"> </div> <ul class="pager wizard"> <li class="previous"><a href="javascript:;"><?php echo System::translate("Previous"); ?></a></li> <li class="next"><a href="javascript:;"><?php echo System::translate("Next"); ?></a></li> </ul> </div> </div> 

and initial call:

 <script> $(function(){ $.ajax({ url: '<?php echo Config::get('URL'); ?>wizzard/personal_information', type: 'GET', success: function(data){ $('#tab1').html(data); } }); }); </script> 
+5
source share
6 answers

In the two previous answers, people (correctly) suggest that you rebuild your code to avoid registering the event handler inside another event handler. However, since you do not accept these answers, I believe that this does not fully answer the question.

What you want to do is simply submit the contents of the form when you click the "Next" button. At the same time, this button is not part of the form, so just clicking it will not cause the "send" event. This way you fire the event manually.

Now, what is strange in your description is that your ajax requests double each time you click. Usually with each click you will have only one request added. See my fiddle here , which is a simplified version of your code.

 var form = $('form'); $(document).on('click', '.next', function(){ form.on('submit', function() {//with every click one more handler is registered. Click the "click" link several times to see alert('submit fired'); return false; }); form.trigger('submit') }) 

So the question is: where do you register the handler with $(document).on("click",".next", function() ? You need to make sure that this handler is registered only once. To do this, you can put an alert('registering handler') immediately before this line in your code for verification. The correct sequence for registering event handlers is displayed in this modified fiddle . Code:

 var form = $('form'); $(document).on('click', '.next', function(){ form.trigger('submit') }) form.on('submit', function() {//with every click one more handler is registered. Click the "click" link several times to see alert('submit fired'); return false; }); 

So, can you try what I suggested and tell me the result?

PS I'm not sure why you need to start submitting a form at all. For your ajax request, you serialize the form and cancel the original view (you return false ;). Thus, I would recommend not using the "send" event at all and just doing all the work in the "click" handler.

UPDATE (after additional information has been added in the comments below)

So, the second part of the problem is as follows. With each "next" click, you attach new event listeners, and you replace the html of your tabs with the following $('#tab2').html(data); , and data contains not only markup, but also js code that is executed upon insertion (btw, I did not know that it works like that, it's nice). I think what you expect is that after removing the markup (html), the corresponding event listeners will also be deleted. But actually it is not. What for? Since you are delegating your event to listening to document with code starting with:

 $(document).on("click",".next", function() 

Here $(document) is what you attach your listener to. Instead of going into details, I highly recommend that you check out this original jquery explanation of event delegation .

So how do you fix this? There are several different ways. Perhaps the simplest (minimal amount of code editing) is to remove the event listeners before you do .html(data) . Another way, also simple, is to record

 $('.next').on("click", function(), 

as you did in qualification_history.php. Thus, you attach events to the element itself, and not to the document. The only thing you want to make sure is that there is a corresponding DOM element before executing this code (so you can put your code after markup).

+3
source

You bind a new submit event to the form every time you click a button, so it doubles. Unlink inside the click handler

 $(document).on("click",".next", function() { $('#update_contact_information').trigger('submit'); }); $(document).on("submit", '#update_contact_information', function() { $.ajax({ url: $(this).attr('action'), type: $(this).attr('method'), dataType: 'json', data: $(this).serialize(), success: function(data){ if(!data.success){ $.notify(data.error,{ className:'error', clickToHide: true, autoHide: true, globalPosition: 'bottom right' }); $.ajax({ url: '<?php echo Config::get('URL'); ?>wizzard/employment_history', type: 'GET', success: function(data){ $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab2').html(''); $('#tab3').html(data); $('#tab3').addClass('active'); $('.tab_3').addClass('active'); } }); }else{ $.notify(data.success,{ className:'success', clickToHide: true, autoHide: true, globalPosition: 'bottom right' }); $.ajax({ url: '<?php echo Config::get('URL'); ?>wizzard/employment_history', type: 'GET', success: function(data){ $('#tab2').html(''); $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab3').html(data); $('#tab3').addClass('active'); $('.tab_3').addClass('active'); } }); } } }); return false; }); 
+8
source

Not knowing the full html of the page involved, there are some guesses. The code in the OP is not structured correctly and has other logical errors. The problem in a nutshell is that you have defined an event handler to add an event handler.

By $('#update_contact_information').on("submit", function(){...}) in the handler definition for $(document).on("click",".next", function(){...}) , you say:

Each time I click the a button with the next class, I want to create a new event handler for my element with the id update_contact_information . Therefore, the first time you click next you define and then run submit . The second time you click next , an existing handler for sending already exists, plus you add another.

Since you have not provided the rest of the HTML and JavaScript, it is not clear where your code exists. Other problems are possible.

I would restructure JavaScript by putting all the event handlers inside jQuery into a ready-made function for the page. This allows you to define event handlers once and still make the initial call to load the page.

Something like that:

 $(function() { $(document).on("click", ".previous", function() { $.ajax({ url: '<?php echo Config::get(' URL '); ?>wizzard/personal_information', type: 'GET', success: function(data) { $('#tab2').html(''); $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab1').html(data); $('#tab1').addClass('active'); $('.tab_1').addClass('active'); } }); }); $('#update_contact_information').on("submit", function() { $.ajax({ url: $(this).attr('action'), type: $(this).attr('method'), dataType: 'json', data: $(this).serialize(), success: function(data) { if (!data.success) { $.notify(data.error, { className: 'error', clickToHide: true, autoHide: true, globalPosition: 'bottom right' }); $.ajax({ url: '<?php echo Config::get(' URL '); ?>wizzard/employment_history', type: 'GET', success: function(data) { $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab2').html(''); $('#tab3').html(data); $('#tab3').addClass('active'); $('.tab_3').addClass('active'); } }); } else { $.notify(data.success, { className: 'success', clickToHide: true, autoHide: true, globalPosition: 'bottom right' }); $.ajax({ url: '<?php echo Config::get(' URL '); ?>wizzard/employment_history', type: 'GET', success: function(data) { $('#tab2').html(''); $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab3').html(data); $('#tab3').addClass('active'); $('.tab_3').addClass('active'); } }); } } }); return false; }); $(document).on("click", ".next", function() { $('#update_contact_information').trigger('submit'); }); $.ajax({ url: '<?php echo Config::get(' URL '); ?>wizzard/personal_information', type: 'GET', success: function(data) { $('#tab1').html(data); } }); }); 

Depending on the rest of your HTML and JavaScript code for your page, this may or may not work as it does for you. I provide a fiddle demonstrating something similar in action. This is not an exact duplicate of the original message because the logic of this example does not work. This should be a sufficient starting point for:

  • Solving the Existing Multiple Event Binding Problem
  • Providing you with a better place to fix logic problems in your original examples

Here is the fiddle

+2
source

This should help with the order and logic of your events.

 //bind only when the doc has rendered... $(document).ready(function() { //bind click to and element with class previous $(".previous").on("click", function() { //... previous code alert("test me ;-)"); } //bind click to and element with class next $(".next").on("click", function() { //... next code. alert("test me ;-)"); } } 
+1
source

I assume that the witch id element #update_contact_information does not exist at the beginning. You want to bind the event on .next pressed. Therefore, I suggest you use $.delegate to bind the event before displaying the elements. see .delegate() for more details.

eg.

 $(document).delegate('#update_contact_information','submit', function(){ $.ajax({ url: $(this).attr('action'), type: $(this).attr('method'), dataType: 'json', data: $(this).serialize(), success: function(data){ if(!data.success){ $.notify(data.error,{ className:'error', clickToHide: true, autoHide: true, globalPosition: 'bottom right' }); $.ajax({ url: '<?php echo Config::get('URL'); ?>wizzard/employment_history', type: 'GET', success: function(data){ $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab2').html(''); $('#tab3').html(data); $('#tab3').addClass('active'); $('.tab_3').addClass('active'); } }); }else{ $.notify(data.success,{ className:'success', clickToHide: true, autoHide: true, globalPosition: 'bottom right' }); $.ajax({ url: '<?php echo Config::get('URL'); ?>wizzard/employment_history', type: 'GET', success: function(data){ $('#tab2').html(''); $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab3').html(data); $('#tab3').addClass('active'); $('.tab_3').addClass('active'); } }); } } }); return false; }); 
0
source

According to my comment

 $(document).on("click",".previous", function(){ $.ajax({ url: '<?php echo Config::get('URL'); ?>wizzard/personal_information', type: 'GET', success: function(data){ $('#tab2').html(''); $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab1').html(data); $('#tab1').addClass('active'); $('.tab_1').addClass('active'); } }); }); $(document).on("click",".next", function(){ /* Submit binding code from here moved just after this block. */ $('#update_contact_information').trigger('submit'); }); /* submit binding code from above block */ $('#update_contact_information').on("submit", function(){ $.ajax({ url: $(this).attr('action'), type: $(this).attr('method'), dataType: 'json', data: $(this).serialize(), success: function(data){ if(!data.success){ $.notify(data.error,{ className:'error', clickToHide: true, autoHide: true, globalPosition: 'bottom right' }); $.ajax({ url: '<?php echo Config::get('URL'); ?>wizzard/employment_history', type: 'GET', success: function(data){ $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab2').html(''); $('#tab3').html(data); $('#tab3').addClass('active'); $('.tab_3').addClass('active'); } }); }else{ $.notify(data.success,{ className:'success', clickToHide: true, autoHide: true, globalPosition: 'bottom right' }); $.ajax({ url: '<?php echo Config::get('URL'); ?>wizzard/employment_history', type: 'GET', success: function(data){ $('#tab2').html(''); $('#tab2').removeClass('active'); $('.tab_2').removeClass('active'); $('#tab3').html(data); $('#tab3').addClass('active'); $('.tab_3').addClass('active'); } }); } } }); return false; }); 
0
source

Source: https://habr.com/ru/post/1244240/


All Articles