FrameBeurk File
Fmbk/Module/Beurk/_js/moduleBeurk.js.php
//FrameBeurk V0.65 Copyright ToolOscope 2016. Licence CeCILL-C.
// Javascript associé au module Beurk
// rend visible une div qui était en display:none; et fait défiler la page jusqu'à sa position
function beurk_afficheDiv(divName) {
if (myDiv = document.getElementById(divName)) {
myDiv.style.display='';
data_div = '';
if (myDiv.hasAttribute("data-div"))
data_div = myDiv.getAttribute("data-div");
if (data_div == 'PopUp') { // c'est une PopUp, on active le masque
document.getElementById("popupBackground").style.display='';
} else if (data_div != 'inPopUp') { // on désactive le masque SAUF si la div est déclarée comme faisant partie d'une PopUp
document.getElementById("popupBackground").style.display='none';
}
if (data_div == 'PopUp' || divName == DIV_VUE_PAGE) // c'est une PopUp ou la vue principale, on scrolle
// myDiv.scrollIntoView();
zenpa_declencheDefilement(myDiv);
}
}
//cache la div dont le nom est passé en paramètre
function beurk_cacheDiv(divName) {
if (myDiv = document.getElementById(divName)) {
//la div est la vue principale : reinit => on fait un back dans l'historique (cas du bouton Annuler si pas d'amélioration)
if (myDiv.getAttribute("data-div") == 'Vue') {
//back à implémenter
// div à faire disparaitre
} else {
myDiv.style.display='none';
if (myDiv.getAttribute("data-div") == 'PopUp')
document.getElementById("popupBackground").style.display='none';
<?php echo $CONFIG['Module']['Beurk']['Fonctions']['ApresCacheDiv']; ?>(); // fonction post-cache
}
} else {
alert(sprintf("<?php echo Beurk_traduit("L'élément '%%s' n'existe pas.", 'Beurk'); ?>", divName));
}
}
//cache la div dont le nom est stocké en attribut data-cache
function beurk_cache(element, evt) {
if (element.hasAttribute("data-cache")) {
tabData = element.getAttribute("data-cache").split("/"); // extraction du nom de la div à cacher
if (tabData[0])
divName = tabData[0];
beurk_cacheDiv(divName);
}
}
// formatte l'URL de la vue. ATTENTION : en cas de réécriture d'URL, clefURL doit être ordonné comme défini dans la config
function beurk_UrlVue(clefURL, estAjax, DivVue) {
url = URL_PATH; // pas de http:// pour accepter aussi le https
if (typeof estAjax === "undefined")
estAjax = false;
var radicalUrl = '';
if (URL_REWRITING) {
radicalUrl = '/' + clefURL.ActVue + '-' + clefURL.IdVue;
for (var nom in clefURL)
if (nom != 'ActVue' && nom != 'IdVue')
radicalUrl += '/' + encodeURIComponent(clefURL[nom]);
if (estAjax)
url += '/Ajax' + ((typeof DivVue === "undefined") ? '' : ('-' + DivVue));
url += radicalUrl;
} else {
for (var nom in clefURL)
radicalUrl += '&' + encodeURIComponent(nom) + '=' + encodeURIComponent(clefURL[nom]);
radicalUrl = '?' + radicalUrl.substr(1); // supprime le '&' initial
url += '/index.php' + radicalUrl;
if (estAjax && ! (typeof DivVue === "undefined"))
url += '&DivVue=' + DivVue;
}
return url;
}
// ---------------------------------------- gestion de requetes Ajax ----------------------------------------------
// variables globales
var NAV_HISTORIQUE = false; // true si on navigue par l'historique, false sinon
var BEURK_PARAMS_FORM = []; // tableau contenant les données du form, y compris le contenu des fichiers à uploader
var BEURK_NB_FILES_FORM; // nombre de fichiers à uploader : la requête post est envoyée lorsque ce compteur retombe à 0
var BEURK_POST_URL; // url du form envoyé en méthode POST
var BEURK_POST_ENCTYPE; // enctype " " " "
// ajoute un Listener qui prend en charge la navigation par Ajax dans l'historique des pages
window.addEventListener("popstate", function(event) {
if (event.state) { // si c'est une vue chargée par ajax
NAV_HISTORIQUE = true; // réinit pour empêcher AjaxRetour() de re-pusher la requête précédente
beurk_ajaxAllerGET(event.state.canonical_url_ajax);
// return false; ?
}
// sinon, vue chargée classiquement : Rien à faire -le navigateur le gère
});
function beurk_creeRequeteAjax() {
var httpRequest = false;
if (window.XMLHttpRequest) { // tout sauf IE
httpRequest = new XMLHttpRequest();
if (httpRequest.overrideMimeType) {
httpRequest.overrideMimeType('text/xml');
}
} else if (window.ActiveXObject) { // IE
try {
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (! httpRequest) {
alert("<?php echo Beurk_traduit('Abandon : Impossible de créer une instance XMLHTTP', 'Beurk'); ?>");
return false;
} else {
return httpRequest;
}
}
//envoie d'une requete en GET
function beurk_ajaxAllerGET(url, fonctionRetour) {
//si fonctionRetour n'est pas passé en paramètre, c'est beurk_ajaxRetour qui sera appelé
fonctionRetour = (typeof fonctionRetour === "undefined") ? "beurk_ajaxRetour" : fonctionRetour;
var httpRequest = false;
if (httpRequest = beurk_creeRequeteAjax()) {
httpRequest.onreadystatechange = function() { window[fonctionRetour](httpRequest); };
httpRequest.open('GET', url, true);
httpRequest.setRequestHeader('X-Requested-With','XMLHttpRequest');
httpRequest.setRequestHeader('charset', 'utf-8'); // 'windows-1252'
httpRequest.send(null);
<?php echo $CONFIG['Module']['Beurk']['Fonctions']['InitAffichageAjax']; ?>(); // initialisation de l'affichage lors de l'envoi d'une requête Ajax
}
}
//envoie d'une requete en POST, BEURK_PARAMS_FORM est un tableau assocatif du type ['nom' => 'valeur', ]
function beurk_ajaxAllerPOST() {
// si tous les fichiers ont été uploadé (asynchrone)
if (BEURK_NB_FILES_FORM == 0) {
BEURK_NB_FILES_FORM = -1;
//création de la requête
if (httpRequest = beurk_creeRequeteAjax()) {
httpRequest.onreadystatechange = function() { beurk_ajaxRetour(httpRequest); };
httpRequest.open('POST', BEURK_POST_URL, true);
httpRequest.setRequestHeader('X-Requested-With','XMLHttpRequest');
httpRequest.setRequestHeader('charset', 'utf-8'); // 'windows-1252'
// si form à envoyer en urlencoded
if (BEURK_POST_ENCTYPE == 'application/x-www-form-urlencoded') {
if (window.FormData === undefined ) { // vieux browser :(
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var parametres = '';
var first = true;
for (var myparamName in BEURK_PARAMS_FORM) { //boucle sur tous les éléments du form à envoyer
if (first == false)
parametres += '&';
parametres += encodeURIComponent(myparamName) + '=' + encodeURIComponent(BEURK_PARAMS_FORM[myparamName]);
first = false;
}
httpRequest.setRequestHeader('Content-length', parametres.length);
httpRequest.send(parametres);
} else { // browser cool :)
var formData = new FormData();
for (var myparamName in BEURK_PARAMS_FORM)
formData.append(myparamName, BEURK_PARAMS_FORM[myparamName]);
httpRequest.send(formData); // multipart/form-data
}
// si form à envoyer en multi-part (upload de fichier)
} else if (BEURK_POST_ENCTYPE == 'multipart/form-data') {
if (window.FormData === undefined ) { // vieux browser :(
alert(sprintf("<?php echo Beurk_traduit("Upload de fichier disponible sur navigateur HTML5 (ex: IE>=10)", 'Beurk'); ?>", BEURK_POST_ENCTYPE));
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var parametres = '';
var first = true;
for (var myparamName in BEURK_PARAMS_FORM) {
if (BEURK_PARAMS_FORM[myparamName].type != 'file') {
if (parametres != '')
parametres += '&';
parametres += encodeURIComponent(myparamName) + '=' + encodeURIComponent(BEURK_PARAMS_FORM[myparamName]);
}
}
httpRequest.setRequestHeader('Content-length', parametres.length);
httpRequest.send(parametres);
} else { // browser cool :)
var formData = new FormData();
for (var myparamName in BEURK_PARAMS_FORM) {
if (BEURK_PARAMS_FORM[myparamName].type == 'file' && BEURK_PARAMS_FORM[myparamName].files.length > 0) { // il y a des fichiers à uploader
for (noFichier = 0; noFichier < BEURK_PARAMS_FORM[myparamName].files.length; noFichier++) {
formData.append(BEURK_PARAMS_FORM[myparamName].name, BEURK_PARAMS_FORM[myparamName].files[noFichier]);
}
} else // autre champ
formData.append(myparamName, BEURK_PARAMS_FORM[myparamName]);
}
}
httpRequest.send(formData);
} else {
alert(sprintf("<?php echo Beurk_traduit("Méthode d'encryption '%%s' inconnue", 'Beurk'); ?>", BEURK_POST_ENCTYPE));
}
<?php echo $CONFIG['Module']['Beurk']['Fonctions']['InitAffichageAjax']; ?>(); // initialisation de l'affichage lors de l'envoi d'une requête Ajax
}
}
}
//gestion du XML retourné par la requête
function beurk_ajaxRetour(httpRequest) {
// try {
if (httpRequest.readyState == 4) {
if (httpRequest.status == 200) {
var xmldoc = httpRequest.responseXML;
//extraction du nom de la div à mettre à jour
if (nomDivAModifier = beurk_texteNoeudXml(xmldoc, 'aModifier')) {
//extraction du contenu de la div à mettre à jour
if (contenuDiv = beurk_texteNoeudXml(xmldoc, nomDivAModifier)) {
//mise à jour de la div
if (document.getElementById(nomDivAModifier))
document.getElementById(nomDivAModifier).innerHTML = contenuDiv;
//si le nom de la div est le même que celle qui contient la Vue : mise à jour de la navigation
if (nomDivAModifier == DIV_VUE_PAGE) {
titrePage = beurk_texteNoeudXml(xmldoc, 'TitrePage');
document.title = titrePage;
canonical_url = beurk_texteNoeudXml(xmldoc, 'canonical_url');
canonical_url = canonical_url.replace(/&/g,'&');
canonical_url_ajax = beurk_texteNoeudXml(xmldoc, 'canonical_url_ajax');
canonical_url_ajax = canonical_url_ajax.replace(/&/g,'&');
if (history && history.pushState && ! NAV_HISTORIQUE) { //si NAV_HISTORIQUE, on a fait back/forward : on ne repushe pas.
if (! history.state || history.state.canonical_url_ajax != canonical_url_ajax) { // nouvelle URL
history.pushState({'canonical_url_ajax':canonical_url_ajax}, titrePage, canonical_url); // ajoute l'URL (sans Ajax) à l'historique et stocke l'adresse AVEC ajax pour navigation
} else {
history.replaceState({'canonical_url_ajax':canonical_url_ajax}, titrePage, canonical_url); // où cas où quelquechose ait changé (ex : le titre)
}
}
}
}
// traitement standart
<?php echo $CONFIG['Module']['Beurk']['Fonctions']['RetourAjax']; ?>(xmldoc, nomDivAModifier);
}
//extraction de la redirection de la page complète
if (redirectionPage = beurk_texteNoeudXml(xmldoc, 'redirectionPage')) {
//chargement de la nouvelle page au bout de 4 secondes
setTimeout('document.location.assign("' + redirectionPage + '");', 4000);
}
} else {
alert(sprintf("<?php echo Beurk_traduit('Erreur status (%%s) : %%s', 'Beurk'); ?>", httpRequest.status, httpRequest.statusText));
}
}
/* }
catch(e) {
alert(sprintf("<?php echo Beurk_traduit("Une exception s'est produite : %%s - %%s", 'Beurk'); ?>", e.description, httpRequest.responseText));
} */
}
//renvoie le texte contenu dans le noeud ou '' si non trouvé
function beurk_texteNoeudXml(xmldoc, nodeName) {
myResult = '';
if (myItem = xmldoc.getElementsByTagName(nodeName).item(0)) {
if (myItem.hasChildNodes()) {
//rem : Firefox découpe les noeuds > 4K en plusieurs
for (var i=0; i < myItem.childNodes.length; i++) {
myResult += myItem.childNodes[i].nodeValue;
}
}
}
return myResult;
}
//demande de chargement d'une div par Ajax (ne change pas l'historique des pages)
function beurk_chargeDivAjax(DivVue, clefURL) {
beurk_afficheDiv(DivVue);
<?php echo $CONFIG['Module']['Beurk']['Fonctions']['AfficheChargement']; ?>(DivVue);
NAV_HISTORIQUE = false;
beurk_ajaxAllerGET(beurk_UrlVue(clefURL, true, DivVue));
}
//charge un formulaire dans le tableau BEURK_PARAMS_FORM, pour envoi par Ajax
//si c'est pour une prévisualisation, on n'envoie pas ActMaj ni IdMaj (ni *Aff), pour ne pas déclencher les actions/vues
function beurk_formEnParametres(myform, topPrevisu) {
var myFileReader;
BEURK_NB_FILES_FORM = 1; // pour bloquer l'envoi du form tant que cette fonction n'est pas terminée
BEURK_PARAMS_FORM = []; // init du tableau des éléments du form
for (i = 0; i < myform.elements.length ; i++) {
myType = myform.elements[i].type;
myInputName = myform.elements[i].name;
if (myType == 'text' || myType == 'textarea' || myType == 'hidden' || myType == 'password' || myType == 'hidden') {
if ((topPrevisu == false) || (myInputName != 'ActMaj' && myInputName != 'IdMaj'
&& myInputName != 'ActVue' && myInputName != 'IdVue' && myInputName != 'DivVue' && myInputName != 'JetonAct'
&& myInputName != 'ActVueErr' && myInputName != 'EntVueErr' && myInputName != 'IdVueErr' && myInputName != 'DivVueErr')) {
if (myInputName == 'JetonAct') {
BEURK_PARAMS_FORM[myInputName] = JETON_AJAX;
} else {
BEURK_PARAMS_FORM[myInputName] = myform.elements[myInputName].value;
}
}
} else if (myType == 'select-one' || myType == 'select-multiple') { //ne gère pas le multiple !!!
if (myInputName != 'BBstyle' && myInputName != 'BBcolor' && myInputName != 'BBinsere' && myInputName != 'BBlangue')
BEURK_PARAMS_FORM[myInputName] = myform.elements[myInputName].options[myform.elements[myInputName].selectedIndex].value;
} else if (myType == 'checkbox') {
if (myform.elements[myInputName].checked == true)
BEURK_PARAMS_FORM[myInputName] = myform.elements[myInputName].value;
} else if (myType == 'radio') { // à tester !!!
var myRadio = myform.elements[myInputName];
for (j = 0; j < myRadio.length ; j++) {
if (myRadio[j].checked = true)
BEURK_PARAMS_FORM[myInputName] = myRadio[j].value;
}
} else if (myType == 'file') {
var myFichier = myform.elements[myInputName];
BEURK_PARAMS_FORM[myInputName] = myFichier;
//lancement du chargement des fichiers en asynchrone
if (topPrevisu == false && myFichier.files.length > 0) {
for (noFichier = 0; noFichier < myFichier.files.length; noFichier++) {
if (myFichier.files[noFichier].name.length > 0) {
BEURK_NB_FILES_FORM++; // 1 fichier de plus à charger
myFileReader = new FileReader();
myFileReader.inputName = myInputName; // stockage en custom properties du nom de l'input
myFileReader.noFichier = noFichier; // et du numéro de fichier
myFileReader.onload = integreFichier;
myFileReader.readAsBinaryString(myFichier.files[noFichier]);
}
}
}
} // incomplet : A compléter !!!
}
BEURK_NB_FILES_FORM--;
}
// déclenché à la fin du chargement asynchrone d'un fichier
function integreFichier (myFileReaderEvent) {
BEURK_PARAMS_FORM[this.inputName].files[this.noFichier].binary = myFileReaderEvent.target.result;
BEURK_NB_FILES_FORM--; // 1 fichier de moins à charger
beurk_ajaxAllerPOST();
}
// ------------------------------------------- améliorations par attributs data ----------------------------------------------
// fonction appelée au chargement du document ou d'une nouvelle div.
// ajoute un évènement onclick sur les éléments ayant un attribut relié à une fonction dans $CONFIG
function beurk_ameliorationBalises(divModifiee) {
var elements = divModifiee.getElementsByTagName("*"); // tous les éléments de la div
for (var i = 0; i < elements.length; i++) {
<?php // tissage des fonctions associées aux data-attributes
foreach($CONFIG['Module']['Beurk']['Attributs'] as $attribut => $tabEvenements) {
foreach($tabEvenements as $evenement => $fonction) {
?>
if (elements[i].hasAttribute("<?php echo $attribut; ?>"))
elements[i].<?php echo $evenement; ?> = function(evt) { return <?php echo $fonction; ?>(this, evt); };
<?php } } ?>
}
}
//remplace le chargement de la page index.php par une requete http
// - l'attribut data-ajax est de la forme <DivVueChargement>/<DivVue>/<DivVueErr>
// - au moins 1 div est obligatoire
// - le mot-clé 'Page' est pour la vue principale
function beurk_lienAmeliore(element, evt) {
// empêche la propagation de l'évènement pour prévenir l'éxécution de kom1_basculeAffichageEtCharge()
// pour le cas où le lien data-div est inclus dans un élément portant l'attribut data-basculeCharge
if (! evt)
var evt = window.event;
evt.cancelBubble = true;
if (evt.stopPropagation) evt.stopPropagation();
if (element.hasAttribute("data-ajax")) {
typeElement = element.nodeName.toLowerCase();
// détermination des div cibles
DivVueChargement = '';
DivVue = '';
DivVueErr = '';
tabData = element.getAttribute("data-ajax").split("/"); // extraction de la div d'affichage (OK)
if (tabData[0])
DivVueChargement = tabData[0]; // div où afficher le message de chargement
if (tabData[1])
DivVue = tabData[1]; // div d'affichage
if (tabData[2])
DivVueErr = tabData[2]; // div d'affichage en cas d'erreur action
if (DivVueChargement == 'Page')
DivVueChargement = DIV_VUE_PAGE;
if (DivVue == 'Page')
DivVue = DIV_VUE_PAGE;
if (DivVue == '') // par défaut
DivVue = DivVueChargement;
if (DivVueErr == 'Page')
DivVueErr = DIV_VUE_PAGE;
// récupération de l'url "normale"
if (typeElement == "a") {
url = element.href;
} else if (typeElement == "input") {
url = element.form.action;
}
// calcul de la nouvelle URL Ajax
baseUrl = URL_PATH;
lng = baseUrl.length;
posloc = url.indexOf(baseUrl);
if (URL_REWRITING) {
url = url.substr(0, posloc + lng) + '/Ajax-' + DivVue + url.substr(posloc + lng); //insère /Ajax-<DivVue>
if (DivVueErr != '' && ((posSiErr = url.indexOf('/SiErreur/')) >= 0)) {
url = url.substr(0, posSiErr) + '/SiErreur-' + DivVueErr + url.substr(posSiErr + 9); // insère -<DivVueErr> après /SiErreur
}
} else {
url = url + ((url.indexOf('?') >= 0) ? '&' : '?') + "DivVue=" + DivVue;
if (DivVueErr != '')
url = url + "&DivVueErr=" + DivVueErr;
}
if (typeElement == "a") {
url = beurk_majJetonUrl(url); // met à jour le jeton avec la dernière valeur envoyée
beurk_ajaxAllerGET(url);
} else if (typeElement == "input") {
beurk_formEnParametres(element.form, false); // beurk_formEnParametres met aussi à jour le jeton
BEURK_POST_ENCTYPE = element.form.enctype;
BEURK_POST_URL = url;
beurk_ajaxAllerPOST();
}
// chargement de la div
beurk_afficheDiv(DivVueChargement);
<?php echo $CONFIG['Module']['Beurk']['Fonctions']['AfficheChargement']; ?>(DivVueChargement);
NAV_HISTORIQUE = false;
return false; // pour inhiber le href
}
return true; // si pas d'attribut ajax
}
// met à jour le jeton dans l'url du lien ou dans l'input du form
function beurk_majJetonAction(element, evt) {
typeElement = element.nodeName.toLowerCase();
if (typeElement == "a") { // si l'élément est un lien
element.href = beurk_majJetonUrl(element.href);
} else if (typeElement == "input" || typeElement == "select") { // si l'élément est une balise input ou un select
element.form.elements["JetonAct"].value = JETON_AJAX;
}
return true;
}
// met à jour le jeton et soumet le form
function beurk_soumetForm(element, evt) {
beurk_majJetonAction(element, evt);
element.form.submit();
}
// renvoie l'url en paramètre avec le JetonAct mis à jour avec la dernière valeur envoyée (par Ajax)
function beurk_majJetonUrl(url) {
if (JETON_AJAX != '') {
if (URL_REWRITING) {
var posloc = url.indexOf('/MAJ-');
if (posloc > 0) {
posloc += 5;
var debut = url.substring(0, posloc);
var fin = url.substring(posloc);
fin = fin.substring(fin.indexOf('/'));
// alert(url + ' => ' + debut + JETON_AJAX + fin);
return debut + JETON_AJAX + fin;
}
} else {
var posloc = url.indexOf('JetonAct=');
if (posloc > 0) {
posloc += 9;
var debut = url.substring(0, posloc);
var tmp = url.substring(posloc);
posloc = tmp.indexOf('&');
var fin = (posloc > 0) ? tmp.substring(posloc) : '';
// alert(url + ' => ' + debut + JETON_AJAX + fin);
return debut + JETON_AJAX + fin;
}
}
}
return url; // rien à changer
}
// renvoie un jeton aléatoire
function beurk_jeton() {
return (Math.random() + 1).toString(36).substring(2) + (Math.random() + 1).toString(36).substring(2);
}
// fonction utilisée pour le debugging
function beurk_dump(obj) {
var out = '';
for (var i in obj) {
out += i + ": ";
try {
out += obj[i];
} catch(e) {
out += "???";
}
out += "\n";
}
alert(typeof obj + ' ' + out);
}
// emprunt à https://gist.github.com/flesch/315070
function sprintf(){
var args = Array.prototype.slice.call(arguments);
return args.shift().replace(/%s/g, function(){
return args.shift();
});
}