Q:

Registration/Login Confirmation Before Redirect

I have a registration and login form which is working and updates/queries the database linked to my website. Currently, I am using JavaScript for client side validation before executing the registration/login processes on the server side (also has validation but only to make sure fields that are posted from the forms are not empty). Once these processes are done, the user is redirected to home/redirect page. However, for a better Human-Computer Interaction, I wish for the web page to show a loading icon while the server side deals with the registration/login processes and then display a confirmation message to the user if the details are correct before redirecting them to the home/redirect page. Is there any way I can achieve this? Any suggestions/help would be appreciated.
Registration Form
<form method="POST" action="userRegistration.php" id="registrationForm" novalidate>
    <div class="form-row">
        <div class="col-md-6 pt-4">
            <div class="form-group">
                <input type="text" class="form-control" id="firstname" name="firstname" required />
                <label class="form-ph" for="firstname" id="firstnamePlaceholder">FIRST NAME</label>
            </div>
        </div>

        <div class="col-md-6 pt-4">
            <div class="form-group">
                <input type="text" class="form-control" id="surname" name="surname" required />
                <label class="form-ph" for="surname" id="surnamePlaceholder">LAST NAME</label>
            </div>
        </div>
    </div>

    <div class="form-row">
        <div class="col pt-4">
            <div class="form-group">
                <input type="email" class="form-control" id="email" name="email" autocomplete="off" required />
                <label class="form-ph" for="email" id="emailPlaceholder">EMAIL ADDRESS</label>
                <small>
                    <span id="emailCheck"></span>
                </small>
            </div>
        </div>
    </div>

    <div class="form-row">
        <div class="col pt-4">
            <div class="form-group">
                <input type="text" class="form-control" id="usernameSignup" name="usernameSignup" autocomplete="off" minlength="6" maxlength="32" required />
                <label class="form-ph" for="usernameSignup" id="usernameSignupPlaceholder">USERNAME</label>
                <small id="helpBlock" class="form-text text-muted">
                    Must be between 6-32 characters
                    <span id="usernameCheck"></span>
                </small>
            </div>
        </div>
    </div>

    <div class="form-row">
        <div class="col-md-6 pt-4">
            <div class="form-group">
                <input type="password" class="form-control" id="passwordSignup" name="passwordSignup" minlength="8" required />
                <label class="form-ph" for="passwordSignup" id="passwordSignupPlaceholder">PASSWORD</label>
                <small id="helpBlock" class="form-text text-muted">
                    Must be 8 or more characters
                </small>
            </div>
        </div>

        <div class="col-md-6 pt-4">
            <div class="form-group">
                <input type="password" class="form-control" id="passwordConfirm" name="passwordConfirm" required />
                <label class="form-ph" for="passwordConfirm" id="passwordConfirmPlaceholder">CONFIRM PASSWORD</label>
                <small>
                    <span id="passwordCheck"></span>
                </small>
            </div>
        </div>
    </div>

    <p>
        By creating an account, you agree to our Terms and Conditions &
        Privacy Policy.
    </p>

    <button type="submit" class="btn btn-primary btn-block" id="registrationButton">
        SIGN UP
    </button>
</form>

Registration Server Side Process
<?php
// try catch statement to connect to database through getConnection() function in dbConn.php file
try {
    require_once("dbConn.php");
    $dbConn = getConnection();
} catch (Exception $e) {
    echo "A problem occured: " . $e->getMessage();
}

// Form validation for POST method to check fields are not empty
if (!empty($_POST['firstname'])) {
    $firstname = filter_has_var(INPUT_POST, 'firstname') ? $_POST['firstname'] : null;
    $firstname = trim($firstname);
} else {
    echo "A first name must be entered.<br/>";
}

if (!empty($_POST['surname'])) {
    $surname = filter_has_var(INPUT_POST, 'surname') ? $_POST['surname'] : null;
    $surname = trim($surname);
} else {
    echo "A surname must be entered.<br/>";
}

if (!empty($_POST['email'])) {
    $email = filter_has_var(INPUT_POST, 'email') ? $_POST['email'] : null;
    $email = trim($email);
} else {
    echo "An email address must be entered.<br/>";
}

if (!empty($_POST['usernameSignup'])) {
    $usernameSignup = filter_has_var(INPUT_POST, 'usernameSignup') ? $_POST['usernameSignup'] : null;
    $usernameSignup = trim($usernameSignup);
} else {
    echo "A username must be entered.<br/>";
}

if (!empty($_POST['passwordSignup'])) {
    $passwordSignup = filter_has_var(INPUT_POST, 'passwordSignup') ? $_POST['passwordSignup'] : null;
    $passwordSignup = trim($passwordSignup);
} else {
    echo "A password must be entered.<br/>";
}

if (!empty($_POST['passwordConfirm'])) {
    $passwordConfirm = filter_has_var(INPUT_POST, 'passwordConfirm') ? $_POST['passwordConfirm'] : null;
    $passwordConfirm = trim($passwordConfirm);
} else {
    echo "A password must be entered that matches the previous one.<br/>";
}

// Checks to see if both passwords entered match, to set the passwordHash variable.
if ($passwordSignup == $passwordConfirm) {
    $passwordHash = password_hash($passwordSignup, PASSWORD_DEFAULT);
} else {
    echo "The passwords entered don't match, please try again <br/>";
}

// If all the previous steps are valid and variables are set, try to run the SQL query to make new account.
if (!empty($firstname) && !empty($surname) && !empty($email) && !empty($usernameSignup) && !empty($passwordHash)) {
    try {
        $sqlQuery = "INSERT INTO GH_users (firstname, surname, email, accountConfirmed, username, passwordHash)
        VALUES ('$firstname', '$surname', '$email', 0, '$usernameSignup', '$passwordHash')";

        $dbConn->exec($sqlQuery);
        header("location: index.php");
        exit;
    } catch (PDOException $e) {
        echo $sqlQuery . "<br>" . $e->getMessage();
    }
}

JavaScript Validation
$("#registrationForm").submit(function(event) {
  $("#registrationForm input").each(function() {
    if (!$(this).hasClass("is-valid")) {
      $(this).addClass("is-invalid");
      event.preventDefault();
      event.stopPropagation();
    }
  });
});

Login Form
<form method="POST" action="userAuthentication.php" id="loginForm" novalidate>
    <div class="form-row">
        <div class="col-12 pt-4">
            <div class="form-group">
                <input type="text" class="form-control" id="username" name="username" required />
                <label class="form-ph" for="username" id="usernamePlaceholder">USERNAME</label>
            </div>
        </div>
    </div>

    <div class="form-row pb-3">
        <div class="col-12 pt-3">
            <div class="form-group">
                <input type="password" class="form-control" id="password" name="password" required />
                <label class="form-ph" for="password" id="passwordPlaceholder">
                    PASSWORD
                </label>
                <small id="helpBlock" class="float-right">
                    <a href="#">Forgotten Password?</a>
                </small>
            </div>
        </div>
    </div>

    <button type="submit" class="btn btn-primary btn-block" id="loginButton">
        SIGN IN
    </button>
</form>

Login Server Side Process
<?php

// try catch statement to connect to the database connection file to use the getConnection() function and store it
// in $dbConn. If it doesn't connect, then show the error message.
try {
    ini_set("session.save_path", "/home/unn_w16010421/sessionData");
    session_start();
    require_once("dbConn.php");
    $dbConn = getConnection();
} catch (Exception $e) {
    // Instead of echoing error, redirect user to error page for a more professional look.
    echo "A problem occured: " . $e->getMessage();
}

// Takes the entered username and password from the post method (Login form) and stores them into a variable for
// later use.
$username = filter_has_var(INPUT_POST, 'username') ? $_POST['username'] : null;
$username = trim($username);
$password = filter_has_var(INPUT_POST, 'password') ? $_POST['password'] : null;

// If the post method has an empty username or password let the user know.
if (empty($username) || empty($password)) {
    // Again in stead of echoing error, redirect user to error page for a more professional look.
    echo "You need to provide a username and a password. Please try again.";
}
// Else, check the database for a match with the inputted username and password.
else {
    // try statement to check if the entered username and password matches with one in the database.
    try {
        // Clears any session data.
        // $_SESSION = array();

        // SQL Query to retrieve the passwordHash for a user from the GH_users table where the username entered by 
        // the user matches one in the database.
        $sqlQuery = "SELECT passwordHash FROM GH_users WHERE username = :username";
        $stmt = $dbConn->prepare($sqlQuery);
        // Executes the query to go through the array until the username entered by the user matches one in the
        // database and stores it into $user variable.
        $stmt->execute(array(':username' => $username));
        $user = $stmt->fetchObject();

        // If the query returns a user with the entered username, then check if the password entered also matches
        // with the one in the database. If it does, authentication is complete and create a session for the user.
        // Redirect user to home page.
        if ($user) {
            if (password_verify($password, $user->passwordHash)) {
                $userID = $user->userID;
                $_SESSION['userID'] = $userID;
                $_SESSION['logged-in'] = true;
                $_SESSION['username'] = $username;

                if (isset($_SESSION['login_redirect'])) {
                    header("Location: " . $_SESSION['login_redirect']);
                    // Cleans up the session variable 
                    unset($_SESSION['login_redirect']);
                    exit;
                } else {
                    header("location: index.php");
                    exit;
                }
            }
            // If the password for an existing username doesn't match with the one in the database, inform the user
            else {
                echo "The username and/or password was incorrect, please try again.";
            }
        }
        // If the query doesn't return a user, inform the user.
        else {
            echo "The username or password was incorrect, please try again.";
        }
    } catch (PDOException $e) {
        echo "Error: " . $e->getMessage();
    }
}

A:

Since you're using jQuery you can use the following functions to run an animation during an AJAX call which would perform the submission of the form:
$(document).ajaxStart(function(){
    // code to display animation
});

$(document).ajaxStop(function(){
    // code to remove animation when AJAX is complete
});

Your redirection should be in the AJAX return, not the PHP code.

