I’m setting up a registration/login in system for my online trivia game and have come up with a dynamic way to check for username duplicates in a MySQL Database Table in real time.
First the Vanilla-JS script:
'use strict';
const d = document;
const sendUrl = 'checkName.php'; // Name of php file:
const unavailable = d.querySelector('.unavailable');
var username = d.querySelector('#username');
var checkUsername = {};
/* Success function utilizing FETCH */
const checkUISuccess = function (status) {
/*
* Make <span> HTML tag visible to highlight message
* in red.
*/
if (status) {
unavailable.style.display = "inline-block";
} else {
unavailable.style.display = "none";
}
};
/* If Database Table fails to update data in mysql table */
const checkUIError = function (error) {
console.log("Database Table did not load", error);
};
/*
* Grab the status if there is an error.
*/
const handleSaveErrors = function (response) {
if (!response.ok) {
throw (response.status + ' : ' + response.statusText);
}
return response.json();
};
/*
* Fetch ($.get in jQuery) that basic is a simplified newer Ajax
* protocol (function?).
*/
const checkRequest = (sendUrl, succeed, fail) => {
fetch(sendUrl, {
method: 'POST', // or 'PUT'
body: JSON.stringify(checkUsername)
})
.then((response) => handleSaveErrors(response))
.then((data) => succeed(data))
.catch((error) => fail(error));
};
/*
* Grab the keystrokes
*/
const checkForDuplicate = (e) => {
e.preventDefault();
checkUsername.username = username.value; // Put the keystrokes in object var:
/*
* Call the checkRequest Function using sendUrl variable as the name
* of the php file that will be used to check against the database table.
*/
checkRequest(sendUrl, checkUISuccess, checkUIError);
};
/*
* Add an Event Listener to check for username already in
* database table. When the person types every keyup stroke
* is checked against the database table.
*/
username.addEventListener('keyup', checkForDuplicate, false);
The HTML
<form class="registerForm" action="" method="post" autocomplete="on">
<h1><?php echo (isset($message)) ? $message : 'Register'; ?></h1>
<p><?php echo (isset($errPassword)) ? $errPassword : "Please fill in this form to create an account."; ?></p>
<hr>
<label for="username"><b>Username <span class="unavailable"> - Not Available, please choose a different one.</span></b></label>
<input id="username" type="text" placeholder="<?php echo (isset($statusUsername) && $statusUsername) ? "Username is not available, please re-enter!" : "Enter Username"; ?>" name="data[username]" value="" autofocus required>
<label for="email"><b>Email</b></label>
<input type="text" placeholder="Enter Email" name="data[email]" value="<?php echo (isset($data['email'])) ? $data['email'] : null; ?>" required>
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="data[password]" required>
<label for="psw-repeat"><b>Repeat Password</b></label>
<input type="password" placeholder="Repeat Password" name="data[repeatPassword]" required>
<hr>
<p>By creating an account you agree to our <a href="#">Terms & Privacy</a>.</p>
<input type="submit" name="submit" value="enter" class="registerbtn">
<div class="signin">
<p>Already have an account? <a href="index.php">Sign in</a>.</p>
</div>
</form>
the checkName.php
<?php
require_once 'assets/config/config.php';
require_once "vendor/autoload.php";
require_once 'loginFunctions.php';
use Library\Users;
use Library\Database as DB;
$db = DB::getInstance();
$pdo = $db->getConnection();
/*
* The below must be used in order for the json to be decoded properly.
*/
$data = json_decode(file_get_contents('php://input'), true);
/*
* Check to see if username already exists
* in the MySQL Database Table (members).
*/
function duplicateUsername($username, $pdo) {
$query = "SELECT 1 FROM members WHERE username = :username";
$stmt = $pdo->prepare($query);
$stmt->bindParam(':username', $username);
$stmt->execute();
$row = $stmt->fetch();
if ($row) {
return true; // userName is in database table
} else {
return false; // Username isn't in database table
}
}
$username = trim($data['username']);
$status = duplicateUsername($username, $pdo);
output($status);
/*
* After encoding data to JSON send back to javascript using
* these functions.
*/
function errorOutput($output, $code = 500) {
http_response_code($code);
echo json_encode($output);
}
function output($output) {
http_response_code(200);
echo json_encode($output);
}
and a little bit of the CSS
.unavailable { display: none; color: #cf0004; font-style: italic; }
.registerForm {
display: block;
width: 100%;
max-width: 600px;
height: auto;
background-color: #fff;
padding: 16px;
margin: 20px auto;
/* Full-width input fields */
input[type=text], input[type=password] {
width: 100%;
padding: 15px;
margin: 5px 0 22px 0;
display: inline-block;
border: none;
background: #f1f1f1;
}
input[type=text]:focus, input[type=password]:focus {
background-color: #ddd;
outline: none;
}
/* Overwrite default styles of hr */
hr {
border: 1px solid #f1f1f1;
margin-bottom: 25px;
}
/* Set a style for the submit/register button */
.registerbtn {
background-color: #4CAF50;
color: white;
padding: 16px 20px;
margin: 8px 0;
border: none;
cursor: pointer;
text-transform: capitalize;
font-size: 1.2em;
width: 100%;
opacity: 0.9;
&:hover {
opacity:1;
}
}
Sorry, it’s written in Sass, but I think it would be easy to decipher. I hope this will give someone help in doing something like this and/or how to use Fetch. Just a note Fetch is supported by all browsers though it’s mostly older browsers. Though if you are concerned about that you can probably find a polyfill for the script, but as for me I don’t worry about that too much.