Avatar billede alvion Nybegynder
11. december 2003 - 21:00 Der er 11 kommentarer og
2 løsninger

Drag and drop

Er der nogen, der har erfaring med at lave drag'n'drop med DHTML og javascript?

Jeg har lavet en træstruktur (lavet i en tabel), hvor jeg gerne vil give brugeren mulighed for at kunne flytte rundt på elementerne med drag'n'drop.

Eksempel

Top
+--Element 1
|  +--Element 1.1
|    +--Element 1.1.1
|    +--Element 1.1.2
|  +--Element 1.2
+--Element 2
  +--Element 2.1
  +--Element 2.2

Så vil jeg gerne visualisere et drag'n'drop af f.eks. "Element 1.1" (inklusiv underelementer) til "Element 2".

Selve server-side opdateringen af flytningen skal jeg nok håndtere selv.

Men på klientsiden kunne jeg godt bruge noget hjælp.
Avatar billede roenving Novice
11. december 2003 - 21:05 #1
Måske kunne dette inspirere dig ?-)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Byt celler</title>
<meta name="Generator" content="Stone's WebWriter 4">
<meta http-equiv="Content-Language" content="da">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
.tdname{
border:red 1px solid;
}
.tdkampe{
border:red 1px solid;
}
.dkampe{
background:'url(../transparent.gif)' 400px 25px repeat;
position:relative;
height:25px;
width:400px;
display:block;
}
.fkampe{
position:absolute;
background-color:grey;
border:#7f7f7f 1px dotted;
height:25px;
width:400px;
display:block;
z-index:3;
}
.dname{
background:'url(../transparent.gif)' 100px 25px no-repeat;
position:relative;
height:25px;
width:100px;
display:block;
}
.tdmellemrum{
background:'url(../transparent.gif)';
position:relative;
height:8 px;
font-size:4px;
border:transparent 0px;
}
</style>
<script language="javascript" type="text/javascript">
var nede = false;
var x = y = 0;
var stTop = 0;
var stHeight = 0;
var numDivs = 0;
var flytDivs = new Array();

function traek(obj) {
  if (nede) {
  //alert(stTop+"\n"+stHeight+"\n"+event.clientY+"\n"+y+"\n"+""+"\n"+obj.lastElm);
    //obj.style.left = event.clientX - x;
    var newTop = event.clientY - y - 3;
    //first can't move up, last can't move down
    if((newTop<stTop&&obj.num==0)||(newTop>stTop&&obj.num==numDivs)){return false;
    }else{
        //movement only allowed until 60% then a swap occurs
        if(0.6*stHeight>Math.abs(stTop-newTop)){
            obj.style.top = newTop;
            return false;
        }else{
            swapElms(obj,newTop)
          }
    }
  }
}
function swapElms(obj,newTop){
    //Swapping values and relations
  var newNum = oldNum = obj.num;
    if (newTop>stTop)newNum++;
        else newNum--;
  var swap = flytDivs[newNum];
  var newPar = swap.par;
    var newSib = swap.sib;
  swap.par = obj.par;
  swap.sib = obj.sib;
    swap.num = obj.num;
    obj.par = newPar;
  obj.sib = newSib;
    obj.num = newNum;
    flytDivs[oldNum] = swap;
    flytDivs[newNum] = obj;
  swap.sib.innerHTML = obj.sib.innerHTML;
  obj.sib.innerHTML = obj.innerHTML;
    swap.style.top = getPos(swap.par).y;
  stTop = getPos(obj.par).y;
  obj.style.top = stTop;
  alert('Poster byttet rundt!');
}
function getPos(elm) {
    for(var zx=zy=0;elm!=null;zx+=elm.offsetLeft,zy+=elm.offsetTop,elm=elm.offsetParent);
    return {x:zx,y:zy}
}
function initMove(obj){
    stTop=getPos(obj.par).y;
    stHeight=obj.par.scrollHeight;
    x=event.offsetX;
    y=event.offsetY;
    nede=true;
    obj.innerHTML = obj.sib.innerHTML;
}
function initFlytDiv(){
    var b = document.body;
    for(i=0;document.getElementById("tdkampe"+i);i++){
        //document.body.innerHTML+='<DIV CLASS="fkampe" ID="fkampe'+i+'" onMouseDown="initMove(flytDivs[this.num]);" onMouseUp="nede=false;" onMouseOut="nede=false;" onMouseMove="traek(this);" onSelectStart="return false;" ></DIV>'
        var d = document.getElementById("fkampe"+i);
        var p = document.getElementById("tdkampe"+i);
        d.style.top = getPos(p).y;
        d.style.left = getPos(p).x;
        d.par = p;
        d.sib = document.getElementById("kampe"+i);
        d.num = i;
        flytDivs[i] = d;
        numDivs = i;
    }
}
</script>
</head>
<body onresize onload="initFlytDiv()">
<table cellpadding="0" cellspacing="0" cols="2" style="border-collapse:collapse"><!--  STYLE="border:black 1px solid;border-collapse:collapse" -->
    <tr>
        <td class="tdname" onselectstart="return false;"><div class="dname" id="dato0">&nbsp;</div></td>
        <td class="tdkampe" id="tdkampe0" onselectstart="return false;"><div class="dkampe" id="kampe0">&nbsp;0</div></td>
    </tr>
    <tr>
        <td class="tdmellemrum" colspan="2" onselectstart="return false;">&nbsp;</td>
    </tr>
    <tr>
        <td class="tdname" onselectstart="return false;"><div class="dname" id="dato1">&nbsp;</div></td>
        <td class="tdkampe" id="tdkampe1" onselectstart="return false;"><div class="dkampe" id="kampe1">&nbsp;1</div></td>
    </tr>
    <tr>
        <td class="tdmellemrum" colspan="2" onselectstart="return false;">&nbsp;</td>
    </tr>
    <tr>
        <td class="tdname" onselectstart="return false;"><div class="dname" id="dato2">&nbsp;</div></td>
        <td class="tdkampe" id="tdkampe2" onselectstart="return false;"><div class="dkampe" id="kampe2">&nbsp;2</div></td>
    </tr>
    <tr>
        <td class="tdmellemrum" colspan="2" onselectstart="return false;">&nbsp;</td>
    </tr>
    <tr>
        <td class="tdname" onselectstart="return false;"><div class="dname" id="dato3">&nbsp;</div></td>
        <td class="tdkampe" id="tdkampe3" onselectstart="return false;"><div class="dkampe" id="kampe3">&nbsp;3</div></td>
    </tr>
    <tr>
        <td class="tdmellemrum" colspan="2" onselectstart="return false;">&nbsp;</td>
    </tr>
    <tr>
        <td class="tdname" onselectstart="return false;"><div class="dname" id="dato4">&nbsp;</div></td>
        <td class="tdkampe" id="tdkampe4" onselectstart="return false;"><div class="dkampe" id="kampe4">&nbsp;4</div></td>
    </tr>
    <tr>
        <td class="tdmellemrum" colspan="2" onselectstart="return false;">&nbsp;</td>
    </tr>
    <tr>
        <td class="tdname" onselectstart="return false;"><div class="dname" id="dato5">&nbsp;</div></td>
        <td class="tdkampe" id="tdkampe5" onselectstart="return false;"><div class="dkampe" id="kampe5">&nbsp;5</div></td>
    </tr>
    <tr>
        <td class="tdmellemrum" colspan="2" onselectstart="return false;">&nbsp;</td>
    </tr>
    <tr>
        <td class="tdname" onselectstart="return false;"><div class="dname" id="dato6">&nbsp;</div></td>
        <td class="tdkampe" id="tdkampe6" onselectstart="return false;"><div class="dkampe" id="kampe6">&nbsp;6</div></td>
    </tr>
</table>
<div class="fkampe" id="fkampe0" onmousedown="initMove(this);" onmouseup="nede=false;" onmouseout="nede=false;" onmousemove="traek(this);" onselectstart="return false;" ></div>
<div class="fkampe" id="fkampe1" onmousedown="initMove(this);" onmouseup="nede=false;" onmouseout="nede=false;" onmousemove="traek(this);" onselectstart="return false;" ></div>
<div class="fkampe" id="fkampe2" onmousedown="initMove(this);" onmouseup="nede=false;" onmouseout="nede=false;" onmousemove="traek(this);" onselectstart="return false;" ></div>
<div class="fkampe" id="fkampe3" onmousedown="initMove(this);" onmouseup="nede=false;" onmouseout="nede=false;" onmousemove="traek(this);" onselectstart="return false;" ></div>
<div class="fkampe" id="fkampe4" onmousedown="initMove(this);" onmouseup="nede=false;" onmouseout="nede=false;" onmousemove="traek(this);" onselectstart="return false;" ></div>
<div class="fkampe" id="fkampe5" onmousedown="initMove(this);" onmouseup="nede=false;" onmouseout="nede=false;" onmousemove="traek(this);" onselectstart="return false;" ></div>
<div class="fkampe" id="fkampe6" onmousedown="initMove(this);" onmouseup="nede=false;" onmouseout="nede=false;" onmousemove="traek(this);" onselectstart="return false;" ></div>
</body>
</html>
Avatar billede alvion Nybegynder
11. december 2003 - 21:17 #2
Mnjaaa.... Du slipper jo lidt let om ved at finde ud af, hvor elementet droppes. I dit eksempel kan man kun rykke op og ned og kun et "ryk" af gangen. Derfor finder du dit "target" ved blot at se om y-koordinaten er højere eller lavere end for elementet der flyttes
Avatar billede roenving Novice
11. december 2003 - 21:18 #3
Jeps ...

Det var starten på et projekt, jeg aldrig er kommet videre med !-)
Avatar billede olebole Juniormester
15. december 2003 - 03:37 #4
<ole>
Du kan bruge MS' drag&drop funktionalitet - eller skrive den selv  :)

http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/events/ondragstart.asp
/mvh
</bole>
Avatar billede alvion Nybegynder
15. december 2003 - 10:50 #5
Jeg har undersøgt MS's drag'n'drop og andre alternativer. Og det er lidt noget lort, for man kan kun "dragge" billeder ELLER markeret tekst. Hvad jeg gerne ville var at at kunne dragge et lag, men som der også står på MS's hjemmeside:

"When dragging anything other than an img object, some text to be dragged must be selected."

Og DET er jeg ikke interesseret i...
Avatar billede olebole Juniormester
15. december 2003 - 12:34 #6
Nej, du kan dragge, hvad somhelst. Du kan anbringe et billede i span'et (et 'drag-håndtag'). På ondragstart lægger du billedets parentNode.outerHTML (span'ets outerHTML) i dit dataTransfer-object - sammen med span'ets id.
På ondrop kan du så kalde det 'gamle' span-element og delete det - samtidig med du sætter HTML'en ind på det nye sted.

Ellers må du jo bare smøge ærmerne op og lave det hele selv i JavaScript  :)
Avatar billede alvion Nybegynder
15. december 2003 - 15:58 #7
Nåja et drag-håndtag.... Ja det var selvfølgelig en mulighed. :-)

Ok send begge et svar, i har begge to fortjent point :)
Avatar billede olebole Juniormester
15. december 2003 - 16:58 #8
Du kan vel også gøre noget à la:

<div style="position:relative;width:200px;height:100px;">
  <img src="trans.gif" style="width:100%;height:100%;position:absolute;left:0px;top:0px;z-index:2">
  En eller anden tekst her
</div>

Så vil billedet lægge sig ovenpå teksten og fylde hele div'et. På billedet kan du nu lægge din ondragstart-handler ... voila  ;o)
/mvh
Avatar billede olebole Juniormester
15. december 2003 - 16:59 #9
... og et lille-bitte swaaar  :)
Avatar billede roenving Novice
15. december 2003 - 17:52 #10
-- og velbekomme '-)
Avatar billede roenving Novice
15. december 2003 - 18:33 #11
-- tak for points ;~}
Avatar billede olebole Juniormester
15. december 2003 - 18:37 #12
... takker  :)
Avatar billede alvion Nybegynder
15. december 2003 - 19:31 #13
Velbekomme og tak for hjælpen.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester