Ajout des raccourcis clavier et suppression de données inutiles (loader+php vars dans <input:hidden>)

This commit is contained in:
xdrm-brackets 2015-12-02 20:12:34 +01:00
parent f6d40ff903
commit b24b81866b
11 changed files with 234 additions and 245 deletions

2
API.js
View File

@ -51,7 +51,7 @@ APIClass.prototype = {
if( ptrAPI.xhr[i].readyState == 4 ){ // si la requête est terminée if( ptrAPI.xhr[i].readyState == 4 ){ // si la requête est terminée
/* DEBUG : affiche la réponse BRUTE de API.php */ /* DEBUG : affiche la réponse BRUTE de API.php */
// console.log('API.php => '+ptrAPI.xhr[i].responseText); console.log('API.php => '+ptrAPI.xhr[i].responseText);
console.log( JSON.parse(ptrAPI.xhr[i].responseText) ); console.log( JSON.parse(ptrAPI.xhr[i].responseText) );
/* si success de requête */ /* si success de requête */

View File

@ -62,31 +62,6 @@ body{
} }
#LOADER{
/* position */
display: block;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 2px;
/* background */
background-color: #22d135;
/* z axis */
z-index: 100;
/* animation */
transition: all .2s ease-in-out;
-moz-transition: all .2s ease-in-out;
-webkit-transition: all .2s ease-in-out;
-ms-transition: all .2s ease-in-out;
-o-transition: all .2s ease-in-out;
}
#WRAPPER{ #WRAPPER{
/* position */ /* position */
display: block; display: block;

View File

@ -28,25 +28,14 @@ $notifNotifNum = 5;
<!-- Dépendences Javascript --> <!-- Dépendences Javascript -->
<script type='text/javascript' src='API.js' ></script> <!-- Gestion des dialogues client/serveur --> <script type='text/javascript' src='js/adjust.js' ></script> <!-- Gestion des ajouts Javascript -->
<script type='text/javascript' src='js/pageManager.js' ></script> <!-- Gestion réseau/chargement/lient --> <script type='text/javascript' src='API.js' ></script> <!-- Gestion des dialogues client/serveur -->
<script type='text/javascript' src='js/shortcut.js' ></script> <!-- Gestion des raccourcis clavier --> <script type='text/javascript' src='js/pageManager.js' ></script> <!-- Gestion réseau/chargement/lient -->
<script type='text/javascript' src='js/loader.js' ></script> <!-- Gestion du loader --> <script type='text/javascript' src='js/shortcut-manager.js' ></script> <!-- Gestion des raccourcis clavier -->
</head> </head>
<body class='trHoverActivated_'><!-- CORPS DE LA PAGE --> <body class='trHoverActivated_'><!-- CORPS DE LA PAGE -->
<?php
if( $_SESSION['identifiant'] != null ){
echo "<input type='hidden' name='identifiant' value='".$_SESSION['identifiant']."'>";
echo "<input type='hidden' name='semestre' value='".$_SESSION['semestre']."' >";
echo "<input type='hidden' name='annee' value='".$_SESSION['annee']."' >";
}
?>
<div id='LOADER'></div>
<div id='WRAPPER'> <div id='WRAPPER'>
<!-- MENU DE LA PAGE --> <!-- MENU DE LA PAGE -->

View File

@ -30,9 +30,8 @@
/* [0] VARIABLES /* [0] VARIABLES
==============================================================*/ ==============================================================*/
/* Loader */ /* shortcut-manager */
var l = Loader.prototype.getInstance( document.getElementById('LOADER') ); var sm = new ShortcutManager();
/* pageManager */ /* pageManager */
var pageM; var pageM;
@ -203,7 +202,7 @@ var connected = !( DOM.AUTH.children[0].innerHTML == 'Connexion' );
// si la subSection est une string, on essaie de trouver l'élémnent associé // si la subSection est une string, on essaie de trouver l'élémnent associé
if( typeof subSection == 'string' ) if( typeof subSection == 'string' )
subSection = document.querySelector('#HEADER > nav.subsection > span[data-sectname='+subSection+']'); subSection = document.querySelector('#HEADER > nav.subsections > span[data-sectname='+subSection+']');
// si @subSection est un <Element> de type HGROUP [ET] // si @subSection est un <Element> de type HGROUP [ET]
if( subSection instanceof Element && subSection.tagName == 'SPAN' && subSection.dataset.hasOwnProperty('sectname') ){ if( subSection instanceof Element && subSection.tagName == 'SPAN' && subSection.dataset.hasOwnProperty('sectname') ){
@ -365,25 +364,76 @@ initForm( // initialisation du formulaire de connection
* *
* ctrl+alt+n ouvre les notifications * ctrl+alt+n ouvre les notifications
* *
* ctrl+alt+l ouvre l'interface de connection/déconnection * 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
* *
* *
* *
* *
*/ */
// Shortcut('ctrl+alt+n', function(){ sm.append('ctrl+alt+n', function(){
// pageM.vars[0] = 'notifications'; pageM.vars[0] = 'notifications';
// selectSection( document.querySelector('#MENU > span[data-link=home]') ); selectSection( document.querySelector('#MENU > span[data-link=home]') );
// }); });
Shortcut('ctrl+alt+e', function(){ sm.append('ctrl+alt+e', function(){
addClass(DOM.WRAPPER, 'blurred'); 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 /* [6] GESTION DES LIENS SPÉCIFIQUES
==============================================================*/ ==============================================================*/

9
js/adjust.js Normal file
View File

@ -0,0 +1,9 @@
// on définit le "indexOf" pour <HTMLCollection> et <NodeList>
NodeList.prototype.indexOf = HTMLCollection.prototype.indexOf = function(searchedElement){
for( var i = 0 ; i < this.length ; i++ ) // on parcours la collection
// si on trouve l'élement, on retourne son rang
if( this[i] == searchedElement ) return i;
// si on a rien trouvé, on retourne -1
return -1;
};

View File

@ -1,20 +0,0 @@
function Loader(element){ this.element = element; };
Loader.prototype = {
instance: null, // instance Singleton
element: this.element, // contiendra l'élément loader
value: 0, // contiendra le pourcentage de chargement
update: function(){ this.value = (this.value>=100)?100:this.value; this.element.style.width = this.value+'%'; },
start: function(){ this.value = 0; this.update(); },
inc: function(v){ this.value += (v)?v:10; this.update(); },
stop: function(){ this.value = 100; this.update(); },
getInstance: function(element){
if( Loader.prototype.instance == null ) Loader.prototype.instance = new Loader(element);
return Loader.prototype.instance;
}
};

126
js/shortcut-manager.js Executable file
View File

@ -0,0 +1,126 @@
/**************/
/* PRÉ-REQUIS */
/**************/
/* Retourne le keyCode correspondant à la chaîne donnée
*
* @param str enchaînement de touches sous forme de string
*
*
* return keyCode le code de la touche correspondante
*/
function strToKeyCode(keyString){
// on enregistre le keyCode du premier caractère
var keyCode = keyString.toUpperCase().charCodeAt(0);
// s'il s'agit d'un caractère uniquement (entre "a" et "z" ou entre "0" et "9")
if( keyString.length == 1 && ((keyCode >= 65 && keyCode <= 90) || (keyCode >= 49 && keyCode <= 57)) )
return keyCode; // on retourne le keyCode associé
else
switch( keyString ){ // sinon, on récupère l'ascii spécifiquement
case 'ctrl': return 17; break;
case 'maj': return 16; break;
case 'alt': return 18; break;
case 'tab': return 9; break;
case 'left': return 37; break;
case 'top': return 38; break;
case 'right': return 39; break;
case 'down': return 40; break;
}
return null;
}
/**********/
/* CLASSE */
/**********/
function ShortcutManager(){};
ShortcutManager.prototype = {
shortcuts: [], // contiendra tous les raccourcis
progress: [], // contiendra l'avancée des raccourcis
handlers: [], // contiendra tous les handlers (fonctions à éxécuter)
/* tmp */
lastKeyCode: [], // contiendra des "reminder" pour les évènements
/* ajout d'un nouveau raccourcis clavier */
append: function(keyRow, handler){
/* [1] On découpe la chaîne (en minuscule) par "+"
=======================================================*/
var keyStore = keyRow.toLowerCase().split('+');
/* [2] On récupère les keyCodes correspondant aux codes/lettres
=======================================================*/
for( var i = 0 ; i < keyStore.length ; i++ ){
keyStore[i] = strToKeyCode( keyStore[i] );
// si on a une erreur, on retourne NULL
if( keyStore[i] == null ) return null;
}
/* [3] On enregistre dans l'objet (shortcuts, progress, handler)
=======================================================*/
var index = this.shortcuts.push( keyStore ) - 1;
this.progress[index] = 0; // le progrès est l'index d'avancement
this.handlers[index] = handler; // handler (function qui s'éxécutera lors de l'activation)
this.lastKeyCode[index] = null; //
},
/* remet à zéro tous les progrès */
resetProgress: function(keyCode){
for( var i = 0 ; i < this.progress.length ; i++ )
if( this.lastKeyCode[i] != keyCode )
this.progress[i] = 0;
},
/* démarre l'écoute (active les évènements) */
listen: function(){
/* [1] On créé l'évènement d'appui de touche pour chaque élément
=======================================================*/
var pointer = this;
// on initialise/créer l'évènement
window.addEventListener('keydown', function(e){
for( var i = 0 ; i < pointer.shortcuts.length ; i++ ){
// si on a la bonne touche, on incrémente l'avancement / sinon si on c'est une touche différente, on remet à 0
if( e.keyCode == pointer.shortcuts[i][pointer.progress[i]] )
pointer.progress[i] += 1;
else if( e.keyCode != pointer.lastKeyCode[i] )
pointer.progress[i] = 0;
pointer.lastKeyCode[i] == e.keyCode;
// si on a terminé la combinaison de touches, on remet le compteur à 0 + on exécute le handler
if( pointer.progress[i] == pointer.shortcuts[i].length ){
pointer.progress[i] = 0;
pointer.handlers[i](e);
}
}
}, false);
// si on lâche une touche, on remet à zéro
window.addEventListener('keyup', function(e){
pointer.resetProgress( e.keyCode );
}, false);
}
};

View File

@ -1,146 +0,0 @@
/* Retourne le keyCode correspondant à la chaîne
*
* @param keyStore enchaînement de touches sous forme de string
* @param handler function qui s'éxécute lors du raccourci
*
* return keyCode le code de la touche correspondante
*/
function strToKeyCode(str){
// on enregistre le keyCode du premier caractère
var keyCode = str.toUpperCase().charCodeAt(0);
// s'il s'agit d'un caractère uniquement (entre "a" et "z")
if( str.length == 1 && keyCode >= 65 && keyCode <= 90 )
return keyCode; // on retourne le keyCode associé
else
switch( str ){
case 'ctrl': return 17; break;
case 'maj': return 16; break;
case 'alt': return 18; break;
case 'tab': return 9; break;
}
return null;
}
var shortcutList = []; // contient les combinaisons de touches
var shortcutStep = []; // contient l'avancée d'un raccourcis
/* Gestion des raccourcis claviers
*
* @param keyStore enchaînement de touches sous forme de string
* @param handler function qui s'éxécute lors du raccourci
*
*/
function Shortcut(keyStore, handler){
var splittedString = keyStore.toLowerCase().split('+'), // découpe la chaîne (en minuscule) par "+"
splittedKeyCode = new Array(); // contiendra les keyCode de chaque touche
// pour chaque touche, on récupère le keyCode
for( var i = 0 ; i < splittedString.length ; i++ )
splittedKeyCode[i] = strToKeyCode( splittedString[i] ); // on enregistre le keyCode correspondant
// on ajout à la liste globale
eventIndex = shortcutList.length;
shortcutList.push( splittedKeyCode );
// on initialise l'avancement
shortcutStep[eventIndex] = 0;
// creation de la fonction d'évènement
shortcutList[eventIndex].push( function(e, k, f, h){ /* k<keyCode> ; f<eventIndex> ; h<handler()> */
// console.log(f);
// on cherche l'avancée
var step = shortcutStep[f];
// on regarde si la touche est bonne
if( shortcutList[f][step] == k ){ // si c'est la touche suivante
if( step >= shortcutList[f].length-2 ){ // si c'était la dernière touche
// on initialise le tableau
for( var i = 0 ; i < shortcutStep[f].length ; i++ )
shortcutStep[f][i] = 0;
// console.log('ok');
e.preventDefault();
h(); // EXECUTION DE : handler();
}else // sinon on incrémente l'avancée
shortcutStep[f]++;
}else // si c'est pas la bonne touche, on réinitialise le tableau
shortcutStep[f] = 0;
});
// création de l'évènement
window.addEventListener(
'keydown',
function(e){ shortcutList[eventIndex][shortcutList[eventIndex].length-1](e, e.keyCode, eventIndex, handler); },
false
);
}
/* quand on lâche une touche, tout les raccourcis s'effacent */
window.addEventListener('keyup', function(){
for( var i = 0 ; i < shortcutStep.length ; i++ )
shortcutStep[i] = 0;
}, false);
/*** UTILISATION ***/
// Shortcut(
// 'ctrl+s',
// function(){ alert('sauvegardé'); }
// );
//

View File

@ -929,6 +929,9 @@ class DataBase{
/***********************************************************/ /***********************************************************/
public function getNotesForControleEnseignant($enseignant, $annee, $controle, $groupe=null){ // [OPTIONNEL] $groupe public function getNotesForControleEnseignant($enseignant, $annee, $controle, $groupe=null){ // [OPTIONNEL] $groupe
// on vérifie que le semestre existe et que l'enseignant y enseigne
if( !($enseignantUID=userRepo::UID($enseignant)) ) return 'unknown_teacher';
// on récupère les informations du contrôle // on récupère les informations du contrôle
if( !($controlObj=controleRepo::info($controle, $enseignant, $groupe)) ) return 'unknown_controle'; if( !($controlObj=controleRepo::info($controle, $enseignant, $groupe)) ) return 'unknown_controle';
@ -971,9 +974,6 @@ class DataBase{
/*******************************************/ /*******************************************/
public function getNotesForControle($annee, $controle, $groupe=null){ // [OPTIONNEL] $groupe public function getNotesForControle($annee, $controle, $groupe=null){ // [OPTIONNEL] $groupe
// on vérifie que le semestre existe et que l'enseignant y enseigne
if( !($enseignantUID=userRepo::UID($enseignant)) ) return 'unknown_teacher';
// on récupère les informations du contrôle // on récupère les informations du contrôle
if( ! ($controlObj=controleRepo::info($controle)) ) return 'unknown_controle'; if( ! ($controlObj=controleRepo::info($controle)) ) return 'unknown_controle';
@ -997,7 +997,6 @@ class DataBase{
=======================================*/ =======================================*/
}else{ }else{
$controlObj['grouplist'] = groupRepo::forControle($controle); $controlObj['grouplist'] = groupRepo::forControle($controle);
var_dump( $controlObj['grouplist'] );
foreach($controlObj['grouplist'] as $iter=>$grpe) foreach($controlObj['grouplist'] as $iter=>$grpe)
if( $controleNotes = noteRepo::forGroupe($controle, $grpe['id_groupe']) ) // si le groupe a des notes, on les ajoutes if( $controleNotes = noteRepo::forGroupe($controle, $grpe['id_groupe']) ) // si le groupe a des notes, on les ajoutes

View File

@ -76,6 +76,7 @@ class noteRepo extends DBAccess{
AND mcc_ue.id_mcc_ue = mcc_m.id_mcc_ue AND mcc_ue.id_mcc_ue = mcc_m.id_mcc_ue
AND mcc_m.id_mcc_module = ctrl.id_mcc_module AND mcc_m.id_mcc_module = ctrl.id_mcc_module
AND n.id_controle = ctrl.id_controle AND n.id_controle = ctrl.id_controle
AND n.id_note in (SELECT max(id_note) FROM note GROUP BY id_controle, id_appartenance)
AND app.id_etudiant = :etudiant AND app.id_etudiant = :etudiant
AND ctrl.id_controle = :controle AND ctrl.id_controle = :controle
@ -175,6 +176,8 @@ class noteRepo extends DBAccess{
AND mcc_ue.id_mcc_ue = mcc_m.id_mcc_ue AND mcc_ue.id_mcc_ue = mcc_m.id_mcc_ue
AND mcc_m.id_mcc_module = ctrl.id_mcc_module AND mcc_m.id_mcc_module = ctrl.id_mcc_module
AND n.id_controle = ctrl.id_controle AND n.id_controle = ctrl.id_controle
AND n.id_note in (SELECT max(id_note) FROM note GROUP BY id_controle, id_appartenance)
AND ctrl.id_controle = :controle AND ctrl.id_controle = :controle
AND app.id_groupe = :groupe AND app.id_groupe = :groupe
@ -202,6 +205,7 @@ class noteRepo extends DBAccess{
FROM controle as ctrl, note as n FROM controle as ctrl, note as n
WHERE ctrl.id_controle = n.id_controle WHERE ctrl.id_controle = n.id_controle
AND ctrl.id_controle = :controle AND ctrl.id_controle = :controle
AND n.id_note in (SELECT max(id_note) FROM note GROUP BY id_controle, id_appartenance)
GROUP BY ctrl.id_controle"); GROUP BY ctrl.id_controle");
$getMoyenne->execute(array( ':controle' => $controle )); $getMoyenne->execute(array( ':controle' => $controle ));
@ -235,6 +239,7 @@ class noteRepo extends DBAccess{
AND app.id_etudiant = :etudiant AND app.id_etudiant = :etudiant
AND mcc_m.id_module = :module AND mcc_m.id_module = :module
AND app.id_semestre = :semestre AND app.id_semestre = :semestre
AND note.id_note in (SELECT max(id_note) FROM note GROUP BY id_controle, id_appartenance)
GROUP BY mcc_m.id_mcc_module"); GROUP BY mcc_m.id_mcc_module");
$getMoyenneModule->execute(array( ':etudiant' => $etudiant, ':module' => $module, ':semestre' => $semestre )); $getMoyenneModule->execute(array( ':etudiant' => $etudiant, ':module' => $module, ':semestre' => $semestre ));
@ -258,7 +263,8 @@ class noteRepo extends DBAccess{
public static function creer($etudiant, $controle, $semestre, $valeur){ public static function creer($etudiant, $controle, $semestre, $valeur){
/* [1] Premier cas : il faut créer la note de cet étudiant pour ce contrôle /* [1] Premier cas : il faut créer la note de cet étudiant pour ce contrôle
============================================================================*/ ============================================================================*/
if( !($noteUID=noteRepo::UID($etudiant, $controle)) ){ /* [MAJ] On créé toujours une note, même si une existe déjà afin de garder toutes les modifications */
if( true ){ // !($noteUID=noteRepo::UID($etudiant, $controle))
$creationNote = DataBase::getPDO()->prepare("INSERT INTO note(id_note, id_appartenance, id_controle, valeur) $creationNote = DataBase::getPDO()->prepare("INSERT INTO note(id_note, id_appartenance, id_controle, valeur)
VALUES( VALUES(
@ -281,15 +287,15 @@ class noteRepo extends DBAccess{
/* [3] On vérifie que la note a bien été créé pour cet étudiant et ce contrôle /* [3] On vérifie que la note a bien été créé pour cet étudiant et ce contrôle
=================================================================================*/ =================================================================================*/
if( !($noteUID=noteRepo::UID($etudiant, $controle)) ) return false; $verifNote = DataBase::getPDO()->prepare("SELECT n.id_note as id
FROM note as n, appartenance as app
WHERE n.id_appartenance = app.id_appartenance
AND app.id_etudiant = :etudiant
AND n.id_controle = :controle
AND n.valeur = :valeur");
$verifNote->execute(array( ':etudiant' => $etudiant, ':controle' => $controle, ':valeur' => $valeur ));
/* [4] On vérifie que la note créée a bien la valeur qu'on a attribuée return is_array( $verifNote->fetch() );
=================================================================================*/
$verificationValeur = DataBase::getPDO()->prepare("SELECT valeur FROM note WHERE id_note = :noteUID");
$verificationValeur->execute(array( ':noteUID' => $noteUID ));
return ( $verificationValeur->fetch()['valeur'] == $valeur );
} }
@ -319,7 +325,8 @@ class noteRepo extends DBAccess{
/* [1] Premier cas : il faut créer la note de cet étudiant pour ce contrôle /* [1] Premier cas : il faut créer la note de cet étudiant pour ce contrôle
============================================================================*/ ============================================================================*/
if( !($noteUID=noteRepo::UID($cEtudiant, $controle)) ){ /* [MAJ] On créé toujours une note, même si une existe déjà afin de garder toutes les modifications */
if( true ){ // !($noteUID=noteRepo::UID($cEtudiant, $controle))
$creationNote = DataBase::getPDO()->prepare("INSERT INTO note(id_note, id_appartenance, id_controle, valeur) $creationNote = DataBase::getPDO()->prepare("INSERT INTO note(id_note, id_appartenance, id_controle, valeur)
VALUES( VALUES(

View File

@ -95,10 +95,10 @@ if( permission('student') ){ // si l'utilisateur est connecté et que c'est un
echo '<tbody>'; echo '<tbody>';
foreach($UE['modules'] as $MODULE){ foreach($UE['modules'] as $MODULE){
echo '<tr>'; echo '<tr>';
echo '<td>'.$MODULE['nom'].' - '.$MODULE['libelle'].'</td>'; echo "<td>".$MODULE['nom']." - ".$MODULE['libelle']."</td>";
echo '<td>Coefficient <strong>'.$MODULE['coefficient'].'</strong></td>'; echo "<td><span class='unstressed'>Coefficient</span> ".$MODULE['coefficient']."</td>";
echo '<td>'.$UE['nom'].' - '.$UE['libelle'].'</td>'; echo "<td>".$UE['nom']." - ".$UE['libelle']."</td>";
echo '<td>Coefficient <strong>'.$UE['coefficient'].'</strong></td>'; echo "<td><span class='unstressed'>Coefficient</span> ".$UE['coefficient']."</td>";
echo '</tr>'; echo '</tr>';
} }
@ -261,10 +261,10 @@ if( permission('teacher') ){ // si l'utilisateur est un prof
echo '<tbody>'; echo '<tbody>';
foreach($UE['modules'] as $MODULE){ foreach($UE['modules'] as $MODULE){
echo '<tr>'; echo '<tr>';
echo '<td>'.$MODULE['nom'].' - '.$MODULE['libelle'].'</td>'; echo "<td>".$MODULE['nom']." - ".$MODULE['libelle']."</td>";
echo '<td>Coefficient <strong>'.$MODULE['coefficient'].'</strong></td>'; echo "<td><span class='unstressed'>Coefficient</span> ".$MODULE['coefficient']."</td>";
echo '<td>'.$UE['nom'].' - '.$UE['libelle'].'</td>'; echo "<td>".$UE['nom']." - ".$UE['libelle']."</td>";
echo '<td>Coefficient <strong>'.$UE['coefficient'].'</strong></td>'; echo "<td><span class='unstressed'>Coefficient</span> ".$UE['coefficient']."</td>";
echo '</tr>'; echo '</tr>';
} }
@ -440,10 +440,10 @@ if( permission('master') || permission('admin') ){ // si l'utilisateur est un ad
echo '<tbody>'; echo '<tbody>';
foreach($UE['modules'] as $MODULE){ foreach($UE['modules'] as $MODULE){
echo '<tr>'; echo '<tr>';
echo '<td>'.$MODULE['nom'].' - '.$MODULE['libelle'].'</td>'; echo "<td>".$MODULE['nom']." - ".$MODULE['libelle']."</td>";
echo '<td>Coefficient <strong>'.$MODULE['coefficient'].'</strong></td>'; echo "<td><span class='unstressed'>Coefficient</span> ".$MODULE['coefficient']."</td>";
echo '<td>'.$UE['nom'].' - '.$UE['libelle'].'</td>'; echo "<td>".$UE['nom']." - ".$UE['libelle']."</td>";
echo '<td>Coefficient <strong>'.$UE['coefficient'].'</strong></td>'; echo "<td><span class='unstressed'>Coefficient</span> ".$UE['coefficient']."</td>";
echo '</tr>'; echo '</tr>';
} }