user2789116 user2789116 - 4 months ago 23
Javascript Question

Wait for Animation Inside of Form Submit Event

Submitting Form After jQuery Execution



The way I have my form currently set up the user can select one of several options, each represented by a button with a unique value. What I'd like to do is process the form data and then execute an animation if everything checks out. My problem is that if I use
.preventDefault()
I can't get the form to submit with the chosen button value properly, without
preventDefault()
the animation doesn't occur always (I can get it to work sporadically but that isn't really an acceptable solution).

Just to be clear, the desired behavior is to detect a form submission with an event listener, execute an animation upon submission, and redirect the page while sending the value of the button that was selected via POST to the next page.

I tried


  • using
    $("input").click()

  • using
    $("form").submit()



Here is the HTML I was Using to Experiment

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body{
padding:100px;
text-align: center;
}
form{
margin:20px auto;
padding:20px;
border:solid black 2px;
width: 400px;
background-color:red;
}
form input[type='submit']{
display:block;
width:200px;
height:40px;
margin:10px auto;
}
form input[type="submit"]:hover{
background-color:grey;
font-weight:bold;
}

.hidden{
display:none;
}
#sqare{
margin:20px auto;
background-color:black;
width:200px;
height:200px;
}
</style>
<script>
</script>
</head>
<body>

<?php
if(isset($_POST['my_button'])){
echo $_POST['my_button'];
}
?>

<form id="ver_form" method="post" action="">
<input type="submit" value = "Button No. 0" name = "my_button">
<input type="submit" value = "Button No. 1" name = "my_button">
<input type="submit" value = "Button No. 2" name = "my_button">
<input type="submit" value = "Button No. 3" name = "my_button">
</form>

<div id="square"></div>

</body>
</html>

Answer

First a warning: If you're doing this on a form with target="_blank", this may well trigger the pop-up blocker of the user's browser, because it tries to open a window from code that isn't running in immediate response to a user event.

But assuming you're staying in the same window: A combination should do it:

  1. Remove the name of your submit buttons entirely.

  2. Add a type=hidden field with name=my_button

  3. On a click of a submit button, set the form's my_button hidden field to the button's value.

  4. Use your example submit handler but change how you submit the form after the end of the animation to:

    form[0].submit();
    //  ^^^---- note
    

    form.submit() calls jQuery's submit method, which will re-trigger the submit event. form[0].submit() calls the DOM form element's submit function, which does not re-trigger the submit event.

So combining the click and submit handlers:

$(function(){
  var form = $("form");
  // On a click on a submit button, set the hidden field's value
  form.find("input[type=submit]").on("click", function() {
    form.find("[name=my_button]").val(this.value);
  });
  // On form submit...
  form.submit(function(e){
    // Prevent the submission
    e.preventDefault();
    // Start the animation
    $("#square").toggle(100,function(){
      // It's done, do the submission NOT with jQuery's `submit` function
      form[0].submit();
    });
  });
});

With this updated HTML:

<input type="submit" value = "Button No. 0">
<input type="submit" value = "Button No. 1">
<input type="submit" value = "Button No. 2">
<input type="submit" value = "Button No. 3">
<input type="hidden" name = "my_button">

Complete example, doing a GET to google.com using q instead of my_button so we see the result in their search page based on which button you press:

Live Copy on JSBin

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Example</title>
</head>
<body>
<form action="http://google.com/search" method="get">
<input type="submit" value = "Kittens">
<input type="submit" value = "Puppies">
<input type="submit" value = "Unicorns">
<input type="submit" value = "Bunnies">
<input type="hidden" name = "q">
</form>
<div id="square">I'm the square</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(function(){
  var form = $("form");
  // On a click on a submit button, set the hidden field's value
  form.find("input[type=submit]").on("click", function() {
    form.find("[name=q]").val(this.value);
  });
  // On form submit...
  form.submit(function(e){
    // Prevent the submission
    e.preventDefault();
    // Start the animation
    $("#square").toggle(100,function(){
      // It's done, do the submission NOT with jQuery's `submit` function
      form[0].submit();
    });
  });
});
</script>
</body>
</html>