Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Moodle : Modification select des catégories de cours
/* Explications :
Il faut ajouter le code ci dessous a 2 endroits dans le fichier edit_form.php :
- apres ce bout de code (~ligne 77):
// Verify permissions to change course category or keep current.
if (empty($course->id)) {
if (has_capability('moodle/course:create', $categorycontext)) {
$displaylist = coursecat::make_categories_list('moodle/course:create');
$mform->addElement('select', 'category', get_string('coursecategory'), $displaylist);
$mform->addHelpButton('category', 'coursecategory');
$mform->setDefault('category', $category->id);
- et après ce bout de code (~ligne 90, 100 après ajout du code):
if (has_capability('moodle/course:changecategory', $coursecontext)) {
$displaylist = coursecat::make_categories_list('moodle/course:create');
if (!isset($displaylist[$course->category])) {
//always keep current
$displaylist[$course->category] = coursecat::get($course->category, MUST_EXIST, true)->get_formatted_name();
}
$mform->addElement('select', 'category', get_string('coursecategory'), $displaylist);
$mform->addHelpButton('category', 'coursecategory');
*/
/* Le code à rajouter : */
//Modification du code de base : Si ma variable existe, j'appelle ma fonction
//Cela permet crée plein de select de category en plus de celui d'origine qui sont caché par défaut (si le javascript est desactivé, ma modif n'a pas d'impact)
//Le javascript permet ensuite de gerer la disparition du select d'origine et faire appraitre/disparaitre les elements en fonction des selects effectués.
if(isset($_GET["md_test"])) //TODO : à supprimer pour imposer la fonctionnalité à la fin des tests
{
//Ajout du fichier qui contient ma fonction de création des catégories
require_once("edit_form_md.php");
create_categories_md($mform);
}
//Fin de la modification du code de base
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
//ajout d'un "tableau associatif" (object en javascript) global pour gerer les ajout/suppression de select
var categories=new Object;
//Pour afficher un element du formulaire (il faut fournir l'id , ("id_category" par exemple pour ce qui m'interesse))
function afficher(ID)
{
document.getElementById("fitem_"+ID).classList.remove('hide');
document.getElementById(ID).classList.remove('hide');
}
//Pour cacher un element du formulaire
function cacher(ID){
document.getElementById("fitem_"+ID).classList.add('hide');
document.getElementById(ID).classList.add('hide');
}
//déclaration de la fonction qui va servir a gerer les selects lorsque l'on clique sur des nouvelles options
//faire apparaitre et disparaitre les selects, remettre sur la position 0 du select
function gestionSelects(select){
index=select.selectedIndex; //la position dans la liste de l'element que l'on selectionne (si c'est 0 c'est le premier, c'est donc le meme numero que le select d'avant
parentID=select.id;
categoryID=select.options[index].value;
//console.log("index : "+index+"\n");
//console.log("parentID : "+parentID+"\n");
//console.log("categoryID : "+categoryID+"\n");
//Si l'item existe deja, il faut d'abord supprimer tous les sous select
if(categories[parentID]!=null)
{
//on stock le numero de la category fils
tempCategoryID=categories[parentID];
while(tempCategoryID!=null)
{
//console.log("tempCategoryID : "+tempCategoryID+"\n");
//on cache la category fils
if(document.getElementById("fitem_id_category"+tempCategoryID)!=null)
{
document.getElementById("fitem_id_category"+tempCategoryID).classList.add('hide'); //On cache la ligne complete
document.getElementById("id_category"+tempCategoryID).classList.add('hide'); //On cache le select qui est dans la liste (pas forcement utile, mais par défaut la classe hide est sur les 2)
document.getElementById("id_category"+tempCategoryID).options[0].selected=true; //On remet le select sur la 1ere option
}
//On stock l'id de la categorie fils
tempCategoryID2=categories["id_category"+tempCategoryID];
//console.log("tempCategoryID2 : "+tempCategoryID2+"\n");
//on supprime l'element du tableau
delete categories["id_category"+tempCategoryID];
//On recommence avec le potentiel fils du fils
tempCategoryID=tempCategoryID2;
}
//On supprime l'element pour repartir sur une structure vierge
delete categories[parentID];
}
//si on a bien selectionné un enfant et qu'on n'est donc pas revenu sur la categorie parent (ce qui est possible lorsque l'on ne veut pas selectionner de sous enfant)
//et Si la categorie selectionnée à des categories enfants on fait appraitre le select des sous categories
if( (parentID!="id_category"+categoryID) && (document.getElementById("fitem_id_category"+categoryID)!=null))
{
categories[parentID]=categoryID;
afficher("id_category"+categoryID);
}
//On modifie la valeur du select d'origine pour qu'il contienne la bonne valeur.
document.getElementById("id_category").value=categoryID;
//console.log(categories);
}
function init()
{
//On cache le champs categorie d'origine
cacher("id_category");
//On fait appraitre le champs categorie que j'ai crée en php
afficher("id_category0");
//Amelioration : Ajout d'un data-ancestors coté php que l'on peut facilement utiliser ici pour faire apparaitre la "bonne suite" (celle d'origine) de categories
//On recupere la valeur de la categorie deja remplie
current_category=document.getElementById("id_category").value;
//on distingue 2 cas : soit la categorie selectionner est une feuille et on n'affiche que ces ancetres, soit la categories n'en est pas une et on l'affiche en plus de ces ancetres
//Si cela existe, ce n'est pas une feuille, on l'affiche et on recupere l'ancetre
if(document.getElementById("id_category"+current_category)!=null)
{
afficher("id_category"+current_category);
ancetre=document.getElementById("id_category"+current_category).dataset.ancestors;
}
else //sinon c'est une feuille, on ne l'affiche pas mais on recupere quand meme l'ancetre
{
//console.log(document.getElementById("id_category_feuille"+current_category));
ancetre=document.getElementById("id_category_feuille"+current_category).dataset.ancestors;
}
//On fait apparaitre l'ensemble de ces ancetres
while(ancetre!='')
{
//console.log(ancetre);
//On affiche l'ancetre
afficher("id_category"+ancetre);
//On selectionne l'option qui doit etre affiché
document.getElementById("id_category"+ancetre).value=current_category;
//On rempli le tableau categorie
categories["id_category"+ancetre]=current_category;
//et on met à jour le current et le nouvel ancetre
current_category=ancetre;
ancetre=document.getElementById("id_category"+ancetre).dataset.ancestors;
}
//console.log(categories);
}
init();
//Idée mieux : fonction recursive pour créer les selects des sous category
function recursiveSelectCaterogiesForm($mform,$category_id,$nomcategorie='',$ancestors='')
{
//On recupere un objet qui contient les category
$obj_category=coursecat::get($category_id)->get_children();
//On transforme l'objet obtenu en array qui est adaptée à l'ajout dans le formulaire
$array_category=array();
//Ajout d'un tableau pour le css/javascript
$options_category=array();
$options_category['onChange']='gestionSelects(this)'; //On ajoute un appel d'une fonction javascript
$options_category['class']='hide'; //Par défaut : je cache tous les selects que je crée, si le javascript n'est pas fonctionnel cela n'apparaitra jamais, on reste bien sur le fonctionnement classique
$options_category['data-ancestors']=$ancestors;
//Si on est pas la categorie mere, on met le nom de la categorie en premiere option du select pour ne pas imposer de selectionner une sous categorie
if($category_id!=0)
{
$array_category[$category_id]=$nomcategorie; //On ajoute le nom de la categorie en premier
}
//On met ensuite toutes les sous categorie dans le tableau
foreach ($obj_category as $key => $value) {
$array_category[$key]=$value->name;
}
//Si la category n'a pas de categories enfant, on met un id particulier pour dire que c'est une "feuille" (bout de l'arbre des categories) (pour faire un traitement different ensuite dans le javascript)
if(empty($obj_category))
{
$mform->addElement('select', 'category_feuille'.$category_id, get_string('coursecategory'), $array_category, $options_category);
$mform->addHelpButton('category_feuille'.$category_id, 'coursecategory');
}
else
{
$mform->addElement('select', 'category'.$category_id, get_string('coursecategory'), $array_category, $options_category);
$mform->addHelpButton('category'.$category_id, 'coursecategory');
}
//On fait l'appel "après" l'ajout dans le formulaire pour avoir les select dans le bon ordre ..
//Pour chacune des categories enfant on rappelle la fonction pour ajouter les sous selects
foreach ($obj_category as $key => $value) {
recursiveSelectCaterogiesForm($mform,$key,$value->name,$category_id); //pour chacun des enfants on rappelle la fonction (recursivement donc).
}
}
//fonction qui permet de creer/gerer les categories : utilisation de la fonction recursive puis du javascript
function create_categories_md($mform)
{
//On appelle ma fonction recursive qui ajoute tous les selects de toutes les categories :
recursiveSelectCaterogiesForm($mform,0);
//Il faut qu'il cache le "select category de base" et qu'il fasse apparaitre celui que j'ai crée à la place
$mform->addElement('html', '<script type="text/javascript" src="edit_form_md.js"></script>');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment