After all these years I finally added Javascript to my contact form on my website. I used Vanilla Javascript and FETCH ($.GET is the jQuery Equivalent). The form won’t work with older browsers as I didn’t write any code or translate the code to support these older browsers. I might do this is in the future.
I’ll start of with the Javascript file and the PHP file that retrieves the JSON data.
Javascript File:
'use strict';
const contact = () => {
const d = document;
const sendUrl = 'sendmsg.php';
const submit = d.querySelector('#submitForm');
const radioBtn = d.querySelector('#radio-toolbar');
const buttons = d.getElementsByName("reason");
const message = d.querySelector('#message');
var messageSuccess = d.querySelector('#messageSuccess');
var name = d.querySelector('#name');
var email = d.querySelector('#email');
var phone = d.querySelector('#phone');
var website = d.querySelector('#web');
var notice = d.querySelector('#notice');
var sendEmail = {};
var sendStatus = {
name: false,
email: false,
comments: false
};
sendEmail.reason = 'message';
sendEmail.token = d.querySelector('#token').value;
var comments = d.querySelector("textarea");
var output = d.querySelector("#length");
name.addEventListener('input', evt => {
const value = name.value.trim();
if (value) {
notice.style.display = "none";
sendEmail.name = name.value;
sendStatus.name = true;
} else {
notice.style.display = "block";
notice.textContent = "Name is Required";
}
});
const emailIsValid = (email) => {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
};
email.addEventListener('change', () => {
var status = emailIsValid(email.value);
console.log('Email Address', email.value, 'Status', status);
if (!status) {
email.value = "";
notice.style.display = "block";
notice.textContent = "Email Address Invalid!";
} else {
notice.style.display = "none";
sendEmail.email = email.value;
sendStatus.email = true;
}
});
/*
* Selection Element
*/
buttons.forEach((value, index) => {
//console.log(value, index);
buttons[index].addEventListener('change', (e) => {
sendEmail.reason = e.target.value;
//console.log('Reason:', sendEmail.reason);
});
});
comments.addEventListener("input", evt => {
output.textContent = comments.value.length;
const value = comments.value.trim();
if (value) {
notice.style.display = "none";
sendEmail.comments = comments.value;
sendStatus.comments = true;
} else {
notice.style.display = "block";
notice.textContent = "Comment is Required!";
}
});
/* Success function utilizing FETCH */
const sendUISuccess = function (result) {
//console.log('Result', result);
if (result) {
d.querySelector('#recaptcha').style.display = "none";
submit.style.display = "none";
notice.style.display = "block";
notice.textContent = "Email Successfully Sent!";
notice.style.color = "green";
notice.style.fontSize = "xx-large";
messageSuccess.style.display = "block";
d.querySelectorAll('form > *').forEach(function (a) {
a.disabled = true;
});
}
};
/* If Database Table fails to update data in mysql table */
const sendUIError = function (error) {
console.log("Database Table did not load", error);
};
const handleSaveErrors = function (response) {
if (!response.ok) {
throw (response.status + ' : ' + response.statusText);
}
return response.json();
};
const saveRequest = (sendUrl, succeed, fail) => {
//const data = {username: 'example'};
fetch(sendUrl, {
method: 'POST', // or 'PUT'
body: JSON.stringify(sendEmail)
})
.then((response) => handleSaveErrors(response))
.then((data) => succeed(data))
.catch((error) => fail(error));
};
submit.addEventListener('click', (e) => {
e.preventDefault();
sendEmail.phone = phone.value;
sendEmail.website = website.value;
sendEmail.response = submit.getAttribute('data-response');
//console.log(sendEmail, sendStatus);
if (sendStatus.name && sendStatus.email && sendStatus.comments) {
saveRequest(sendUrl, sendUISuccess, sendUIError);
} else {
notice.style.display = "block";
notice.textContent = "Name, Email, and Message Required!";
}
}, false);
};
contact();
the php file:
<?php
require_once '../private/initialize.php';
use Library\Database\Database as DB;
use Library\Email\Email;
/*
* The below must be used in order for the json to be decoded properly.
*/
$data = json_decode(file_get_contents('php://input'), true);
$token = $data['token'];
if (hash_equals($_SESSION['token'], $data['token'])) {
/* The Following to get response back from Google recaptcha */
$url = "https://www.google.com/recaptcha/api/siteverify";
$remoteServer = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_SANITIZE_URL);
/*
* g-response is from $data['response'] that was sent over using FETCH
*/
$response = file_get_contents($url . "?secret=" . PRIVATE_KEY . "&response=" . $data['response'] . "&remoteip=" . $remoteServer);
$recaptcha_data = json_decode($response);
/* The actual check of the recaptcha */
if (isset($recaptcha_data->success) && $recaptcha_data->success === TRUE) {
/*
* If token matches and ReCaptcha is valid then send to an email
* php script or php class. I personally use Swiftmailer, but you can use
* another 3rd Party Mailer or write you own email script (I wouldn't
* recommend it).
*/
$result = new Email($data);
/* Send Back Result (true or false) back to Fetch */
if ($result) {
output(true);
} else {
errorOutput(false);
}
} else {
$success = "You're not a human!"; // Not on a production server:
}
} else {
output('Token Error');
}
function errorOutput($output, $code = 500) {
http_response_code($code);
echo json_encode($output);
}
/*
* After converting data array to JSON send back to javascript using
* this function.
*/
function output($output) {
http_response_code(200);
echo json_encode($output);
}
and the contact page file itself:
<?php
require_once '../private/initialize.php';
use Library\Database\Database as DB;
use Library\Email\Email;
$username = \NULL;
$success = "Contact Form";
$token = $_SESSION['token'];
$db = DB::getInstance();
$pdo = $db->getConnection();
/*
* Fallback if user disables Javascript
*/
$submit = filter_input(INPUT_POST, 'submit', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if (isset($submit) && $submit === 'submit') {
$token = filter_input(INPUT_POST, 'token', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if (!empty($token)) {
if (hash_equals($_SESSION['token'], $token)) {
/* The Following to get response back from Google recaptcha */
$url = "https://www.google.com/recaptcha/api/siteverify";
$remoteServer = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_SANITIZE_URL);
$response = file_get_contents($url . "?secret=" . PRIVATE_KEY . "&response=" . \htmlspecialchars($_POST['g-recaptcha-response']) . "&remoteip=" . $remoteServer);
$recaptcha_data = json_decode($response);
/* The actual check of the recaptcha */
if (isset($recaptcha_data->success) && $recaptcha_data->success === TRUE) {
$success = "Mail was sent!";
$data['name'] = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$data['email'] = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$data['phone'] = filter_input(INPUT_POST, 'phone', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$data['website'] = filter_input(INPUT_POST, 'website', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$data['reason'] = filter_input(INPUT_POST, 'reason', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$data['comments'] = filter_input(INPUT_POST, 'comments', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$send = new Email($data);
} else {
$success = "You're not a human!"; // Not on a production server:
}
} else {
// Log this as a warning and keep an eye on these attempts
}
}
}
$server_name = filter_input(INPUT_SERVER, 'SERVER_NAME', FILTER_SANITIZE_URL);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<title>Contact Page</title>
<link rel="shortcut icon" href="favicon.ico" >
<script src='https://www.google.com/recaptcha/api.js'></script>
<?php if ($pageName === 'triviaGame.php') { ?>
<link href="https://fonts.googleapis.com/css?family=Teko:400,700&display=swap" rel="stylesheet">
<?php } ?>
<link rel="stylesheet" href="assets/css/quizStyling.css">
<link rel="stylesheet" href="assets/css/countdown.css">
</head>
<body>
<div id="pictureBox" class="shade">
<div id="picture">
<div class="play">
<button class="controls" id="pause">Play</button>
</div>
<img id="pictureELE" src="assets/large/img-photos-1554677976.jpg" alt="Big Screen Picture">
<div class="exifInfo">
<p id="exifData"></p>
</div>
<div class="exitBtn">
<a id="exitBtn" class="btn" href="#">← Exit</a>
</div>
</div>
<div class="prevSlide">
<a id="preSlide" href="#">← Prev</a>
</div>
<div class="nextSlide">
<a id="nextSlide" href="#">Next →</a>
</div>
</div>
<div id="page">
<header>
<a class="logo" title="Miniature Photographer Logo" href="index.php"><span>Miniature Photographer Logo</span></a>
<div class="intro">
<h1>The Miniature Photographer</h1>
<a class="btn menuExit" title="My LinkedIn Page" href="https://www.linkedin.com/in/johnpepp/">LinkedIn Page</a>
</div>
</header>
<section class="main">
<form id="contact" name="contact" action="contact.php" method="post" autocomplete="on">
<div id="message">
<h2 id="notice">Form Notification</h2>
<a id="messageSuccess" href="index.php" title="Home Page">Home</a>
</div>
<fieldset>
<legend>Contact Form</legend>
<input id="token" type="hidden" name="token" value="<?= $_SESSION['token']; ?>">
<label class="labelstyle" for="name" accesskey="U">Name</label>
<input name="name" type="text" id="name" tabindex="1" autofocus required="required" />
<label class="labelstyle" for="email" accesskey="E">Email</label>
<input name="email" type="email" id="email" tabindex="2" required="required" />
<label class="labelstyle" for="phone" accesskey="P" >Phone <small>(optional)</small></label>
<input name="phone" type="tel" id="phone" tabindex="3">
<label class="labelstyle" for="web" accesskey="W">Website <small>(optional)</small></label>
<input name="website" type="text" id="web" tabindex="4">
<div id="radio-toolbar">
<input type="radio" id="radioMessage" name="reason" value="message" checked>
<label for="radioMessage">message</label>
<input type="radio" id="radioOrder" name="reason" value="order">
<label for="radioOrder">order</label>
<input type="radio" id="radioStatus" name="reason" value="status">
<label for="radioStatus">status</label>
</div>
<p> </p>
<label class="textareaLabel" for="comments">Comments Length:<span id="length"></span></label>
<textarea name="comments" id="comments" spellcheck="true" tabindex="6" required="required"></textarea>
<?php if (filter_input(INPUT_SERVER, 'SERVER_NAME', FILTER_SANITIZE_URL) == "localhost") { ?>
<div id="recaptcha" class="g-recaptcha" data-sitekey="6LcR8OQUAAAAAG1qLKJal22tLlpW4loJ7CIcfrlX" data-callback="correctCaptcha"></div>
<?php } else { ?>
<!-- Use a data callback function that Google provides -->
<div id="recaptcha" class="g-recaptcha" data-sitekey="6LdXNpAUAAAAAMwtslAEqbi9CU3sviuv2imYbQfe" data-callback="correctCaptcha"></div>
<?php } ?>
<input id="submitForm" type="submit" name="submit" value="submit" tabindex="7" data-response="">
</fieldset>
</form>
</section>
<nav>
<ul>
<li>
<a class="menuExit" title="Home Page" href="index.php">Home</a>
</li>
<li>
<a class="menuExit" title="Blog Page" href="blog.php"aria-haspopup='true'>Wild Side</a>
<ul>
<li>
<a class="menuExit" title="Gallery" href="gallery.php" aria-haspopup='true'>Gallery</a>
<ul>
<?php
if (is_logged_in()) {
echo '<li>';
echo '<a class="menuExit" title="Member Page" href="member_page.php">Member</a>';
echo '</li>';
echo '<li>';
echo '<a id="maintenance" class="menuExit" title="Trivia Maintenance" href="trivMain.php">Maintenance</a>';
echo '</li>';
echo '<li>';
echo '<a id="editPage" class="menuExit" title="Edit Page" href="editTrivia.php">Edit</a>';
echo '</li>';
}
?>
<li>
<?php echo (is_logged_in()) ? '<a class="menuExit" title="Logout" href="logout.php">Logout</a>' : '<a class="menuExit" title="Login Page" href="login.php">Login</a>'; ?>
<?php echo (is_logged_in()) ? '<a class="menuExit" title="Facebook Logout" href="FacebookLogout.php">Logout</a>' : '<a class="menuExit" title="Facebook Login" href="facebookLogin.php">FB Login</a>'; ?>
</li>
</ul>
</li>
</ul>
</li>
<li>
<a class="menuExit" title="About Me" href="about.php">About</a>
</li>
<li>
<a class="menuExit" title="Contact Page" href="contact.php">Contact</a>
</li>
<li>
<a id="photography" class="menuExit" data-category="movie" title="Trivia Game" href="game.php">Photography Trivia</a>
</li>
<li>
<a class="menuExit" title="Astronomy Picture of the Day" href="nasa.php">APOD</a>
</li>
</ul>
</nav><!-- End of Navigation -->
<footer>
© The Miniature Photographer
<div class="content">
<a class="menuExit" title="Facebook Miniature Photographer" href="https://www.facebook.com/Pepster64/">Facebook Miniature Photographer Page</a>
<!-- <a title="Terms of Service" href="#">Terms of Service</a>-->
</div>
</footer>
</div>
<script src="assets/js/contact.js"></script>
<!-- Fetch the g-response using a callback function -->
<script>
var correctCaptcha = function (response) {
document.querySelector('#submitForm').setAttribute('data-response', response);
};
</script>
</body>
</html>
Sorry about the long files, but it should not be too hard to decipher. The code isn’t tight, but over the next couple of weeks I will update the code and HTML. I have only tested a little, but it works though there might be some hidden bugs that I might come across. I hope this will help some one out?
A working example can be found here: https://www.miniaturephotographer.com/contact.php