|
|
@@ -33,8 +33,23 @@ Handlebars.registerHelper('if_eq', function (a, opts) {
|
|
|
|
|
|
//### Initialisation
|
|
|
|
|
|
+
|
|
|
+// ************** CONFIGURATION *****************
|
|
|
+
|
|
|
+// Nom et version de la base de données locale à créer/utiliser
|
|
|
var db_name = "ModelePWA"
|
|
|
var db_version = "3"
|
|
|
+
|
|
|
+// Si deleteOnSuccess est vrai, les données synchronisées seront supprimées de la base locale.
|
|
|
+var deleteOnSync = true;
|
|
|
+
|
|
|
+// Les stores de la liste doNotSync ne seront pas synchronisés.
|
|
|
+var doNotSync = ["params"];
|
|
|
+
|
|
|
+var postUrl = "/api/modelepwa";
|
|
|
+
|
|
|
+// **********************************************
|
|
|
+
|
|
|
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;
|
|
|
var request;
|
|
|
|
|
|
@@ -48,19 +63,22 @@ var sectionId;
|
|
|
var section;
|
|
|
var objId;
|
|
|
|
|
|
+var submitHandler;
|
|
|
+var deleteHandler;
|
|
|
+var editHandler;
|
|
|
+
|
|
|
+// Charge la page en fonction de l'url actuelle
|
|
|
var load = function () {
|
|
|
- // Vide la section main
|
|
|
-
|
|
|
+
|
|
|
+ // Reinitialise l'affichage des sections
|
|
|
$("#sync").hide();
|
|
|
$("#main").empty();
|
|
|
$("#main").show();
|
|
|
|
|
|
- // Page en cours
|
|
|
+ // Parse l'url actuelle
|
|
|
var base = window.location.hash.split('?')[0];
|
|
|
sectionId = base.length > 0 ? base : "#index";
|
|
|
section = $("body").find(sectionId);
|
|
|
- console.log("Section: " + sectionId);
|
|
|
-
|
|
|
var qry = {};
|
|
|
var qrystr = window.location.hash.split('?')[1];
|
|
|
if (qrystr) {
|
|
|
@@ -70,54 +88,55 @@ var load = function () {
|
|
|
qry[parts[0]] = parts[1];
|
|
|
});
|
|
|
}
|
|
|
- console.log("Query: " + qry);
|
|
|
|
|
|
- // compile la section avec handlebars
|
|
|
+ // Met à jour le contenu de #main avec la section demandée dans l'url/
|
|
|
+
|
|
|
+ // Si l'attribut 'model' existe pour cette section, charge les données depuis la localDb
|
|
|
+ // et compile la section avec handlebars.
|
|
|
if ($(section).attr("model")) {
|
|
|
- var model = $(section).attr("model");
|
|
|
|
|
|
+ var model = $(section).attr("model");
|
|
|
var template = Handlebars.compile(section.html());
|
|
|
|
|
|
// Charge la base de données, et le stockage courant
|
|
|
- //var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;
|
|
|
request = indexedDB.open(db_name, db_version);
|
|
|
var db;
|
|
|
var txs;
|
|
|
var store;
|
|
|
+
|
|
|
|
|
|
// Cree les stockages necessaires si ceux ci sont manquants
|
|
|
request.onupgradeneeded = function () {
|
|
|
var db = request.result;
|
|
|
+
|
|
|
db.createObjectStore(model, { keyPath: "guid" });
|
|
|
console.log("[DB] Cree '" + model + "'");
|
|
|
};
|
|
|
|
|
|
+ // Si l'accès a la db s'est bien passé:
|
|
|
+
|
|
|
request.onsuccess = function () {
|
|
|
+ var data;
|
|
|
db = request.result;
|
|
|
txs = db.transaction(model, "readonly");
|
|
|
store = txs.objectStore(model);
|
|
|
|
|
|
- if (!qry["id"]) {
|
|
|
- store.getAll().onsuccess = function (event) {
|
|
|
- var data = { data: event.target.result };
|
|
|
- console.log(data);
|
|
|
+ // Si un id specifique a été demandé, on charge specifiquement cet objet.
|
|
|
+ // Sinon: on les charge tous en memoire.
|
|
|
+ if (qry["id"]) {
|
|
|
+ store.get(qry["id"]).onsuccess = function (event) {
|
|
|
+ data = { data: event.target.result };
|
|
|
$("#main").html(template(data));
|
|
|
- };
|
|
|
+
|
|
|
+ populateForm(data['data']);
|
|
|
+ }
|
|
|
}
|
|
|
else {
|
|
|
- store.get(qry["id"]).onsuccess = function (event) {
|
|
|
- var data = { data: event.target.result };
|
|
|
+ store.getAll().onsuccess = function (event) {
|
|
|
+ data = { data: event.target.result };
|
|
|
$("#main").html(template(data));
|
|
|
- $("input, select, textarea").each(function () {
|
|
|
- var input = $(this);
|
|
|
- var fieldName = input.attr('id');
|
|
|
- console.log(fieldName + ': ' + data['data'][fieldName]);
|
|
|
- input.val(data['data'][fieldName]);
|
|
|
- });
|
|
|
- }
|
|
|
+ };
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
};
|
|
|
|
|
|
request.onerror = function () {
|
|
|
@@ -126,10 +145,8 @@ var load = function () {
|
|
|
return;
|
|
|
};
|
|
|
|
|
|
- // Intercepte la soumision de formulaires
|
|
|
- $("#main").off("submit", "form");
|
|
|
- $("#main").on("submit", "form", function (event) {
|
|
|
- console.log("handle submit");
|
|
|
+ // (Re)définit la fonction d'interception de la soumission de formulaires
|
|
|
+ submitHandler = function (event) {
|
|
|
|
|
|
var form = $("#main").find("form")[0];
|
|
|
|
|
|
@@ -140,21 +157,14 @@ var load = function () {
|
|
|
var data = formToJSON(form.elements);
|
|
|
|
|
|
data.guid = createGuid();
|
|
|
- //data.tstamp = Date.now();
|
|
|
- data.user = localStorage.hasOwnProperty("params") ? JSON.parse(localStorage.getItem("params")).user : "(unknown)";
|
|
|
-
|
|
|
txs = db.transaction(model, "readwrite");
|
|
|
store = txs.objectStore(model);
|
|
|
store.put(data);
|
|
|
-
|
|
|
- store.getAll().onsuccess = function (event) {
|
|
|
- window.location = "";
|
|
|
- };
|
|
|
- });
|
|
|
|
|
|
- // Gere le clic sur un bouton supprimer
|
|
|
- $("#main").off("click", ".del");
|
|
|
- $("#main").on("click", ".del", function (event) {
|
|
|
+ };
|
|
|
+
|
|
|
+ // (Re)définit la fonction de suppression des lignes de l'index
|
|
|
+ deleteHandler = function(event) {
|
|
|
var del = $(this);
|
|
|
if (confirm("Supprimer la selection?") == true) {
|
|
|
|
|
|
@@ -172,11 +182,10 @@ var load = function () {
|
|
|
};
|
|
|
});
|
|
|
}
|
|
|
- });
|
|
|
+ };
|
|
|
|
|
|
- // Gere le clic sur un bouton editer
|
|
|
- $("#main").off("click", ".edit");
|
|
|
- $("#main").on("click", ".edit", function (event) {
|
|
|
+ // (Re)définit la fonction de suppression d'edition
|
|
|
+ editHandler = function(event) {
|
|
|
var edit = $(this);
|
|
|
|
|
|
var id = $(".ui-selected:first").data("id")
|
|
|
@@ -188,33 +197,55 @@ var load = function () {
|
|
|
obj.onsuccess = function (event) {
|
|
|
window.location = "/#activites?id=" + id;
|
|
|
};
|
|
|
-
|
|
|
- });
|
|
|
+ };
|
|
|
|
|
|
}
|
|
|
else {
|
|
|
- //template = Handlebars.compile(section.html());
|
|
|
- //$("#main").html(template({}));
|
|
|
+ // Pas de modele, on charge simplement le html de la section.
|
|
|
$("#main").html(section.html());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
load();
|
|
|
|
|
|
-
|
|
|
-
|
|
|
// Recharge dynamiquement le contenu HTML à chaque changement d'url
|
|
|
$(window).on('hashchange', function () {
|
|
|
- console.log("Trigger: hashchange");
|
|
|
load();
|
|
|
});
|
|
|
|
|
|
+// Met a jour le contenu des champs d'un formulaire
|
|
|
+// Le binbding se fait via l'id du champs
|
|
|
+var populateForm = function (data) {
|
|
|
+ if ($("form").length) {
|
|
|
+ $("input, select, textarea").each(function () {
|
|
|
+ var input = $(this);
|
|
|
+ var fieldName = input.attr('id');
|
|
|
+ input.val(data[fieldName]);
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
-// ############ MAIN ###############
|
|
|
+// ###########################
|
|
|
|
|
|
// ### Interactions
|
|
|
|
|
|
-// Affiche ou masque la sidebar
|
|
|
+// Intercepte la soumission de formulaires
|
|
|
+$("#main").on("submit", "form", function (event) {
|
|
|
+ submitHandler(event);
|
|
|
+ window.location = "/#index";
|
|
|
+});
|
|
|
+
|
|
|
+// Gere le clic sur un bouton Supprimer
|
|
|
+$("#main").on("click", ".del", function (event) {
|
|
|
+ deleteHandler(event);
|
|
|
+});
|
|
|
+
|
|
|
+// Gere le clic sur un bouton Editer
|
|
|
+$("#main").on("click", ".edit", function (event) {
|
|
|
+ editHandler(event);
|
|
|
+});
|
|
|
+
|
|
|
+// Gere le clic sur le bouton de menu pour afficher ou masquer la sidebar
|
|
|
$('.bt-menu').on('click', 'svg', function () {
|
|
|
$(this).closest('nav').find('div:not(:first)').toggleClass('sidebar');
|
|
|
});
|
|
|
@@ -222,7 +253,7 @@ $(document).on('click', '.sidebar', function () {
|
|
|
$(this).closest('nav').find('div:not(:first)').toggleClass('sidebar');
|
|
|
});
|
|
|
|
|
|
-// Affiche ou masque le bouton de sync
|
|
|
+// Affiche ou masque le bouton de sync selon que le poste est en ligne ou non
|
|
|
if (navigator.onLine) {
|
|
|
$(".start-sync").removeAttr("disabled");
|
|
|
}
|
|
|
@@ -232,18 +263,17 @@ else {
|
|
|
$(".start-sync").attr("disabled")
|
|
|
}
|
|
|
}
|
|
|
-/* retour haut de page*/
|
|
|
+
|
|
|
+// Affiche ou masque, et gere le clic sur le bouton de retour au haut de page.
|
|
|
window.onscroll = function (ev) {
|
|
|
document.getElementById("back-top").className =(window.pageYOffset > 100) ? "": "hidden";
|
|
|
};
|
|
|
-
|
|
|
$('#back-top').on('click', function () {
|
|
|
$('html, body').animate({ scrollTop: 0 }, 200);
|
|
|
});
|
|
|
|
|
|
// Rend les lignes des tables .selectable selectionnables
|
|
|
mo = new MutationObserver(function (mutations, observer) {
|
|
|
-
|
|
|
$(".selectable > tbody").bind("mousedown", function (e) {
|
|
|
e.metaKey = true;
|
|
|
}).selectable({
|
|
|
@@ -257,59 +287,71 @@ mo = new MutationObserver(function (mutations, observer) {
|
|
|
mo.observe(document.querySelector('#main'), { childList: true });
|
|
|
|
|
|
// ### Synchronisation des données
|
|
|
-
|
|
|
$(".start-sync").on("click", function () {
|
|
|
|
|
|
- infodiv = $("#sync")
|
|
|
+ // (!) voir en debut de fichier pour la configuration de la synchro (cf. les variables doNotSync et deleteOnSync)
|
|
|
|
|
|
+ // Affiche la page de synchro
|
|
|
+ $("#main").hide();
|
|
|
+ $("#sync").show();
|
|
|
+
|
|
|
+ // Verifie l'acces à la LocalDb
|
|
|
if (!request) {
|
|
|
request = indexedDB.open(db_name, db_version);
|
|
|
request.onerror = function () {
|
|
|
console.log("Error while accessing the db");
|
|
|
- infodiv.html("<p>Erreur de synchronisation: impossible d'accéder à la base de données locale.</p>");
|
|
|
+ $("#sync").find(".status").html("<p>Erreur de synchronisation: impossible d'accéder à la base de données locale.</p>");
|
|
|
return;
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- $("#main").hide();
|
|
|
- $("#sync").show();
|
|
|
-
|
|
|
var db = request.result;
|
|
|
- var txs = db.transaction("activites", "readonly");
|
|
|
- var stores = txs.objectStore("activites");
|
|
|
-
|
|
|
- console.log("post all");
|
|
|
- stores.openCursor().onsuccess = function (event) {
|
|
|
- var cursor = event.target.result;
|
|
|
- if (cursor) {
|
|
|
- $("#sync").find(".status").html("<p>Synchronisation en cours, veuillez patienter...</p>");
|
|
|
- cursor.value.model = "activites";
|
|
|
- var id = cursor.value.guid;
|
|
|
- var posting = $.post("/api/modelepwa", { data: JSON.stringify(cursor.value) });
|
|
|
-
|
|
|
- // Put the results in a div
|
|
|
- posting.done(function (data) {
|
|
|
- if (data == true) {
|
|
|
- var tx = db.transaction("activites", "readwrite");
|
|
|
- var store = tx.objectStore("activites");
|
|
|
- store.delete(id).onsuccess = function (evt) {
|
|
|
- };
|
|
|
- }
|
|
|
- });
|
|
|
- cursor.continue();
|
|
|
- }
|
|
|
- else {
|
|
|
- $("#sync").find(".status").html("<p>Synchronisation terminée.</p>");
|
|
|
- $("#sync").find(".end-sync").show();
|
|
|
+ $("#sync").find(".status").html("<p>Synchronisation en cours, veuillez patienter...</p>");
|
|
|
+ var model;
|
|
|
+
|
|
|
+ // Parcourt les differents stores
|
|
|
+ for (var i = 0; i < db.objectStoreNames.length; i++) {
|
|
|
+ model = db.objectStoreNames[i];
|
|
|
+
|
|
|
+ if (doNotSync.indexOf(model) >= 0) {
|
|
|
+ console.log("Ignored: " + model);
|
|
|
+ continue;
|
|
|
}
|
|
|
- };
|
|
|
|
|
|
- stores.openCursor().onerror = function (event) {
|
|
|
- $("#sync").find(".status").html("<p>Erreur de synchronisation: .</p>");
|
|
|
- console.log(event);
|
|
|
+ console.log("Sync: " + model);
|
|
|
+ var txs = db.transaction(model, "readonly");
|
|
|
+ var stores = txs.objectStore(model);
|
|
|
+
|
|
|
+ stores.openCursor().onsuccess = function (event) {
|
|
|
+ var cursor = event.target.result;
|
|
|
+ if (cursor) {
|
|
|
+
|
|
|
+ cursor.value.model = model;
|
|
|
+ var id = cursor.value.guid;
|
|
|
+ var posting = $.post(postUrl, { data: JSON.stringify(cursor.value) });
|
|
|
+
|
|
|
+ // Put the results in a div
|
|
|
+ posting.done(function (data) {
|
|
|
+ if (deleteOnSync & data) {
|
|
|
+ var tx = db.transaction(model, "readwrite");
|
|
|
+ var store = tx.objectStore(model);
|
|
|
+ store.delete(id).onsuccess = function (evt) {
|
|
|
+ };
|
|
|
+ }
|
|
|
+ });
|
|
|
+ cursor.continue();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ stores.openCursor().onerror = function (event) {
|
|
|
+ console.log(event);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-})
|
|
|
+ console.log("Synchro ok");
|
|
|
+ $("#sync").find(".end-sync").show();
|
|
|
+ $("#sync").find(".status").html("<p>Synchronisation terminée.</p>");
|
|
|
+});
|
|
|
|
|
|
$(".end-sync").click(function () {
|
|
|
load();
|