464 lines
16 KiB
JavaScript
Executable File
464 lines
16 KiB
JavaScript
Executable File
|
|
/***********************************************************
|
|
* *
|
|
* SCRIPT POST-HTML - SCRIPT PRINCIPAL *
|
|
* *
|
|
************************************************************
|
|
* *
|
|
* [0] Variables *
|
|
* [1] Gestionnaires de navigation *
|
|
* [a] pageManager.js *
|
|
* [b] API.js *
|
|
* [2] Gestion des liens *
|
|
* [a] catégories *
|
|
* [b] sous-parties *
|
|
* [3] Gestion de l'authentification *
|
|
* [4] Gestion des formulaires *
|
|
* [5] Gestion des SHORTCUTs *
|
|
* [6] Gestion des liens spécifiques *
|
|
* *
|
|
* *
|
|
* *
|
|
* *
|
|
* *
|
|
* *
|
|
* *
|
|
* *
|
|
* *
|
|
***********************************************************/
|
|
|
|
|
|
/* [0] VARIABLES
|
|
==============================================================*/
|
|
/* shortcut-manager */
|
|
var sm = new ShortcutManager();
|
|
|
|
/* pageManager */
|
|
var pageM;
|
|
/* API */
|
|
var API;
|
|
|
|
/* Structure de la page */
|
|
var DOM = {
|
|
DRAGNDROP : document.querySelector('#DRAGNDROP'),
|
|
WRAPPER : document.querySelector('#WRAPPER'),
|
|
MENU : document.querySelector('#MENU'),
|
|
CURRENTYEAR: document.querySelector('#MENU > #CURRENTYEAR'),
|
|
HEADER : document.querySelector('#HEADER'),
|
|
SUBHEADER : document.querySelector('#SUBHEADER'),
|
|
SUBSECTIONS : document.querySelector("#HEADER > nav.subsections"),
|
|
CONTAINER : document.querySelector('#CONTAINER'),
|
|
AUTH : document.querySelector('#AUTH'),
|
|
LOGOUT : document.querySelector('#HEADER #LOGOUT'),
|
|
NOTIFBTN : document.querySelector('#HEADER > .notifbar > .notification')
|
|
|
|
};
|
|
|
|
/* VRAI = utilisateur connecté */
|
|
var connected = !( DOM.AUTH.children[0].innerHTML == 'Connexion' );
|
|
|
|
|
|
/* [1] GESTIONNAIRES DE NAVIGATION
|
|
==============================================================*/
|
|
|
|
|
|
/* [a] pageManager.js
|
|
==============================================================*/
|
|
pageM = new pageManager(); // instance principale
|
|
|
|
/* initialisation du gestionnaire */
|
|
pageM.setPage(null, 'page', DOM.CONTAINER, ['home', 'groups', 'modules', 'career', 'settings'] );
|
|
|
|
/* ON REMPLACE "F5" par le rechargement manuel */
|
|
// window.addEventListener('keydown', function(e){
|
|
// if( e.keyCode == 116 ){ // F5
|
|
// e.preventDefault();
|
|
// reload();
|
|
// }
|
|
// }, false);
|
|
|
|
|
|
|
|
|
|
|
|
/* [b] API.js
|
|
==============================================================*/
|
|
API = new APIClass();
|
|
|
|
/* [c] gestion des classes
|
|
================================================*/
|
|
function addClass(el, pClass){
|
|
if( el.className.length > 0 && el.className != pClass ) el.className = el.className + ' ' + pClass;
|
|
else el.className = pClass;
|
|
}
|
|
|
|
function remClass(el, pClass){
|
|
if( el.className.indexOf(pClass) > -1 ) // si la class de l'élement contient la classe à enlever
|
|
el.className = el.className.substr(0, el.className.indexOf(pClass)) + '' + el.className.substr(el.className.indexOf(pClass)+pClass.length);
|
|
}
|
|
|
|
|
|
|
|
/* [2] GESTION DES LIENS
|
|
==============================================================*/
|
|
|
|
|
|
/* [a] CATÉGORIES
|
|
==============================================================*/
|
|
/* GESTION DES CATEGORIES (SECTIONS)
|
|
*
|
|
* @param section<Element> l'élément à activer
|
|
* @param clearParam<Boolean> VRAI si on doit supprimer les variables de l'URL
|
|
*
|
|
* [1] selectionne l'élément, l'affichage de la page associée est géré par pageManager.js
|
|
* [2] déselectionne l'élément précédemment selectioné
|
|
*
|
|
*/
|
|
function selectSection(section, clearParam){
|
|
|
|
// si la section est une string, on essaie de trouver l'élémnent associé
|
|
if( typeof section == 'string' )
|
|
section = document.querySelector('#MENU span[data-link='+section+']');
|
|
|
|
// si @subSection est un <Element> de type <li> qui a la propriété "data-link" [ET] section pas déjà active
|
|
if( section instanceof Element && section.tagName == 'SPAN' && section.dataset.hasOwnProperty('link') ){
|
|
|
|
if( clearParam === true ) // si clearParam est vrai
|
|
pageM.vars = new Array(pageM.vars[0]); // on efface les paramètres de l'URL
|
|
|
|
// on charge la page
|
|
pageM.setPage( section.dataset.link );
|
|
|
|
/* on active les sous-parties */
|
|
pageM.container.innerHTML = '';
|
|
pageM.container.style.background= 'url(../src/loader.gif) center center no-repeat';
|
|
pageM.container.style.backgroundSize= '2em auto';
|
|
pageM.xhr[pageM.xhr.length-1].addEventListener('load', function(){
|
|
|
|
// on récupère les sections du document
|
|
var sections = document.querySelectorAll('#CONTAINER section[name][data-title]');
|
|
if( sections != null ){ // si on en trouve
|
|
|
|
DOM.SUBSECTIONS.innerHTML = ""; // on efface le #SUBHEADER > nav <=> les liens des sous-parties
|
|
|
|
for( var i = 0 ; i < sections.length ; i++ ) // pour chaque section, on créé un lien correspondant
|
|
if( i == 0 ) // on active le premier
|
|
DOM.SUBSECTIONS.innerHTML += "<span data-sectname='" +sections[i].getAttribute('name')+ "' class='active'>" +sections[i].getAttribute('data-title')+ "</span>";
|
|
else // pas les autres
|
|
DOM.SUBSECTIONS.innerHTML += "<span data-sectname='" +sections[i].getAttribute('name')+ "'>" +sections[i].getAttribute('data-title')+ "</span>";
|
|
}
|
|
|
|
// si dans pageManager.js, on a une sous-partie et qu'elle existe physiquement
|
|
var selectedSubSectionFromURL = document.querySelector('#HEADER > nav.subsections > span[data-sectname='+pageM.vars[0]+']');
|
|
|
|
if( selectedSubSectionFromURL != null ) // si on trouve, on charge la sous-partie
|
|
selectSubSection( selectedSubSectionFromURL );
|
|
else // sinon, on selectionne celle définie dans le HTML
|
|
selectSubSection( document.querySelector('#HEADER > nav.subsections > span.active') );
|
|
|
|
}, false);
|
|
|
|
|
|
// on récupère la section déja selectionnée si elle existe
|
|
var last = document.querySelector('#MENU span.active');
|
|
|
|
if( last != null ) // si une section est déjà activée
|
|
remClass(last, 'active'); // on désactive la courante
|
|
|
|
addClass(section, 'active'); // on active @section
|
|
|
|
}else // sinon on affiche l'erreur
|
|
console.log("[selectSection_Error] - ("+section+")");
|
|
|
|
}
|
|
|
|
// permet de recharger la page courante
|
|
function reload(){ selectSection(pageM.page); }
|
|
|
|
/* activation au chargement en fonction de la page courante de pageManager.js */
|
|
var lastSection = document.querySelector('#MENU span[data-link='+pageM.page+']');
|
|
if( lastSection != null )
|
|
selectSection(lastSection); // on l'active
|
|
|
|
/* Gestion des liens du menu */
|
|
DOM.MENU.addEventListener('click', function(e){ selectSection( e.target, true); }, false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* [b] SOUS-PARTIES
|
|
==============================================================*/
|
|
/* GESTION DES SOUS-PARTIES (SOUS-CATÉGORIES)
|
|
*
|
|
* @param subSection<Element> l'élément à activer
|
|
*
|
|
* [1] selectionne l'élément, l'affichage de la page associée est géré en CSS3
|
|
* [2] déselectionne l'élément précédemment selectioné
|
|
*
|
|
*/
|
|
function selectSubSection(subSection){
|
|
|
|
// si la subSection est une string, on essaie de trouver l'élémnent associé
|
|
if( typeof subSection == 'string' )
|
|
subSection = document.querySelector('#HEADER > nav.subsections > span[data-sectname='+subSection+']');
|
|
|
|
// si @subSection est un <Element> de type HGROUP [ET]
|
|
if( subSection instanceof Element && subSection.tagName == 'SPAN' && subSection.dataset.hasOwnProperty('sectname') ){
|
|
|
|
// on essaie de récupérer l'ancien "lien"
|
|
var lastActive = document.querySelector('#HEADER > nav.subsections > span.active');
|
|
if( lastActive != null ) // si on a trouvé qqch
|
|
remClass(lastActive, 'active'); // on le désactive
|
|
|
|
// on essaie de récupérer l'ancienne section active
|
|
var lastSection = document.querySelector('#CONTAINER section.active');
|
|
if( lastSection != null ) // si on a trouvé qqch
|
|
remClass(lastSection, 'active'); // on la désactive
|
|
|
|
// on active la page associée
|
|
var target = document.querySelector('#CONTAINER section[name='+subSection.dataset.sectname+'][data-title]');
|
|
if( target != null )
|
|
addClass(target, 'active');
|
|
|
|
// on définit la sous-page de pageManager.js
|
|
pageM.vars[0] = subSection.dataset.sectname;
|
|
pageM.updateURL();
|
|
|
|
addClass(subSection, 'active'); // on active @subSection
|
|
}
|
|
|
|
}
|
|
|
|
/* gestion du clic sur les sous-parties */
|
|
DOM.SUBSECTIONS.addEventListener('click', function(e){ selectSubSection(e.target); }, false);
|
|
|
|
|
|
|
|
/* [3] GESTION DE L'AUTHENTIFICATION
|
|
==============================================================*/
|
|
|
|
// ferme l'interface d'authentification quand clic autre part que sur zone AUTH
|
|
DOM.WRAPPER.addEventListener('mousedown', function(e){ remClass(DOM.WRAPPER, 'blurred'); }, false);
|
|
|
|
|
|
|
|
// ouvre l'interface d'authentification quand click sur bouton prévu à cet effet
|
|
DOM.LOGOUT.addEventListener('mouseup', function(e){ addClass(DOM.WRAPPER, 'blurred'); DOM.AUTH.children[1].focus(); }, false);
|
|
|
|
if( !connected ) // sur zone verte si pas connecté
|
|
DOM.MENU.children[0].addEventListener('mouseup', function(e){ addClass(DOM.WRAPPER, 'blurred'); DOM.AUTH.children[1].focus(); }, false);
|
|
|
|
else // sinon amène sur le profil
|
|
DOM.MENU.children[0].addEventListener('mouseup', function(e){
|
|
pageM.vars[0] = 'myprofile';
|
|
selectSection( document.querySelector('#MENU > span[data-link=settings]') );
|
|
}, false);
|
|
|
|
|
|
|
|
|
|
|
|
/* [4] GESTION DES FORMULAIRES
|
|
==============================================================*/
|
|
/* INITIALISE UN FORMULAIRE POUR QU'IL INTERPRETE UN OBJET LORS DE SA SOUMISSIONS
|
|
*
|
|
* @param pForm<Element> le formulaire cible
|
|
* @param pHandler<Function> fonction exécutée lors de la soumission du formulaire
|
|
*
|
|
* [1] parcourt les élements du formulaire @pForm et active un évènement lors du "submit"
|
|
* [2] retourne l'objet à @pHandler lors du "submit"
|
|
*
|
|
*
|
|
* @example
|
|
*
|
|
* <form id='nomFormulaire'>
|
|
*
|
|
* <input type='text' name='nomDuChamp1' value='valeurDuChamp1'>
|
|
* <input type='mail' name='nomduChamp2' value='valeurDuChamp2'>
|
|
*
|
|
* <input type='submit' value='VALIDER'>
|
|
*
|
|
* </form>
|
|
*
|
|
* @explaination
|
|
*
|
|
* Lors du clic sur le bouton [VALIDER], la fonction @pHandler s'exécutera avec pour paramètre un objet
|
|
* OBJ{ id: nomFormulaire, nomDuChamp1: valeurDuChamp1, nomDuChamp2: valeurDuChamp2 }
|
|
*
|
|
*/
|
|
function initForm(pForm, pHandler){
|
|
|
|
// vérification des arguments
|
|
var isForm = pForm instanceof Element && pForm.tagName == 'FORM';
|
|
var isFunc = pHandler instanceof Function;
|
|
|
|
// si les arguments sont corrects
|
|
if( pForm instanceof Element && pForm.tagName == 'FORM' ){
|
|
|
|
var submitButton = null; // contiendra le bouton d'envoi du formulaire
|
|
|
|
for( var i = 0 ; i < pForm.children.length ; i++ )
|
|
if( pForm.children[i].type == 'button' ){
|
|
submitButton = pForm.children[i]; // on définit le bouton
|
|
break; // on sort du for
|
|
}
|
|
|
|
// on définit l'évènement de validation du formulaie
|
|
function submitEvent(){
|
|
|
|
var obj = {} // on créé l'objet qui va être envoyé
|
|
|
|
for( var i = 0 ; i < pForm.children.length ; i++ ) // on parcourt les enfants
|
|
if( pForm.children[i].tagName == 'INPUT' && pForm.children[i].type != 'button' ) // si c'est un champ et que c'est pas le bouton
|
|
obj[pForm.children[i].name] = pForm.children[i].value; // alors on enregistre le champ dans l'objet
|
|
|
|
// on exécute la fonction @pHandler en lui envoyant les arguments
|
|
pHandler(obj);
|
|
|
|
}
|
|
|
|
// on définit l'évènement du clic sur le bouton
|
|
submitButton.addEventListener('click', function(e){
|
|
submitEvent(e.target.parentNode); // on envoie le formulaire
|
|
}, false);
|
|
|
|
// on définit l'évènement de l'appui sur la touche [ENTRER]
|
|
pForm.addEventListener('keydown', function(e){
|
|
if(e.keyCode==13) submitEvent(e.target); // si c'est la bonne touche, on submit le formulaire
|
|
}, false);
|
|
|
|
|
|
|
|
}else
|
|
console.log('[initForm_Error] - ('+pForm+', '+pHandler+')');
|
|
|
|
|
|
}
|
|
|
|
|
|
initForm( // initialisation du formulaire de connection
|
|
DOM.AUTH, // formulaire (élément DOM)
|
|
function(request){ // handler
|
|
// ajout d'informations à la requête
|
|
request.level_0 = 'user';
|
|
request.level_1 = (connected) ? 'exit' : 'authentification';
|
|
|
|
API.send(request, function(response){
|
|
if( response.request == 'success' )// si connection ok
|
|
document.location = '';
|
|
else
|
|
document.querySelector('#AUTH .errorbox').innerHTML = 'Identifiants incorrects.';
|
|
});
|
|
}
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
/* [5] Gestion des SHORTCUTs
|
|
==============================================================*/
|
|
/* LISTE DES RACCOURCIS
|
|
*
|
|
* ctrl+alt+n ouvre les notifications
|
|
*
|
|
* ctrl+alt+e ouvre l'interface de connection/déconnection
|
|
*
|
|
* ctrl+alt+NUM ouvre la section numéro "NUM"
|
|
*
|
|
* alt+haut ouvre la section suivante
|
|
* alt+bas ouvre la section précédente
|
|
*
|
|
* alt+droite ouvre la sous-section suivante
|
|
* alt+gauche ouvre la sous-section précédente
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
sm.append('ctrl+alt+n', function(){
|
|
pageM.vars[0] = 'notifications';
|
|
selectSection( document.querySelector('#MENU > span[data-link=home]') );
|
|
});
|
|
|
|
sm.append('ctrl+alt+e', function(){
|
|
addClass(DOM.WRAPPER, 'blurred');
|
|
DOM.AUTH.children[1].focus();
|
|
});
|
|
|
|
sm.append('alt+up', function(){// on récupère la section courante
|
|
var cSection = document.querySelector('#MENU span[data-link='+pageM.page+']');
|
|
if( cSection != null ){ // si on a trouvé la section
|
|
var parentChildren = cSection.parentNode.children;
|
|
var prevIndex = parentChildren.indexOf( cSection ) - 1;
|
|
|
|
// si il y a une section avant, on la charge
|
|
if( prevIndex > 0 )
|
|
selectSection( parentChildren[prevIndex] );
|
|
}
|
|
});
|
|
|
|
|
|
|
|
sm.append('alt+down', function(){// on récupère la section courante
|
|
var cSection = document.querySelector('#MENU span[data-link='+pageM.page+']');
|
|
if( cSection != null ){ // si on a trouvé la section
|
|
var parentChildren = cSection.parentNode.children;
|
|
var nextIndex = parentChildren.indexOf( cSection ) + 1;
|
|
|
|
// si il y a une section après, on la charge
|
|
if( nextIndex < parentChildren.length )
|
|
selectSection( parentChildren[nextIndex] );
|
|
}
|
|
});
|
|
|
|
|
|
sm.append('alt+right', function(){
|
|
// on récupère la sous-section courante
|
|
var cSubSection = document.querySelector('#HEADER > nav.subsections > span[data-sectname='+pageM.vars[0]+']');
|
|
if( cSubSection != null ){ // si on a trouvé la sous-section
|
|
var parentChildren = cSubSection.parentNode.children;
|
|
var nextIndex = parentChildren.indexOf( cSubSection ) + 1;
|
|
|
|
// si il y a une section après, on la charge
|
|
if( nextIndex < parentChildren.length )
|
|
selectSubSection( parentChildren[nextIndex] );
|
|
}
|
|
});
|
|
|
|
sm.append('alt+left', function(){
|
|
// on récupère la sous-section courante
|
|
var cSubSection = document.querySelector('#HEADER > nav.subsections > span[data-sectname='+pageM.vars[0]+']');
|
|
if( cSubSection != null ){ // si on a trouvé la sous-section
|
|
var parentChildren = cSubSection.parentNode.children;
|
|
var prevIndex = parentChildren.indexOf( cSubSection ) - 1;
|
|
|
|
// si il y a une section avant, on la charge
|
|
if( prevIndex >= 0 )
|
|
selectSubSection( parentChildren[prevIndex] );
|
|
}
|
|
});
|
|
|
|
// on active les raccourcis
|
|
sm.listen();
|
|
|
|
|
|
/* [6] GESTION DES LIENS SPÉCIFIQUES
|
|
==============================================================*/
|
|
if( DOM.NOTIFBTN != null )
|
|
DOM.NOTIFBTN.addEventListener('click', function(e){
|
|
pageM.vars[0] = 'notifications';
|
|
selectSection( document.querySelector('#MENU > span[data-link=home]') );
|
|
}, false);
|
|
|
|
|
|
// modification de l'année scolaire en cours
|
|
function updateCurrentYear(y){
|
|
y = parseInt(y);
|
|
|
|
var anneeScolaire = y+' - '+(y+1);
|
|
|
|
DOM.CURRENTYEAR.children[1].innerHTML = anneeScolaire;;
|
|
} |