If you are lucky enough to be reading this article in the future and this website is actually finished you may be shocked to know that I actually began to write a publish articles while it was still under development. While I would not recommend that in a business environment, as this website was more for my own development and experience it didn’t matter.
One of the first
I had was the anger at finishing an article and having it have taken so long that I had been logged out, and the entire contents lost. One of the second things I learnt was how frustrating it can be to lose an article you’ve been writing because you accidentally closed the tab, hit the back button on your fancy and very sensitive 5 button mouse or just closed the window because you’re an idiot. Thankfully those issues had solutions.
First of all, having a timeout on your website is a good idea for security, or rather a better statement would be, logging out idle users is a good idea. For my first site, Diamond Dust, I had the genius idea of setting the expiry time of the cookie an hour into the future. However at no point did that cookie update, so even if you came back to the site and used it within that hour, you would suddenly be logged out. Similarly when I re-designed my login/user account system I had an idle timeout – again something that isn’t a bad thing, provided it is a suitable time. I found 30 minutes is too short; if you like to waffle on and it may take you more than 30 minutes to write a post then when you hit submit you’re gonna have a bad time, I find an hour – maybe 2, is a good benchmark.
As for the actual code, I stuck this bit in my Main Script, which is something loaded on every page, which in effect means whenever you navigate through pages, you extend your idle timeout.
session_start();
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 3600)) {
// last request was more than 1 hour ago
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
and once you expire the 1 hour time period you will be logged out as soon as you navigate away from the page, which will include form submissions. While this probably isn’t best for security, it does okay for small blog sites like this. My original design was the same, except that I had a separate cookie logging the last activity, and set the expiry time of those cookies ahead 1 hour depending on whether or not the user was not ‘idle’.
As for the second part, the main issue with using the back buttons, close button or close window is that they’re unexpected events, i.e I wouldn’t imagine you could server-side script something to prevent it. I did consider the idea of committing the form to the database periodically but as it turned out there was a much simpler solution. JQuery.
I had done some basic JavaScript in the past so I thought it might be time to move on up a bit. JQuery on the whole is very similar to JavaScript, binding events to an element on a page and having that execute your code to the desired effect while acting client-side provides a much smoother experience for your user, rather than reloading the page when you want something to happen. For this particular issue, I wanted to prevent the user navigating away from a page when they had started to edit it, thankfully I imagine there are a lot of devs out there as ham fisted as I am, and the question had been asked to death on stack overflow.
Eventually the solution I settled on was this
$(document).ready(function() {
formmodified=0;
$('#ArticleForm *').keypress(function(){
formmodified=1;
console.log('form modified');
});
window.onbeforeunload = confirmExit;
function confirmExit() {
if (formmodified == 1) {
return "New information not saved. Do you wish to leave the page?";
}
}
$("input[name='btnSubmitPost']").click(function() {
formmodified = 0;
});
});
The first part is the document ready, which is triggered as soon as the page is loaded. This function binds 3 events and creates 1 function. The events are as follows
1) Keep track of any change in the form with ID=”ArticleForm” and sets a variable
2) On Window OnBeforeUnload run function confirmExit
3) On pressing button name=”btnSubmitPost” set a variable.
The Function “confirmExit” simply checks the global variable “formmodified” and if it is set to 1 the form has been modified. If not, it hasn’t.
Tips I learned here. When making a JQuery call, the designation you give to an element may have a preceding symbol as in the below examples
<form id="FancyForm">
<input class="FreeTextBox" type="textbox" />
<input type="submit" value="submit" />
</form>
<script>
// To reference an id
$('#FancyForm').change(function() { //etc...});
//To reference a class
$('.FreeTextBox').keypress(function() { //etc...});
//To reference a html element
$('input').click(function() { //etc...});
</script>
Obviously you may wish to apply stuff to one, some or all elements on your page so I guess this allows you to be a bit more creative with your solutions.
In the code I used I had the following:
$('#ArticleForm *').keypress(function(){ //etc... });
Which applied the defined function to every keypress done inside a form element with ID “ArticleForm”
Which meant when trying to navigate away from the page I got a nice alert box asking if I was sure.
I still have a great deal to learn about JQuery, but I’m quickly learning its use in more user experience roles rather than functionality. Either way, at least I was able to create this post in one go this time…
Leave a Reply