Travailler hors ligne avec Google Gears (3/3)

Javascript/AJAX Ajouter un commentaire

Dernier volet de cet article sur Google Gears. Nous avons vu dans la partie précédente le socle de l’application, c’est-à-dire la mise en place du cache pour le mode déconnecté. Nous verrons dans cette partie comment sauvegarder les données dans la base SQLite en mode hors ligne et comment synchroniser les données lors de la reconnexion.

Sauvegarder les données du formulaire

Je l’avais évoqué lors du premier article : utiliser un framework JS facilitera la vie pour certaines fonctionnalités. On va donc ajouter une petite couche de Prototype pour deux raisons : récupérer les données du formulaire qu’on stockera dans la base, et envoyer les données via AJAX lors d’une reconnexion.

Pour commencer, une ligne supplémentaire dans le HTML :

<script src="prototype.js" type="text/javascript"></script>

Ensuite, on va déclarer prototype.js dans le fichier de manifeste qui ressemblera donc en version finale à ceci :

{
	"betaManifestVersion": 1,
	"version": "1.0.0",
	"entries": [
		{ "url": "prototype.js"},
		{ "url": "gears_init.js"},
		{ "url": "index.html"},
		{ "url": "sondage.js"},
		{ "url": "sondage.css"}
	]
}

Il est nécessaire d’initialiser la base de données locale, on ajoute un petit botu de code pour créer la base et la table au début de la fonction Sondage.init dans sondage.js :

if (Sondage.db == null) {
	Sondage.db = google.gears.factory.create("beta.database");
		Sondage.db.open('sondage');
	Sondage.db.execute('CREATE TABLE IF NOT EXISTS sondage' +
				' (id INTEGER PRIMARY KEY, temp_form TEXT)');
}

On ajoute une fonction Sondage.saveForm qui sera appelé depuis le bouton Sauver du formulaire. Le HTML donne donc :

<input name="save" value="Sauver" onclick="return Sondage.saveForm($('myform'));" type="button" />

La fonction saveForm dans sondage.js gère deux cas, celui du en ligne ou hors ligne.
En mode connecté, la fonction soumet directement le formulaire. En mode hors ligne, il gère la sauvegarde dans la base de données en y stockant le contenu du formulaire, sous forme d’une chaine prête à être passée en requête HTTP via la méthode POST (a=1&b=2&c=3&…). On a donc :

Sondage.saveForm = function(form)
{
	if (navigator.onLine) {
		Sondage.setMessage('Sauvegarde des données. Veuillez patienter...', 'message');
		form.submit();
	} else {
		Sondage.setMessage('Sauvegarde locale des données. Veuillez patienter...', 'message');
		var q = Form.serializeElements(Form.Methods.getElements('myform'));
 
		Sondage.db.execute('BEGIN');
		Sondage.db.execute('INSERT INTO sondage (temp_form) VALUES (?)', [q]);
		Sondage.db.execute('COMMIT');
 
		Sondage.setMessage('Données suvegardées. Elles seront transmises lors de la prochaine synchronisation', 'message');
	}
 
	return false;
};

Synchronisation hors ligne vers en ligne

Nos données sont donc sauvées en mode déconnecté. Regardons maintenant comment envoyer ces données lors de la reconnexion.

Définissons la logique de synchronisation, à l’aide d’une fonction Sondage.synchronize(). Il s’agit dans notre cas de simplement requêter la base de données à l’aide d’un SELECT, de récupérer la chaine sérialisée dans chaque enregistrement, et de “simuler” l’envoi du formulaire vers save.php en l’appelant via AJAX.

La fonction nous donne donc :

Sondage.synchronize = function()
{
	if (!navigator.onLine) {
		return;
	}
 
	// Récupération d'un ResultSet avec les données
	var rs = Sondage.db.execute('SELECT id, temp_form FROM sondage');
 
	// Calcul du nb de records à envoyer
	while (rs.isValidRow()) {
		var id = rs.field(0);
		var postData = rs.field(1);
 
		// Postage des données avec une requête AJAX
		new Ajax.Request('save.php', {
			parameters: postData
		});
 
		// Suppression de l'enregistrement
		Sondage.db.execute('DELETE FROM sondage WHERE id = ?', [id]);
 
		rs.next();
	}
 
	Sondage.setMessage('Données synchronisées.', 'message');
};

Il suffit pour cela de vérifier si le navigateur est en ligne à intervalles réguliers et appeler la fonction Sondage.synchronize(). On ajoute pour cela un petit window.setTimeout à la fin de Sondage.init() :

window.setTimeout(Sondage.synchronize, 1000);

Leave a Reply

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in