jQuery AJAX form submits twice
Asked Answered
E

10

54

I've got a form that I'm capturing via jQuery and sending via AJAX. My problem is that the form submits more than once every time I refresh the page.

I've tried to unbind the submit button but then the form is posted normally after the first submit. Any help would be appreciated

$('#exportForm').submit(function() {
  $.ajax({
    type: "POST",
    url: $(this).attr('action'),
    data: $(this).serialize(),
    success: function(response) {
      $('#exportForm').unbind('submit');
      console.log(response);
    }
  });
  return false;
});
Engelhart answered 25/11, 2013 at 14:24 Comment(2)
I think you need provide more codeAdversary
Hey cosset, That's pretty much all there is other than a very basic form. What else would you need?Engelhart
S
36

It's most likely that you're using a button or submit to trigger the ajax event. Try this:

$('#exportForm').submit(function(e){
        e.preventDefault();
        $.ajax({
            type: "POST",
            url: $(this).attr( 'action' ),
            data: $(this).serialize(),
            success: function( response ) {
                console.log( response );
            }
        });

        return false;
    });
Sadducee answered 25/11, 2013 at 14:29 Comment(5)
Thanks, I removed the '$('#exportForm').unbind('submit');' and added the 'e.preventDefault();' and it seems to have worked. I'll accept when I can.Engelhart
Interesting - you're saying that the return false wouldn't work to prevent the default form submit action? jsfiddle.net/rR8XzCeolaceorl
Sorry, after more testing found out it dose not work.Engelhart
What doesn't work? It's still submitting twice? You do realize that all this AJAX routine is doing is a pretty standard submit via POST, correct? If #exportForm is a button, I suggest you change the .submit to .click.Sadducee
This didn't work for me either, I had to add e.stopImmediatePropagation(); as Chris Sercombe suggests below.Clemmer
P
130

As well as calling preventDefault, also call stopImmediatePropagation on the event.

$('#exportForm').submit(function(e){
    e.preventDefault();
    e.stopImmediatePropagation();
    $.ajax({
        type: "POST",
        url: $(this).attr( 'action' ),
        data: $(this).serialize(),
        success: function( response ) {
            console.log( response );
        }
    });

    return false;
});
Pyroligneous answered 8/10, 2014 at 16:36 Comment(4)
While your answer may solve the question, it is always better if you can provide a description on how your answer solves it. In this case, why preventDefault is not enough. This is a suggestion for further improving this and future answers.Alverson
Adding e.stopImmediatePropagation(); worked for me, thanks Chris! I've been scratching my head over this for about 2 hours this evening. Whereas e.preventDefault() on its own has worked for me in the past, I suspect it is because it's fine for simple links or buttons but when working in a form's submission event, you must use e.stopImmediatePropagation() to prevent the event from bubbling up thorugh the dom. See api.jquery.com/event.stopImmediatePropagation.Clemmer
You are correct but this is also not working for me, what could be the possible reasonManysided
return false; is enough for prevent default behavior and event bubbling.Mauricio
S
36

It's most likely that you're using a button or submit to trigger the ajax event. Try this:

$('#exportForm').submit(function(e){
        e.preventDefault();
        $.ajax({
            type: "POST",
            url: $(this).attr( 'action' ),
            data: $(this).serialize(),
            success: function( response ) {
                console.log( response );
            }
        });

        return false;
    });
Sadducee answered 25/11, 2013 at 14:29 Comment(5)
Thanks, I removed the '$('#exportForm').unbind('submit');' and added the 'e.preventDefault();' and it seems to have worked. I'll accept when I can.Engelhart
Interesting - you're saying that the return false wouldn't work to prevent the default form submit action? jsfiddle.net/rR8XzCeolaceorl
Sorry, after more testing found out it dose not work.Engelhart
What doesn't work? It's still submitting twice? You do realize that all this AJAX routine is doing is a pretty standard submit via POST, correct? If #exportForm is a button, I suggest you change the .submit to .click.Sadducee
This didn't work for me either, I had to add e.stopImmediatePropagation(); as Chris Sercombe suggests below.Clemmer
F
11

In case you are using some kind of validation (e.g jQuery Validation), the form is submitted twice because aside from $('#exportForm').submit you write yourself, the validation plugin will also submit the form after it successfully validates all field.

NB : If you are using jQuery Validation, avoid using .submit(). Instead, use submitHandler.

Fifield answered 3/5, 2015 at 2:17 Comment(0)
B
7

You can simply use e.stopImmediatePropagation(); :

For example :

$('#exportForm').submit(function(e){
    e.stopImmediatePropagation();
Bimetallism answered 19/3, 2018 at 12:37 Comment(0)
U
2

As Chris Sercombe pointed out, e.stopImmediatePropagation() does work and it definitely fixes the problem, but you shouldn't have to use it. The problem still exists in your code somewhere. Let me mention an example of how two post requests could be sent:

If you are using AngularJS, and lets say you make a controller called "HandleAjaxController" you could assign this ng-controller to a div, and then accidentally assign this same ng-controller to an inner div. This would cause the post request to be sent twice. So:

    <div ng-controller='HandleAjaxController'>
        <div ng-controller='HandleAjaxController'>
            <button id="home" type="button" class="btn btn-success">Send data</button>

This caused a lot of stress for me one time because in my ng-route I had set the controller in here:

    $routeProvider
    .when("/", {
        templateUrl : "src/js/partials/home.html",
        controller : "HandleAjaxController"
    })

and then I set it again in my home.html: <div ng-controller='HandleAjaxController'>

Anyways, that is one example of how two posts could be sent.

Unrelenting answered 26/9, 2017 at 4:44 Comment(0)
A
1

You should check your another js code, maybe somewhere it triggers twice "submit" event. This happened in my case, i forget "return false" in onclick handler for one button

Absence answered 22/8, 2018 at 17:34 Comment(0)
L
0

i have added jquery.unobtrusive-ajax.min.js ref twice as answered here https://mcmap.net/q/339607/-html-renderpartial-and-ajax-beginform-gt-submit-is-called-twice

Legation answered 14/12, 2017 at 12:52 Comment(0)
M
0

For someone who have almost same problem I can say that you should control your jQuery events away from function(){}, so the best to had only one request from ajax POST is to have events like this:

$(document).ready(function {
 $("#exportForm").click(function{
   $.ajax({
      type: "POST",
      url: "#", //your url
      data: data, //your variable
      success: function(){
        //do something here
      }
   });
 });
});

not in function which evokes second function like this:

$(document).ready(function {
 exportingForm();

 function exportingForm(){
   $("#exportForm").click(function{
     $.ajax({
        type: "POST",
        url: "#", //your url
        data: data, //your variable
        success: function(){
          //do something here
        }
     });
   });
 }
});
Mycology answered 22/11, 2018 at 13:45 Comment(0)
U
0

Just want to point out, if you have more than one element with the same class, this can happen as well.

<button class="downvote">
  <img src="/img/thumbs-down.png" class="downvote">
</button>
Unbent answered 29/8, 2019 at 3:23 Comment(0)
R
-3

The problem can be resolved by using a div in place of a button on your php form. A button is not needed due to the use of ajax.

Retuse answered 7/2, 2017 at 5:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.