Current File : /home/escuelai/public_html/biblioteca.escuelaintegral.edu.uy/javascript/drag_n_drop.js |
// +-------------------------------------------------+
// � 2002-2004 PMB Services / www.sigb.net pmb@sigb.net et contributeurs (voir www.sigb.net)
// +-------------------------------------------------+
// $Id: drag_n_drop.js,v 1.30 2020/07/06 11:49:20 dgoron Exp $
/*
* Utilisation :
*
* Definition des elements pouvant �tre deplaces :
*
* Les �l�ments draggable doivent avoir obligatoirement un id !
* Attribut draggable="yes" (obligatoire)
* Attribut dragtype="$TXT" (obligatoire= Type d'element a deplacer)
* Attribut callback_before="$FCT" (Nom de la fonction appelee sur clic avant deplacement)
* Attribut callback_after="$FCT" (Nom de la fonction appelee sur relache apres depla�ement)
* Attribut dragflash="yes" (Affichage d'un symbole au survol d'un element depla�able)
* Attribut dragicon="$IMG" (Image affichee lors du deplacement)
* Attribut dragtext="$TEXT" (Texte affiche lors du deplacement)
* Attribut draghand="$ID" (ID de la poignee utilisee pour deplacer l'element)
*
* Definition des elements recepteurs :
*
* Attribut recept="yes" (obligatoire)
* Attribut recepttype="$TXT" (obligatoire= Type d'element recepteur)
* Attribut highlight=$FCT" (Nom de la fonction appelee au survol du recepteur)
* Attribut downlight=$FCT" (Nom de la fonction apres au survol du recepteur)
*
* Appeller la fonction "init_drag()" pour rechercher tous les elements depla�ables de la page
*
* La fonction "dragtype_recepttype(dragged,target)" est appelee pour associer l'element deplace et l'element cible (si elle existe)
*
*
*/
var draggable=new Array(); //Elements depla�ables
var recept=new Array(); //Elements recepteurs
var handler=new Array(); //Poignees
var is_down=false;
var dragup=true;
var posxdown=0;
var posydown=0;
var current_drag=null;
var dragged=null;
var allow_drag= new Array();
allow_drag['caddie']=new Array();
allow_drag['caddie']['all']=true;
allow_drag['row']=new Array();
allow_drag['row']['row']=true;
allow_drag['cell']=new Array();
allow_drag['cell']['cell']=true;
allow_drag['celldropzone']=new Array();
allow_drag['celldropzone']['cell']=true;
allow_drag['dropzone']=new Array();
allow_drag['dropzone']['export']=true;
allow_drag['dropzone']['rapport']=true;
allow_drag['rapport']=new Array();
allow_drag['rapport']['rapport']=true;
allow_drag['rapport']['export']=true;
allow_drag['parents']=new Array();
allow_drag['parents']['parents']=true;
allow_drag['pairs']=new Array();
allow_drag['pairs']['pairs']=true;
allow_drag['childs']=new Array();
allow_drag['childs']['childs']=true;
allow_drag['avisdrop']=new Array();
allow_drag['avisdrop']['avisdrop']=true;
allow_drag['circdiffdrop']=new Array();
allow_drag['circdiffdrop']['circdiffdrop']=true;
allow_drag['circdiffprint']=new Array();
allow_drag['circdiffprint']['circdiffprint']=true;
allow_drag['circdiffgroupdrop']=new Array();
allow_drag['circdiffgroupdrop']['circdiffgroupdrop']=true;
allow_drag['circcell']=new Array();
allow_drag['circcell']['circcell']=true;
allow_drag['circrow']=new Array();
allow_drag['circrow']['circcell']=true;
allow_drag['tree_elem']=new Array();
allow_drag['tree_elem']['tree_elem']=true;
allow_drag['categ']=new Array();
allow_drag['categ']['categ']=true;
allow_drag['editionsstatefields']=new Array();
allow_drag['editionsstatefields']['editionsstatefields']=true;
allow_drag['editionsstatefieldslist']=new Array();
allow_drag['editionsstatefieldslist']['editionsstatefieldslist']=true;
allow_drag['editionsstateorders']=new Array();
allow_drag['editionsstateorders']['editionsstateorders']=true;
allow_drag['editionsstateorderslist']=new Array();
allow_drag['editionsstateorderslist']['editionsstateorderslist']=true;
allow_drag['editionsstatefilters']=new Array();
allow_drag['editionsstatefilters']['editionsstatefilters']=true;
allow_drag['editionsstatefilterslist']=new Array();
allow_drag['editionsstatefilterslist']['editionsstatefilterslist']=true;
allow_drag['concept']=new Array();
allow_drag['concept']['concept']=true;
allow_drag['vedette_composee_subdivision']=new Array();
allow_drag['vedette_composee_subdivision']['vedette_composee_available_fields']=true;
allow_drag['vedette_composee_subdivision']['vedette_composee_element']=true;
allow_drag['vedette_composee_element']=new Array();
allow_drag['vedette_composee_element']['vedette_composee_element']=true;
allow_drag['vedette_composee_delete_element']=new Array();
allow_drag['vedette_composee_delete_element']['vedette_composee_element']=true;
allow_drag['instru']=new Array();
allow_drag['instru']['instru']=true;
allow_drag['search_perso']=new Array();
allow_drag['search_perso']['search_perso']=true;
allow_drag['oeuvre_expression']=new Array();
allow_drag['oeuvre_expression']['oeuvre_expression']=true;
allow_drag['oeuvre_expression_from']=new Array();
allow_drag['oeuvre_expression_from']['oeuvre_expression_from']=true;
allow_drag['other_link']=new Array();
allow_drag['other_link']['other_link']=true;
var r_x=new Array();
var r_y=new Array();
var r_width=new Array();
var r_height=new Array();
var r_highlight="";
var drag_icon="./images/drag_symbol.png";
var drag_empty_icon="./images/drag_symbol_empty.png";
//Trouve la position absolue d'un objet dans la page
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft
curtop = obj.offsetTop
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
}
}
return [curleft,curtop];
}
//Recupere les coordonnees du click souris
function getCoordinate(e) {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
return [posx,posy];
}
//Handler : Click sur un element draggable
function mouse_down_draggable(e) {
//On annule tous les comportements par defaut du navigateur (ex : selection de texte)
if (!e) var e=window.event;
if (e.ctrlKey || e.metaKey) return;
if (!e) var e=window.event;
if (e.stopPropagation) {
e.preventDefault();
e.stopPropagation();
} else {
e.cancelBubble=true;
e.returnValue=false;
}
//On commence par recalculer les r�cepteurs.
recalc_recept();
//Recuperation de l'element d'origine qui a re�u l'evenement
if (e.target) var targ=e.target; else var targ=e.srcElement;
//On nettoie tout drag en cours
posxdown=0;
posydown=0;
is_down=false;
if (current_drag) current_drag.parentNode.removeChild(current_drag);
current_drag=null;
dragged=null;
//Recherche du premier parent qui a draggable comme attribut
while ((targ.getAttribute("draggable")!="yes")&&(targ.nodeName!="HTML")) {
targ=targ.parentNode;
}
//On stocke l'element d'origine
dragged=targ;
//Stockage des coordonnees d'origine du click
var pos=getCoordinate(e);
posxdown=pos[0];
posydown=pos[1];
//Il y a un element en cours de drag !
is_down=true;
var to_create = true;
//Appel de la fonction callback before si elle existe
if (targ.getAttribute("callback_before")) {
to_create = eval(targ.getAttribute("callback_before")+"(targ,e)");
}
//Creation du clone qui bougera
if(to_create)
create_dragged(targ);
else{
//On nettoie tout drag en cours
posxdown=0;
posydown=0;
is_down=false;
if (current_drag) current_drag.parentNode.removeChild(current_drag);
current_drag=null;
dragged=null;
}
}
//Evenement : passage au dessus d'un element draggable : on affiche un
// petit symbole pour signifier qu'il est draggable
function mouse_over_draggable(e) {
if (!e) var e=window.event;
if (e.target) var targ=e.target; else var targ=e.srcElement;
//Recherche du premier parent qui a draggable
while ((targ.getAttribute("draggable")!="yes")&&(targ.nodeName!="HTML")) {
targ=targ.parentNode;
}
//On met un petit symbole "drap"
//Recherche de la position
var pos=findPos(targ);
//Creation d'un <div><image/></div> au dessus de l'element
var drag_symbol=document.createElement("div");
drag_symbol.setAttribute("id","drag_symbol_"+targ.getAttribute("id"));
drag_symbol.style.position="absolute";
drag_symbol.style.left=pos[0]+"px";
drag_symbol.style.top=pos[1]+"px";
drag_symbol.style.zIndex=1000;
if (targ.getAttribute("dragflash")=="yes") {
img_symbol=document.createElement("img");
img_symbol.setAttribute("src",drag_icon);
drag_symbol.appendChild(img_symbol);
}
//Affichage a partir de l'ancre
document.getElementById("att").appendChild(drag_symbol);
}
//Evenement : on sort du survol d'un element "draggable"
function mouse_out_draggable(e) {
if (!e) var e=window.event;
if (e.target) var targ=e.target; else var targ=e.srcElement;
//Recherche du premier parent qui a draggable
while ((targ.getAttribute("draggable")!="yes")&&(targ.nodeName!="HTML")) {
targ=targ.parentNode;
}
//Suppression du petit symbole
drag_symbol=document.getElementById("drag_symbol_"+targ.getAttribute("id"));
if (drag_symbol) drag_symbol.parentNode.removeChild(drag_symbol);
}
//Quand on relache le clone, y-a-t-il un element recepteur en dessous ? Si oui, on retourne l'id
function is_on() {
var i;
if (current_drag!=null) {
var current_drag_id=current_drag.getAttribute('id');
try { //gestion paniers
var scrollbar_pos=document.getElementById('pannel_carts').scrollTop;
}catch(err){
var scrollbar_pos=0;
}
var dragged_id=current_drag_id.substring(0, current_drag_id.length-5);
var pos=findPos(current_drag);
// for (i=0; i<recept.length; i++) {
for (i=recept.length-1;i>=0 ;i--) {
/*
if( (document.getElementById(recept[i]).getAttribute('recepttype')=='caddie') ||
(document.getElementById(recept[i]).getAttribute('recepttype')=='dropzone' && document.getElementById(dragged_id).getAttribute('dragtype')=='cell') ||
(document.getElementById(recept[i]).getAttribute('recepttype')==document.getElementById(dragged_id).getAttribute('dragtype')) ) {
*/
if(document.getElementById(recept[i]).style.display != "none"){
if( (allow_drag[document.getElementById(recept[i]).getAttribute('recepttype')]['all']==true) ||
(allow_drag[document.getElementById(recept[i]).getAttribute('recepttype')][document.getElementById(dragged_id).getAttribute('dragtype')]==true) ) {
var isx=0;
var isy=0;
if ((pos[0]>r_x[i])&&(pos[0]<parseFloat(r_x[i])+parseFloat(r_width[i]))) isx++;
if (((parseFloat(pos[0])+parseFloat(current_drag.offsetWidth))>r_x[i])&&((parseFloat(pos[0])+parseFloat(current_drag.offsetWidth))<parseFloat(r_x[i])+parseFloat(r_width[i]))) isx++;
if ((pos[1]>r_y[i]-scrollbar_pos)&&(pos[1]<parseFloat(r_y[i]-scrollbar_pos)+parseFloat(r_height[i]))) isy++;
if (((parseFloat(pos[1])+parseFloat(current_drag.offsetHeight))>r_y[i]-scrollbar_pos)&&((parseFloat(pos[1])+parseFloat(current_drag.offsetHeight))<parseFloat(r_y[i]-scrollbar_pos)+parseFloat(r_height[i]))) isy++;
if (parseInt(isx)*parseInt(isy)){
return recept[i];
}
}
}
}
}
return false;
}
//Si la souris est au dessus du document et qu'on est en cours de drag, on annule tous les
// comportements par defaut du navigateur
function mouse_over(e) {
if (!e) var e=window.event;
if (is_down) {
if (e.stopPropagation) {
e.preventDefault();
e.stopPropagation();
} else {
e.cancelBubble = true;
e.returnValue=false;
}
}
}
//On relache le bouton en cours de drag
function up_dragged(e) {
//Si il y a un clone en cours de mouvement, on le supprime, on remet tout a zero et on
// appelle la fonction qui gere le drag si elle existe et qu'il y a un recepteur en dessous
if (current_drag!=null) {
//Y-a-t-il un recepteur en dessous du l�che ?
try{
target=is_on();
} catch(e){
target=null;
}
//Remise a zero
posxdown=0;
posydown=0;
is_down=false;
if (current_drag) current_drag.parentNode.removeChild(current_drag);
current_drag=null;
//Si il y a un recepteur : callback de la fonction d'association si elle existe
if (target) {
if (eval("typeof "+dragged.getAttribute("dragtype")+"_"+document.getElementById(target).getAttribute("recepttype")+"=='function'")) {
eval(dragged.getAttribute("dragtype")+"_"+document.getElementById(target).getAttribute("recepttype")+"(dragged,document.getElementById(target))");
}
}
//Appel de la fonction callback_after si elle existe
if (dragged && dragged.getAttribute("callback_after")) {
eval(dragged.getAttribute("callback_after")+"(dragged,e,'"+target+"')");
}
//On nettoie la reference a l'element d'origine
dragged=null;
}
}
//Evenement : Deplacement du clone (draggage)
function move_dragged(e) {
if (!e) var e=window.event;
//Si il y a un drag en cours
if (is_down) {
//On annule tous les comportements par defaut du navigateur
if (e.stopPropagation) {
e.preventDefault();
e.stopPropagation();
} else {
e.cancelBubble = true;
e.returnValue=false;
}
//Deplacement
var pos=getCoordinate(e);
//Positionnement du clone pour que le pointeur de la souris soit au milieu !
// On g�re le cas de la pr�sence d'un handler
var current_drag_handler = document.getElementById(current_drag.getAttribute("handler"));
if (current_drag_handler) {
var encx=current_drag_handler.offsetWidth;
var ency=current_drag_handler.offsetHeight;
} else {
var encx=current_drag.offsetWidth;
var ency=current_drag.offsetHeight;
}
current_drag.style.left=(pos[0]-(encx/2))+"px";
current_drag.style.top=(pos[1]-(ency/2))+"px";
try{
var r=is_on();
} catch(e){
var r=null;
}
if (r) {
if ((r_highlight)&&(r_highlight!=r)) {
if (document.getElementById(r_highlight).getAttribute('downlight'))
eval(document.getElementById(r_highlight).getAttribute('downlight')+"(document.getElementById(r_highlight))");
}
if (document.getElementById(r).getAttribute('highlight'))
eval(document.getElementById(r).getAttribute('highlight')+"(document.getElementById(r))");
r_highlight=r;
} else if ((r_highlight)&&document.getElementById(r_highlight)) {
if (document.getElementById(r_highlight).getAttribute('downlight')) {
eval(document.getElementById(r_highlight).getAttribute('downlight')+"(document.getElementById(r_highlight))");
r_highlight="";
}
}
}
}
//Creation du clone
function create_dragged(targ) {
//Recherche de la position d'origine
initpos=findPos(targ);
//Creation du clone si necessaire
if (current_drag==null) {
dragtext=targ.getAttribute("dragtext");
dragicon=targ.getAttribute("dragicon");
if (dragtext||dragicon) {
clone=document.createElement("span");
clone.className="dragtext";
if (dragicon) {
var icon=document.createElement("img");
icon.src=dragicon;
clone.appendChild(icon);
}
if (dragtext) {
clone.appendChild(document.createTextNode(dragtext));
}
} else {
if (targ.nodeName=='TR') { //Et c'est encore IE qui fait des siennes !!!
fclone=targ.cloneNode(true);
t=document.createElement('TABLE');
b=document.createElement('TBODY');
b.appendChild(fclone);
t.appendChild(b);
clone=t;
} else {
clone=targ.cloneNode(true);
// clone.style.width=targ.offsetWidth+'px';
// clone.style.height=targ.offsetHeight+'px';
}
}
current_drag=document.createElement("div");
current_drag.setAttribute("id",targ.getAttribute("id")+"drag_");
current_drag.setAttribute('handler',targ.getAttribute("handler"));
current_drag.className="dragged";
current_drag.appendChild(clone);
current_drag.style.position="absolute";
current_drag.style.visibility="hidden";
current_drag.style.width=targ.offsetWidth;
current_drag=document.getElementById("att").appendChild(current_drag);
// On g�re le cas de la pr�sence d'un handler
var current_drag_handler = document.getElementById(current_drag.getAttribute("handler"));
if (current_drag_handler) {
var encx=current_drag_handler.offsetWidth;
var ency=current_drag_handler.offsetHeight;
} else {
var encx=current_drag.offsetWidth;
var ency=current_drag.offsetHeight;
}
current_drag.style.left=(posxdown-(encx/2))+"px";
current_drag.style.top=(posydown-(ency/2))+"px";
current_drag.style.zIndex=2000;
current_drag.style.visibility="visible";
current_drag.style.cursor="move";
}
}
//Parcours de l'arbre HTML pour trouver les elements qui ont les attributs draggable ou recept
function parse_drag(n) {
var i;
var c;
var l;
var idh;
var tmp;
//Pour le noeud passe, si c'est un noeud de type element (1), alors on regarde ses attributs
if(n.nodeType==1){
//C'est un recepteur
if (n.getAttribute("recept")=="yes") {
l=recept.length;
recept[l]=n.getAttribute("id");
calc_recept(l);
}
//C'est un element depla�able
if (n.getAttribute("draggable")=="yes") {
draggable[draggable.length]=n.getAttribute("id");
//Avec une poignee
if (n.getAttribute("handler")) {
idh=n.getAttribute("handler");
tmp=document.getElementById(idh);
handler[handler.length]=idh;
} else {
tmp=n;
}
//Implementation des gestionnaires d'evenement pour les elements depla�ables
tmp.onmousedown=function(e) {
mouse_down_draggable(e);
}
tmp.onmouseover=function(e) {
mouse_over_draggable(e);
}
tmp.onmouseout=function(e) {
mouse_out_draggable(e);
}
}
}
//Si il a des enfants, on parse ses enfants !
if (n.hasChildNodes()) {
for (i=0; i<n.childNodes.length; i++) {
c=n.childNodes[i];
parse_drag(c);
}
}
}
//Recherche des recepteurs uniquement, a partir du noeud specifie
function parse_drag_recept(n) {
var i;
var l;
var c;
//Pour le noeud passe, si c'est un noeud de type element (1), alors on regarde ses attributs
if(n.nodeType==1){
//C'est un recepteur
if (n.getAttribute("recept")=="yes") {
l=recept.length;
recept[l]=n.getAttribute("id");
calc_recept(l);
}
}
//Si il a des enfants, on parse ses enfants !
if (n.hasChildNodes()) {
for (i=0; i<n.childNodes.length; i++) {
c=n.childNodes[i];
parse_drag_recept(c);
}
}
}
//Reinitialisation et recherche de tous les recepteurs
function init_recept() {
//Reinitialisation des tableaux recepteurs
r_x=new Array();
r_y=new Array();
r_width=new Array();
r_height=new Array();
r_highlight='';
recept=new Array();
//Recherche de tous les recepteurs
parse_drag_recept(document.body);
}
//Initialisation des fonctionnalites (a appeler a la fin du chargement de la page)
function init_drag() {
//Reinitialisation des tableaux et variables
draggable=new Array(); //Elements depla�ables
recept=new Array(); //Elements recepteurs
handler=new Array(); //Poignees
is_down=false;
dragup=true;
posxdown=0;
posydown=0;
current_drag=null;
dragged=null;
r_x=new Array();
r_y=new Array();
r_width=new Array();
r_height=new Array();
r_highlight="";
//Recherche de tous les elements depla�ables et des recepteurs
parse_drag(document.body);
//On surveille tout ce qui se passe dans le document au niveau de la souris (sauf click down !)
document.onmousemove=function (e) {
move_dragged(e);
}
document.onmouseup=function (e) {
up_dragged(e);
}
document.onmouseover=function (e) {
mouse_over(e);
}
}
//Calcul de l'encombrement de tous les recepteurs
function recalc_recept() {
for(var i=0;i<recept.length;i++) {
calc_recept(i);
}
}
//Calcul de l'encombrement d'un recepteur
function calc_recept(i) {
try {
var r=document.getElementById(recept[i]);
var pos=findPos(r);
r_x[i]=pos[0];
r_y[i]=pos[1];
r_width[i]=r.offsetWidth;
r_height[i]=r.offsetHeight;
r_highlight="";
} catch(err) {
recept.splice(i,1);
r_x.splice(i,1);
r_y.splice(i,1);
r_width.splice(i,1);;
r_height.splice(i,1);
}
}