[SPIP][PLUGINS] v3.0-->v3.2
[lhc/web/www.git] / www / plugins-dist / plan / prive / javascript / spiptree.js
diff --git a/www/plugins-dist/plan/prive/javascript/spiptree.js b/www/plugins-dist/plan/prive/javascript/spiptree.js
new file mode 100644 (file)
index 0000000..99c468c
--- /dev/null
@@ -0,0 +1,255 @@
+;(function($){
+
+$.fn.spiptree = function(options) {
+
+       var $mytree = $(this);
+       var $mytree_source = $mytree.clone();
+       // $mytree.after($mytree_source);
+
+       options.plugins = [ "types", "search", "state" ];
+       if (options.drag) {
+               options.plugins.push("dnd");
+       }
+
+       options.types = {
+               "#" : {
+                       "valid_children" : ["default"]
+               },
+               "default" : {
+                       "icon" : options.default.icon,
+                       "valid_children" : [ "default" ]
+               }
+       }
+
+       options.confirm = {
+               move: null
+       };
+
+       $.each(options.objets, function(nom, desc) {
+               options.types.default.valid_children.push(desc.type);
+               options.types.default.valid_children.push("box_" + desc.type);
+               options.types[desc.type] = {
+                       "icon" : desc.icon,
+                       "max_children" : 0,
+                       "max_depth" : 0
+               };
+               options.types["box_" + desc.type] = {
+                       "icon" : desc.icon,
+                       "max_depth" : 1,
+                       "valid_children" : [ desc.type ]
+               };
+       });
+
+       $mytree.jstree({
+               "plugins" : options.plugins,
+               "core" : {
+                       "animation" : 0,
+                       "check_callback" : function (op, node, par, pos, more) {
+                               if (op === "move_node") {
+                                       // à la fin d'un déplacement
+                                       // (pas de trig spécifique au début d'un déplacement :( )
+                                       if (more && more.core) {
+                                               // ne pas tenter de déplacer une box non chargée
+                                               var box = (node.type.substring(0, 4) == 'box_');
+                                               if (box && (!node.children || !node.children.length)) {
+                                                       $('#contenu p.success, #contenu div.error').remove();
+                                                       $("#contenu #mytree_actions").after("<div class='error removable' onClick='$(this).remove();'><p /><ul class='spip' /></div>");
+                                                       $box = $("#contenu div.error");
+                                                       $box.find('p').text(options.textes.deplacement.vide + ' ' + options.textes.deplacement.suggerer_deplier);
+                                                       return false;
+                                               }
+
+                                               // Demander 1 fois (et 1 seule) une confirmation, même si on déplace 5 items d'un coup
+                                               if (options.confirm.move === null) {
+                                                       options.confirm.move = confirm( options.textes.deplacement.confirmation );
+                                                       // enlever les messages de réussite ou d'erreur pour en avoir des tout neufs
+                                                       if (options.confirm.move) {
+                                                               $('#contenu p.success, #contenu div.error').remove();
+                                                       }
+                                               }
+                                               return options.confirm.move;
+                                       } else {
+                                               // redemander la confirmation au prochain tour
+                                               options.confirm.move = null;
+                                       }
+                               }
+                               return true;
+                       },
+                       "data" : function (node, cb) {
+                               // on est obligé de tout charger en ajax (même la racine)
+                               // donc on charge 1 fois la racine avec le html d'origine
+                               if (node.id === '#') {
+                                       cb($mytree_source.html());
+                               }
+
+                               // et pour ce qu'on ne connait pas (classe css 'jstree-closed' sur un LI, et pas de UL à l'intérieur)
+                               // on fait un appel ajax pour obtenir la liste correspondant à l'objet souhaité, lorsque c'est demandé.
+                               else {
+                                       var objet = node.data.objet;
+                                       var id_rubrique = (objet == 'rubrique')
+                                               ? node.id.split('-')[1]
+                                               : node.parent.split('-')[1];
+                                       var params = {
+                                               "id_rubrique": id_rubrique,
+                                               "objet": objet
+                                       };
+                                       if (options.statut) {
+                                               params.statut = options.statut;
+                                       }
+
+                                       $.ajax({
+                                               url: options.urls.plan,
+                                               data: params,
+                                               dataType: 'html',
+                                               cache: false,
+                                       }).done(function(data) {
+                                               if (data !== undefined) {
+                                                       cb(data);
+                                               } else {
+                                                       cb("");
+                                               }
+                                       });
+                               }
+                       }
+               },
+               "search" : {
+                       "show_only_matches" : true,
+               },
+               "types" : options.types
+       });
+
+       if (options.drag) {
+               $mytree.addClass('drag');
+       }
+
+       // un clic d'une feuille amène sur son lien
+       // mais… éviter que le plugin 'state' clique automatiquement lorsqu'il restaure
+       // la sélection précédente !
+       $mytree.one("state_ready.jstree", function () {
+               $(this).on("changed.jstree", function (e, data) {
+                       data.instance.save_state();
+                       var node = data.instance.get_node(data.node, true);
+                       if (node) {
+                               var lien = node.children('a').attr('href');
+                               if (lien && !(options.drag && $(data.event.target).hasClass('jstree-icon'))) {
+                                       location.href = lien;
+                               }
+                       }
+               });
+       });
+
+       var recharge_plan = false;
+       // lorsqu'on déplace un nœud
+       $mytree.on("move_node.jstree", function(event, data) {
+               // si les parents sont identiques : pas de changement,
+               // on ne peut/veut pas gérer ici les positionnements
+
+               if (data.old_parent == data.parent) {
+                       // data.instance.refresh();
+                       return true;
+               }
+
+               // il existe 2 cas de boites :
+               // - un item (rubrique, article, site) a été déplacé
+               // - un conteneur (box_xx) a été déplacé (ie: tous les articles qu'il contient par exemple)
+               //   dans ce cas on retrouve tous les identifiants déplacés
+               var box = (data.node.type.substring(0, 4) == 'box_');
+               var infos = data.node.id.split('-'); // articles-rubrique-30 (box) ou article-30 (item)
+
+               if (box) {
+                       var ids = [];
+                       $.each(data.node.children, function(key, val) {
+                               ids.push( val.split('-')[1] );
+                       });
+                       var params = {
+                               objet: infos[0],
+                               id_objet: ids, 
+                               id_rubrique_source: infos[2],
+                               id_rubrique_destination: data.parent.split('-')[1]
+                       }
+               } else if (infos[0] == 'rubrique') {
+                       // les rubriques n'ont pas de 'box_' et sont directement dans les sous rubriques
+                       var params = {
+                               objet: infos[0],
+                               id_objet: [ infos[1] ],
+                               id_rubrique_source: (data.old_parent == '#' ? 0 : data.old_parent.split('-')[1]),
+                               id_rubrique_destination: (data.parent == '#' ? 0 : data.parent.split('-')[1])
+                       }
+               } else {
+                       // un item, sa destination est soit une box (de même type) soit une rubrique
+                       var dest = data.parent.split('-'); // articles-rubrique-30 (box) ou rubrique-30
+                       var params = {
+                               objet: infos[0],
+                               id_objet: [ infos[1] ],
+                               id_rubrique_source: data.old_parent.split('-')[2],
+                               id_rubrique_destination: (dest.length == 3 ? dest[2] : dest[1]),
+                       }
+               }
+
+               $mytree.animateLoading();
+
+               $.ajax({
+                       url: options.urls.deplacer,
+                       data: params,
+                       dataType: 'json',
+                       cache: false,
+               }).done(function(response) {
+
+                       if (response) {
+                               var nb_success = Object.keys(response.success).length;
+                               var nb_errors  = Object.keys(response.errors).length;
+                               if (nb_success) {
+                                       var $box = $("#contenu p.success");
+                                       if (!$box.length) {
+                                               $("#contenu #mytree_actions").after("<p class='success removable' onClick='$(this).remove();'></p>");
+                                               $box = $("#contenu p.success").data('nb', 0);
+                                       }
+                                       nb = nb_success + $box.data('nb');
+                                       $box.data('nb', nb).text(nb == 1
+                                               ? options.textes.deplacement.reussi
+                                               : options.textes.deplacement.reussis.replace('@nb@', nb));
+                               }
+                               if (nb_errors) {
+                                       var $box = $("#contenu div.error");
+                                       if (!$box.length) {
+                                               $("#contenu #mytree_actions").after("<div class='error removable' onClick='$(this).remove();'><p /><ul class='spip' /></div>");
+                                               $box = $("#contenu div.error").data('nb', 0);
+                                       }
+                                       nb = nb_errors + $box.data('nb');
+                                       $box.data('nb', nb).find('p').text(nb == 1
+                                               ? options.textes.deplacement.echec
+                                               : options.textes.deplacement.echecs.replace('@nb@', nb));
+                                       $.each(response.errors, function(i, error) {
+                                               $box.find('ul').append("<li>[ " + i + "] " + error+ "</li>");
+                                       });
+                               }
+                               $mytree.endLoading();
+                       }
+
+                       if (recharge_plan) {
+                               clearTimeout(recharge_plan);
+                       }
+                       recharge_plan = setTimeout(function () {
+                               ajaxReload('plan');
+                       }, 500);
+               });
+
+               return true;
+       });
+
+
+       // recherche automatique
+       $mytree_search = $("#mytree_search");
+
+       var to = false;
+       $mytree_search.keyup(function () {
+               if (to) { clearTimeout(to); }
+               to = setTimeout(function () {
+                       var v = $mytree_search.val();
+                       $mytree.jstree(true).search(v);
+               }, 250);
+       });
+
+};
+
+})(jQuery);