Hey all,
Before today, I’ve never really worked with AJAX, XML HTTP Requests, readyStates, form submissions, etc. And before a month or two ago, my Javascript knowledge was pretty abysmal. I’m learning a lot but the tutorials aren’t cutting it—I need a little help!
I’m working on a new portfolio and I have a case study which needs to be password protected. I’ve created a ‘guest’ user and modified the Kirby cookbook for authentication to allow people to access the case study. The username field is pre-filled and hidden on the front-end, so only the password is needed. With the controller I have, this all works fine.
What I would like to do now is:
- If the password is incorrect, display an error message below the input, without page refresh.
- If the password is correct, display a success message below the input, and then redirect to the unlocked page (same URL) after a timeout. (The template already checks whether a user is logged in, so this shouldn’t require any extra authentication.)
I think I’m pretty close, but there are gaps in my understanding of how all the bits communicate with each other, so I’m working in the dark. Anyone who can shine a light would be much appreciated
Please excuse any rookie mistakes below
Also, I’m not using jQuery on this project, so vanilla JS only please!
// Login panel (embedded on templates/project.php,
// if the project is marked as requiring a password and
// no user is logged in)
<form id="protected" method="post">
<input type="hidden" id="username" name="username" value="guest">
<div class="password-submit">
<label for="password">Passphrase</label>
<div class="password-input-wrapper">
<?php snippet('icons/lock') ?>
<input type="text" id="password" name="password" maxlength="48" placeholder="Welcome to the truth">
</div>
</div>
<div class="message"><?php if($message) echo $message ?></div>
<input class="visually-hidden" type="submit" name="login" value="Go">
</form>
// templates/project.json.php
<?php echo json_encode($response);
// submit.js
var form = document.getElementById('protected')
if (form.addEventListener) {
form.addEventListener('submit', handlePasswordSubmit, false)
} else if (form.attachEvent) {
form.attachEvent('onsubmit', handlePasswordSubmit)
}
function handlePasswordSubmit (e) {
e.preventDefault()
var form = document.getElementById('protected')
var url = form.action + '.json'
var usernameField = document.getElementById('username')
var passwordField = document.getElementById('password')
var usernameText = usernameField.value
var passwordText = passwordField.value
var xhr = new XMLHttpRequest()
xhr.open('POST', url, true)
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
xhr.send({
username: usernameText,
password: passwordText
})
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
// Check if password is a match: if no, insert
// error message text into .message div
// If yes, insert success message
// into .message div and redirect after 4000ms
} else {
// If the server fails, I think - what would be the cause of this?
// What error should be displayed to the user?
console.log('Something went wrong. Please try again.')
}
}
}
}
// controllers/project.php
<?php
return function($site, $pages, $page) {
if(r::is('post') and get('login')) {
$invalidMessage = 'Incorrect passphrase. Try again, and be sure to include spaces.';
$successMessage = 'Correct! Redirecting…';
if($user = $site->user(get('username')) and $user->login(get('password'))) {
$message = $successMessage;
return;
} else {
$message = $invalidMessage;
}
// If the username is constant, do I need to include it?
// Does the message go into this array, or should it be elsewhere?
$response = array(
'username' => get('username'),
'password' => get('password'),
'message' => $message
);
}
return $response;
};