/*********************************************************** * * * 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 l'élément à activer * @param clearParam 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 de type
  • 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 += "" +sections[i].getAttribute('data-title')+ ""; else // pas les autres DOM.SUBSECTIONS.innerHTML += "" +sections[i].getAttribute('data-title')+ ""; } // 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 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 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 le formulaire cible * @param pHandler 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 * *
    * * * * * * *
    * * @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+NUM ouvre la section numéro "NUM" * * ctrl+droite ouvre la sous-section suivante * * ctrl+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'); }); sm.append('ctrl+1', function(){ selectSection( document.querySelector('#MENU span[data-link]:nth-child(2)') ); }); sm.append('ctrl+2', function(){ selectSection( document.querySelector('#MENU span[data-link]:nth-child(3)') ); }); sm.append('ctrl+3', function(){ selectSection( document.querySelector('#MENU span[data-link]:nth-child(4)') ); }); sm.append('ctrl+4', function(){ selectSection( document.querySelector('#MENU span[data-link]:nth-child(5)') ); }); sm.append('ctrl+5', function(){ selectSection( document.querySelector('#MENU span[data-link]:nth-child(6)') ); }); sm.append('ctrl+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('ctrl+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;; }