3

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/.

theKing
  • 714
  • 3
  • 14
  • 36
  • Are you trying to respond to the _completion_ of the submit event, or just showing a message of some sort _while_ the form is submitted? – Tieson T. Dec 20 '21 at 07:15
  • This thank you message will be shown on click of submit button as a form submission confirmation, this button will be enabled only after the form validation through another function. – theKing Dec 20 '21 at 07:22
  • 1
    You can refer [Prevent Default on Form Submit jQuery](https://stackoverflow.com/questions/6462143/prevent-default-on-form-submit-jquery) to catch submit event after that use [ajax](https://api.jquery.com/jquery.ajax/) to submit your form. – Lam Tran Duc Dec 20 '21 at 09:52
  • @LamTranDuc though I wanted do non-ajax way to keep the code simple, it is always coming back to ajax to make it simple :). – theKing Dec 20 '21 at 11:25
  • @theKing your issue solved? – Neeraj Dec 22 '21 at 05:44

3 Answers3

2

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>
Fabio Scagliola
  • 338
  • 2
  • 11
0

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>
Neeraj
  • 749
  • 6
  • 15
0

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;

});
theKing
  • 714
  • 3
  • 14
  • 36