Surchoucher le drag'n'drop

Avec dojo il est possible de surcoucher tous les comportements implémentés pour qu'ils s'adaptent à nos besoins.
Nous allons voir ici comment faire avec le drag'n'drop.

Déterminer les classes à surcoucher

Pour cela, il faut fouiller dans la structure de dojo.
Pour le drag'n'drop, on déclare :

javascript
dojo.require("dojo.dnd.*");

on peu donc trouver toutes les classes de drag'n'drop dans dojo/src/dnd.
Pour l'exemple, nous allons surcoucher la classe qui gère l'indicateur de position lors du drag. De cette façon, nous pourrons faire apparaitre nos propres indications. Les parties générant de l'affichage sont dans des fichiers qui commencent par Html. Nous allons donc logiquement ouvrir HtmlDragAndDrop.js.
A l'interieur on repère :

javascript
dojo.declare("dojo.dnd.HtmlDropTarget", 
dojo.dnd.DropTarget, 
	{

Ce code signifie que dojo déclare un objet HtmlDragObject, hérité de DragObject.
Nous avons trouvé ce que nous cherchions. On remarque d'ailleurs que le contenu de cette classe propose plusieurs méthodes :

  • onDragOver
  • _getNodeUnderMouse
  • createDropIndicator
  • onDragMove
  • placeIndicator
  • onDragOut
  • onDrop
  • insert

On peut aisément déduire que celle qui nous intéresse est : createDropIndicator (Création de l'indicateur)

Créer notre classe

Nous allons créer une classe qui va hériter de celles de dojo puis en modifier certaines parties. De cette façon, notre classe n'aura pas besoin de déclarer toutes les méthodes de la classe d'origine. Seule celles déclarées seront surcouchée. Tout d'abord, créons la structure de notre classe :

javascript
dojo.provide("personal.HtmlDropTarget");
personal.HtmlDropTarget = function(node, types){
	dojo.dnd.HtmlDropTarget.call(this, node, types); //dojo.dnd.HtmlDropTarget correspond à la déclaration vu ci-dessus
};
dojo.inherits(personal.HtmlDropTarget,  dojo.dnd.HtmlDropTarget); //dojo.dnd.HtmlDropTarget correspond à la déclaration vu ci-dessus
dojo.lang.extend(personal.HtmlDropTarget, {
/*
* Les méthodes à surcoucher seront ici
*/
 
});
vous pouvez remplacer personal.HtmlDropTarget par ce que vous voulez, néanmoins, pour une meilleure relecture du code, je vous conseille de conserver le nom de l'objet surcouché (ici HtmlDropTarget)

Nous avons donc conçut une classe (qui pour l'instant fait exactement la même chose que dojo.dnd.HtmlDropTarget).
Pour la charger, nous devons faire :

javascript
dojo.require("personal.HtmlDropTarget");

Surchoucher les méthodes

Maintenant que nous avons la classe, nous allons commencé à surcoucher la méthode.
Voici la méthode d'origine :

javascript
createDropIndicator: function(){
	this.dropIndicator = document.createElement("div");
	with(this.dropIndicator.style){
		position = "absolute";
		zIndex = 999;
		if(this.vertical){
			borderLeftWidth = "1px";
			borderLeftColor = "black";
			borderLeftStyle = "solid";
			height = dojo.html.getBorderBox(this.domNode).height + "px";
			top = dojo.html.getAbsolutePosition(this.domNode, true).y + "px";
		}else{
			borderTopWidth = "1px";
			borderTopColor = "black";
			borderTopStyle = "solid";
			width = dojo.html.getBorderBox(this.domNode).width + "px";
			left = dojo.html.getAbsolutePosition(this.domNode, true).x + "px";
		}
	}
},

Le fonctionnement est simple.
La variable this.dropIndicator contient un objet DOM (ici un div). C'est cet objet qui est affiché pour indiquer le positionnement.
Mettons en place notre nouvel indicateur :

javascript
createDropIndicator: function(){
	this.dropIndicator = document.createElement("div");
	with(this.dropIndicator.style){
		position = "absolute";
		zIndex = 999;
		borderTopWidth = "1px";
		borderTopColor = "#f60";
		borderTopStyle = "dashed";
		width = dojo.html.getBorderBox(this.domNode).width + "px";
		left = dojo.html.getAbsolutePosition(this.domNode, true).x + "px";
		height = "18px";
		background = "url(http://www.wikistuce.info/lib/tpl/default/images/footer.jpg)";
	}
},

Notre méthode va toujours créer un div mais avec de nouvelles propriétés. Ici, on lui attribut un image de fond.

A la fin

Maintenant, votre code devrait ressembler à ceci :

javascript
dojo.require("dojo.dnd.HtmlDropTarget"); //Ceci est obligatoire car  pour hériter de la classe principale, il faut d'abord la charger.
 
dojo.provide("personal.HtmlDropTarget");
personal.HtmlDropTarget = function(node, types){
	dojo.dnd.HtmlDropTarget.call(this, node, types); //dojo.dnd.HtmlDropTarget correspond à la déclaration vu ci-dessus
};
dojo.inherits(personal.HtmlDropTarget,  dojo.dnd.HtmlDropTarget); //dojo.dnd.HtmlDropTarget correspond à la déclaration vu ci-dessus
dojo.lang.extend(personal.HtmlDropTarget, {
createDropIndicator: function(){
	this.dropIndicator = document.createElement("div");
	with(this.dropIndicator.style){
		position = "absolute";
		zIndex = 999;
		borderTopWidth = "1px";
		borderTopColor = "#f60";
		borderTopStyle = "dashed";
		width = dojo.html.getBorderBox(this.domNode).width + "px";
		left = dojo.html.getAbsolutePosition(this.domNode, true).x + "px";
		height = "18px";
		background = "url(http://www.wikistuce.info/lib/tpl/default/images/footer.jpg)";
	}
},
});
dojo.require("personal.HtmlDropTarget");

Il ne reste plus qu'à utiliser votre classe. Ceci ce fait de la même façon que n'importe quelle classe dojo :

javascript
	var dl = document.getElementById("lrList");
	new personal.HtmlDropTarget(dl, ["li1"]);
	//Pour la classe Dojo originale, il faut écrire : 
	//new dojo.dnd.HtmlDropTarget(dl, ["li1"]);
Il se peu que vous ailez besoin de faire appel au traitement d'origine de Dojo. Si tel est le cas, vous pouvez utiliser superclass.
Exemple :

javascript
var v = personal.HtmlDropTarget.superclass.createDropIndicator.call(this);
//Ceci appelera le traitement par défaut de Dojo (méthode : createDropIndicator)

Les paramètres de la fonction call sont :

  • this (obligatoire)
  • autant de paramètres que la fonction d'origine en attend (ici aucun…)



30/01/2007 08:53 -

iDo –