How to make modal box appear only after all requirements have been met?

84 views Asked by At

So I have a form, which asks for the user's personal information. At the end of the form I have set a modal to pop up, which says "Thank you for signing up with us etc.". However, even if you leave all the fields blank and you click on the button at the end of the form, the modal still pop up saying "Thank you for signing up with us...".

How can I set the modal to appear only after all the fields are completed?

Note: I need the personal information to remain on the page after I click the button at the end of the form. I changed the type from submit to button, but as soon as I fill in the last question and i click on the button, all the input disappears.

Any help would be much appreciated !

Here's the form:

<form id="personalinfo" name="personalinfo" onsubmit="ask()">
    <b>Please sign up with us before you proceed:</b><br>
    First Name: <input name="firstname" required="" size="40" type="text"><br>
    <br>
    Last Name: <input name="lastname" required="" size="40" type="text"><br>
    <br>
    Age: <select name="dropdown">
        <option value="1">10-18</option>
        <option value="2">19-25</option>
        <option value="3">26-35</option>
        <option value="4">36-45</option>
        <option value="5">46-55</option>
        <option value="6">56-65</option>
        <option value="6">65+</option>
    </select><br>
    <br>
    Gender: <input name="gender" required="" type="radio" value="male"> Male<br>
    <input name="gender" required="" type="radio" value="female"> Female<br>
    <input name="gender" required="" type="radio" value="other"> Other<br>
    <br>
    <br>
    <button id="OK!">OK!</button>
</form>

<div id="myModal" class="modal" type="button">
    <div class="modal-content">
        <span class="close">&times;</span>
        <p>Thank you for signing up with us ! You can now proceed to the test.</p>
    </div>
</div>

<script>
    var modal = document.getElementById('myModal');
    var btn = document.getElementById("OK!");
    var span = document.getElementsByClassName("close")[0];

    btn.onclick = function() 
    {
        modal.style.display = "block";
    }

    span.onclick = function() 
    {
        modal.style.display = "none";
    }

    window.onclick = function(event) 
    {
        if (event.target == modal) 
        {
            modal.style.display = "none";
        }
    }

</script>
</form>
1

There are 1 answers

0
Benito On

The reason why your form is cleared is that your form is submitted to the server, and hence the page reloaded with an empty form.

In my opinion, there are two ways in which you could handle this:

  1. Classic form submission
  2. AJAX form submission

In the first case you would send your form, process it on the server, and then redirect to a page containing a welcome message (the content of your modal). But in this case your form would be cleared on submission.

In the second case, you want to do several things in the right order:

  • Send the form data to the server by an AJAX request
  • Handle success and error cases
  • Show your modal, containing a message according to status (success or error)

As for the code, in your HTML:

  1. Remove onsubmit="ask()" from your <form> tag
  2. Add a type="submit" attribute to your submit button
  3. Add style="display:none" to your <div id="myModal">.
  4. Add a id="modalText" attribute to the <p> tag inside your modal

In your script, add the following after your code (you could use jQuery to make it simpler, however this is not mandatory at all, see this):

// Get <form> element and modal's <p> element
var formElem = document.getElementById('personalinfo');
var modalTextElem = document.getElementById('modalText');
var modalText;

// This replaces onsubmit="ask()"
formElem.addEventListener("submit", ask);

// The e argument to ask is an Event
function ask(e) {
    // This will prevent the form from being submitted
    // (litterally "prevent default event" from taking place)
    e.preventDefault();

    // Send data to the server via an AJAX POST request
    var xhr = new XMLHttpRequest();
    // process.php would be a server-side script (see below)
    xhr.open('POST', 'process.php');

    // This is what is called a callback:
    // code that will be executed when your request returns
    xhr.onload = function() {

        // HTTP status 200 = OK
        if (xhr.status === 200) {
            var data = JSON.parse(xhr.responseText);
            modalText = 'Thank you ' + data.firstname +
                ', for signing up with us ! You can now proceed to the test.';
        }
        // Otherwise an error occurred
        else if (xhr.status !== 200) {
            modalText = 'Request failed.  Returned status of ' + xhr.status
                + ' with error: <b>' + xhr.responseText + '</b>';
        }
        // Set the modal text
        modalTextElem.innerHTML = modalText;
        // Show the moal
        modal.setAttribute("display", "block");
    };

    // Actually send the request
    xhr.send(new FormData(formElem));
}

Then an example of server-side processing in PHP (process.php located in the same folder as your HTML form):

<?php
function validataData() {
    if( strlen($_POST['firstname'] ) < 2 ) {
        return "first name is too short (2+ characters required)";
    }
    if( strlen($_POST['lastname'] ) < 2 ) {
        return "last name is too short (2+ characters required)";
    }
    return "";
}
$validationResult = validataData();

// On error send an error response (400 bad request with the type of error)
if( !empty($validationResult) ) {
    http_response_code(400);
    die($validationResult);
}

// Otherwise send back form data (by default with error code 200)
echo json_encode($_POST);
die();

Keep in mind that this code is quick'n'dirty stuff, just to address your question.

In real-life code,you would ask an email and password in your form, then you would need much more server-side stuff: you would check that the email doesn't already exist in your database, etc.

Feel free to ask if anything isn't clear.