Delay the Bootstrap modal hide after the HTML form is submitted

Viewed 273

In my WordPress v5.8.2, I have a custom HTML form in Bootstrap modal v4.

<!-- Modal -->
<div class="modal fade" id="modal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <form id="form" method="POST" class="form">
          <input id="name" name="name" class="form-control" type="text" placeholder="Full Name" value="">
          <button type="submit" name="form_submit" id="form_submit" class="btn">Submit</button>
        </form>
      </div>
      <div class="modal-footer">
        <div id="confirm" class="row d-none">
          <div class="col-12 text-center">
            <div id="alert" role="alert"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

For user experience, wanted to show a confirmation message for 2 seconds after the form submission in a div #confirm with below jQuery:

  $(document).on("submit", "#form", function(e) {
    $name = $(this).find('input[name=name]').val(); // Name
    $("#alert").text('Thank you ' + $name + '.');
    $("#confirm").removeClass("d-none");
    setTimeout(function() {
      $("#modal").modal('hide');
    }, 2000);
  });

I would like to hold the modal for 2 seconds before it hides, so I can show the message in the #confirm div. However the modal is closing immediately.

Here is the https://jsfiddle.net/kingBethal/08v2qfa5/10/.

3 Answers

I suggest you use a button type of button (not a submit type of button) and then handle the form submission programmatically

Please look at the following sample code

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Test</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        window.addEventListener('load', () => {
            document.getElementById('submitButton').addEventListener('click', () => {
                let name = document.getElementById('name').value;
                if (name !== '') {
                    let alertPlaceholder = document.getElementById('alertPlaceholder');
                    alertPlaceholder.outerHTML = '<div class="alert alert-primary">Thank you, ' + name + '!</div>';
                    setTimeout(() => { document.getElementById('form').submit(); }, 2000);
                }
            });
        });
    </script>
</head>
<body>
    <div class="container">
        <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">Test</button>
        <div class="modal" id="exampleModal">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">This is a test</h5>
                    </div>
                    <div class="modal-body">
                        <div id="alertPlaceholder"></div>
                        <form id="form">
                            <div class="mb-3">
                                <label for="name" class="form-label">Name</label>
                                <input class="form-control" id="name" name="name" value="Fabio" />
                            </div>
                        </form>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-primary" id="submitButton">Submit</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

the problem with your code is when you click on submit it directly submits your form without executing your JS script so to execute JS Script you must need to prevent submitting the form. for that put this code in submitting Js

e.preventDefault()

for submitting form code after script execute

document.getElementById("form").submit()

here is the working code hope it will help you.

 
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>Bootstrap Example</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js">

    </script>
          <script>
          $(document).on("submit", "#form", function(e) {
            e.preventDefault()
            $name = $(this).find('input[name=name]').val(); // Name
            $("#alert").text('Thank you ' + $name + '.');
            $("#confirm").removeClass("d-none");
            setTimeout(function() {
              $("#modal").modal('hide');
             document.getElementById("form").submit();
            }, 2000);
           
          });
          </script>
    </head>
    <body>
    <!-- Button trigger modal -->
    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal">
      Launch modal
    </button>

     <!-- Modal -->
    <div class="modal fade" id="modal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            <form id="form" method="POST" class="form">
              <input id="name" name="name" class="form-control" type="text" placeholder="Full Name" value="">
              <button type="submit" name="form_submit" id="form_submit" class="btn">Submit</button>
            </form>
          </div>
          <div class="modal-footer">
            <div id="confirm" class="row d-none">
              <div class="col-12 text-center">
                <div id="alert" role="alert"></div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    </body>
    </html>

Talking queue from @lam-tran-duc advise on using ajax, this is how I solved:

The form:

    <!-- Modal -->
<div class="modal fade" id="modal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <form id="form" method="POST" class="form">
          <input id="name" name="name" class="form-control" type="text" placeholder="Full Name" value="">
          <button type="submit" name="form_submit" id="form_submit" class="btn">Submit</button>
        </form>
      </div>
      <div class="modal-footer">
        <div id="confirm" class="row d-none">
          <div class="col-12 text-center">
            <div id="alert" role="alert"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Declared below ajax variables in WordPress functions.php file:

/*
 * ajax variables in functions.php
 */

function ajax_variables() {?>
  <script type = "text/javascript" >
    var ajax_url = '<?php echo admin_url("admin-ajax.php"); ?>';
  var ajax_nonce = '<?php echo wp_create_nonce("ajax_nonce"); ?>'; 
  </script> <?php
}

add_action('wp_head', 'ajax_variables');

With below JS script I am able to prevent the form from submitting, so I can show a confirmation message and then process the form submission through ajax:

/*
 * .js file
 */

$(document).on("submit", "#form", function(e) {
  $name = $(this).find('input[name=name]').val(); // Name
  $("#alert").text('Thank you ' + $name + '.');
  $("#confirm").removeClass("d-none");
  setTimeout(function() {
    $("#modal").modal('hide');
  }, 20000);

  // ajax
  var form_data = $(this).serializeArray();

  // Here we add our nonce. The one created in functions.php ajax_variables function.
  form_data.push({
    "name": "form",
    "value": ajax_nonce
  });

  // ajax petition.
  $.ajax({
    url: ajax_url, // AJAX endpoint from ajax_variables function
    type: 'post',
    security: '<?php echo $ajax_nonce; ?>',
    data: form_data
  });

  // prevents the submit event to refresh the page.
  return false;

});
Related