Make your website available offline with a submit fallback

HTML5 Logo

A website with form available offline and the data entered when sending back online, that can be done by HTML5 i.c.m. Javascript! To make the page available offline, you can use the default cache methods. Disadvantage is that when you load the page again once you do get an error page. Better use a cache manifest (works in all browsers and unfortunately, as usual, again not in Internet Explorer). A sample page with a form (index.php) whose content is simply a text file written:

<?php
//Form "gesubmit"?
if($_POST)
{
	//Velden scheiden door een komma en achteraan data.txt toevoegen
	file_put_contents('data.txt', implode(', ',$_POST)."\n", FILE_APPEND);

	//Pagina opnieuw laden
	header('Location: index.php');
}
?>
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Pagina naam</title>
</head>
<body>

	<form method="post" action="">

		<input type="text" name="inputname1" />
		<input type="text" name="inputname2" />

		<input type="submit" value="Opslaan!" />

	</form>

	<p>Data:</p>
	<hr />
	<?php
	//Gegevens ophalen uit data.txt, om XSS te voorkomen door htmlspecialchars halen en als laatste middels nl2br ervoor zorgen dat de "enters" ofwel nieuwe lijnen/regels zichtbaar zijn.
	echo nl2br(htmlspecialchars(file_get_contents('data.txt')));
	?>

</body>
</html>

Manifest bestand

A cache manifest to add, Simply replace the html tag:

<html manifest="manifest.php">

The cache manifest make (manifest.php):

CACHE MANIFEST
index.php

And ready! The page is now offline (provided they have once visited). Drawback now is that when the page (or data.txt changed), let's say that there is an input field to, this is not always visible because the page is loaded from cache. When the page is re-picked? Only if the manifest file has changed. So we make sure that the manifest file changed as index.php data.txt and change by example md5 hash of the file to create, once or index.php data.txt changed that hash will also change. Let's put a little commentary with that hash.

CACHE MANIFEST
index.php
# data.txt md5 hash: <?=md5_file('data.txt');?>
# index.php md5 hash: <?=md5_file('index.php');?>

Localstorage als cache

Top! Problem solved! But if we form “submitten” when offline will not happen much. What are the options for data temporarily in the visitor to store? Cookies! Beautiful but much data we can not lose. WebSQL, has limited support and like to read W3C no longer developed. IndexedDB, unfortunately limited support. Do we local storage over! Is even supported by Internet Explorer (8+)! In… the code! Let us for convenience jQuery load up first and submit the form (when offline) capture and stop the data in local storage:

<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script type="text/javascript">
	//Naamloze functie maken
	(function()
	{
		//Form gesubmit?
		$('form').submit(function()
		{
			//Offline?
			if( ! navigator.onLine )
			{
				//De bezoeker vertellen wat er gebeurd
				alert('Je bent niet verbonden met het internet, de gegevens worden tijdelijk lokaal opgeslagen tot je weer verbonden bent met het internet.')

				//Nieuw item met alle ingevoerde gegevens uit het form aan localstorage toevoegen
				localStorage.setItem(new Date().getTime(), $(this).serialize() );

				//Alle ingevoerde velden leeg maken
				$('input[type=text]').val('');

				//Zorgen dat het form niet echt gesubmit wordt
				return false;
			}
		});

	//Naamloze functie direct uitvoeren
	})();
</script>

Then we need to ensure that when something in localStorage is this the next time sent. Given all this javascript using ajax and we are going to do first “ajax handling script” make, save.php:

<?php
if($_POST){
	//Index echo'en zodat we deze kunnen verwijderen uit localstorage
	echo $_POST['index'];
	unset($_POST['index']);
	file_put_contents('data.txt', implode(', ',$_POST)."\n", FILE_APPEND);
}
?>

And again with javascript:

//Online?
if( navigator.onLine )
{
	//Zijn er items in localstorage?
	if(localStorage.length)
	{
		//Door alle items in localstorage "loopen"
		for(var i in localStorage)
		{
			//Item versturen naar save.php
			$.ajax({
				url: 'save.php',
				data: 'index=' + i + '&' + localStorage.getItem(i),
				type: 'POST',
				success: function(data){
					//Wanneer succesvol verzonden verwijderen uit localstorage
					localStorage.removeItem(data);
				}
			});
		}
	}
}

And ready! But as you may have noticed that your first page twice again to leave before the cache is overwritten. To solve this problem, a small “hotfix” of “hack” to the so called:

//Manifest bestand veranderd? (en dus index.php of data.txt)
window.applicationCache.addEventListener('updateready', function(e)
{
	if (window.applicationCache.status == window.applicationCache.UPDATEREADY)
	{
		//Cash verwijderen en nieuwe items laden
		window.applicationCache.swapCache();

		//Pagina opnieuw laden
		window.location.reload();
	}
}, false);

Best fun this! Where can you apply this? It is very useful for mobile websites, sometimes happens that the visitor does not have internet and that the internet is slow (hope that it will be faster with 4G). Then it is so easy that the site can be visited and the entered data are processed!

Click here for an online demo

Tagged with: , , , , , , , ,
Posted in Tips & Tricks