guestbooky/src/input-example/example.html

156 lines
6.2 KiB
HTML
Raw Normal View History

2024-10-05 00:27:04 +02:00
<!-- Yes, this is a jolly good page with all styles glued in. Don't worry, the JS portion is here too. This way you don't need to check multiple files
And I get to save space? No, actually not.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Guestbook usage example with the captcha</title>
<style>
body {
margin: 0;
background-color: aliceblue;
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
font-size: 10pt;
}
#guestbookForm form {
display: table;
margin: 0;
align-items: center;
font-size: 1.2em;
justify-items: center;
}
#guestbookForm field {
display: table-row;
margin: 4pt 4pt 4pt 4pt;
padding: 4pt 4pt 4pt 4pt;
}
#guestbookForm label {
display: table-cell;
height: auto;
vertical-align: middle;
font-size: 1.2em;
text-align: right;
padding-right: 0.2em;
}
#guestbookForm input, textarea {
display: table-cell;
border: 0.2em hsl(78, 75%, 51%) outset;
box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, .5);
border-radius: 0.4em;
padding: 0.5em 0.5em;
margin: 0.5em;
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
font-size: 1.2em;
resize: vertical;
min-height: 1.2em;
}
#guestbookForm input:focus, textarea:focus {
outline: none;
}
#guestbookForm div {
padding: 2pt;
}
#guestbookForm button {
font-size: 1.4em;
padding: 0.5em 1.5em;
margin: 2pt 3pt;
border-radius: 0.4em;
background-color: hsl(81, 75%, 51%);
}
.form-div {
margin: 5em auto;
width: fit-content;
height: fit-content;
align-self: center;
justify-self: center;
}
</style>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</head>
<body>
<div class="form-div">
<h1>Sample guestbooky input page</h1>
<!-- A form should be defined with the action pointing to the backend's message endpoint, where the POST with the message will be sent. -->
<form id="guestbookForm" action="http://example.guestbook.com/message" method="POST">
<field>
<label for="author">Name: </label>
<input type="text" id="author" placeholder="Please add your name!" cols="40" maxlength="128" minlength="1" required />
</field>
<field>
<label for="author">Message: </label>
<textarea id="message" placeholder="Please add your message!" cols="60" rows="6" maxlength="4096" minlength="1" required></textarea>
</field>
<!-- Cloudflare contains more data on how to further customize the captcha. The site key is also provided in the control panel. -->
<!-- Refer to https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/ for more options. -->
<!-- Once the challenge is executed, the data is sent to the hidden field in the form through the setCaptchaResponse callback defined in the script below. -->
<field>
<label></label>
<div class="cf-turnstile" data-sitekey="0x00000000000000000000000" data-callback="setCaptchaResponse"></div>
<input type="hidden" id="captchaResponse" name="captchaResponse" />
</field>
<field>
<label></label>
<button type="submit" value="Submit">Send</button>
</field>
</form>
</div>
<!-- Now, the script.
-> setCaptchaResponse(): callback from the turnstile to the hidden field
-> Event Listener: Listens to the submit event from the form, acquires the values and sends the POST request as structured JSON.
Once a response pops back we can check if it worked or not. This is rather crude just to get it working in a development setting.
Hopefully if this ever gets used it is tinkered with a bit.
-->
<script>
function setCaptchaResponse(token) {
document.getElementById("captchaResponse").value = token;
}
document
.getElementById("guestbookForm")
.addEventListener("submit", async function (e) {
e.preventDefault();
const author = document.getElementById("author").value;
const message = document.getElementById("message").value;
const captchaResponse = document.getElementById("captchaResponse").value;
const data = {
author,
message,
captchaResponse,
};
const dataJson = JSON.stringify(data);
2024-10-05 00:27:04 +02:00
const xhr = new XMLHttpRequest();
xhr.open("POST", this.action, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader('Content-Length', dataJson.length);
xhr.send(dataJson);
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status <= 299) {
alert("Message sent successfully.");
this.reset(); // Clear the form fields
} else {
alert("An error " + xhr.status + "occurred: " + xhr.responseText);
}
2024-10-05 00:27:04 +02:00
}
});
2024-10-05 00:27:04 +02:00
</script>
</body>
</html>