Avatar billede nemitz Nybegynder
10. september 2004 - 21:14 Der er 31 kommentarer og
1 løsning

Skifte rækkefølge på div's

Hejsa!

Lige en tricky lille sag her.

Ville meget gerne kunne ændre placering på 2 div's dynamisk, altså uden at reloade siden.

eksempel:
<div id="1">indhold 1</div>
<div id="2">Indhold 2</div>

ved at klikke på en knap, bytter de 2 div's nu plads.
og bliver til:

<div id="2">indhold 2</div>
<div id="1">Indhold 1</div>

Skal bruges i forbindelse med afsnits opbygget CMS.
Et hint til søgning ville også være rart - eller endnu bedre til links på nettet med lignende funktioner.

På forhånd tak

Thomas
Avatar billede olebole Juniormester
10. september 2004 - 21:28 #1
<ole>

Det kan der ikke siges ret meget begavet om, før vi ved noget mere. Hvad omkranser f.eks. de to div? Kan der være flere end to div? Info ... info ... info  :)

/mvh
</bole>
Avatar billede nemitz Nybegynder
10. september 2004 - 21:33 #2
hejsa ole.

der skal være flere end de 2 div's ja, og de kunne evt. ligge inden i en anden div.

Det er målet at opnå en visuel effekt af 2 rows/rækker der skifter plads.
Avatar billede olebole Juniormester
10. september 2004 - 21:53 #3
Ja, det kan jeg godt forestille mig, men man er nødt til at tage fat i det omkransende element for at lykkes med noget. Derfor er det vigtigt, hvordan de ligger i forhold til resten af koden.

Ligger de i et andet div ... "de kunne evt. ligge inden i en anden div" er ikke en brugbar information.

Ligger der andre elementer, der skal blive liggende, i det omkransende element?
Avatar billede olebole Juniormester
10. september 2004 - 21:54 #4
... og kan der evt. være fire div - og hvordan ved jeg så i hvilken rækkefølge, de skal sorteres  :)
Avatar billede nemitz Nybegynder
10. september 2004 - 21:57 #5
der skal være en knap der siger "up" og en knap der siger "down" f.eks.
Og så ligger den div man klikker på sig op over diven over sig selv.
Avatar billede olebole Juniormester
10. september 2004 - 22:29 #6
Så kunne det vel gøres noget à la:

<script type="text/JavaScript">
var d=document;
function gE(id){return d.getElementById(id)}

function myMove(elm, dir) {
    var elmHTML, elmID, prevElm, nextElm, newElm;
    elm = elm.parentNode;
    elmHTML = elm.innerHTML
    elmID = elm.id;
    newElm = d.createElement("DIV");
    newElm.id = elmID;
    newElm.innerHTML = elmHTML;
    if (dir=="up" && elm.previousSibling) {
        prevElm = elm.previousSibling;
        gE("cont").removeChild(elm);
        prevElm.insertAdjacentElement("BeforeBegin", newElm);
    }
    else if (dir=="down" && elm.nextSibling) {
        nextElm = elm.nextSibling;
        gE("cont").removeChild(elm);
        nextElm.insertAdjacentElement("AfterEnd", newElm);
    }
}
</script>

<style type="text/css">
#cont div {
    padding: 5px 10px;
    margin: 3px;
    background-color: #6699ff;
    border: 1px solid #003399;
}
</style>

<div id="cont">
    <div id="ID_0">Nummer 0 <button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></div>
    <div id="ID_1">Nummer 1 <button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></div>
    <div id="ID_2">Nummer 2 <button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></div>
    <div id="ID_3">Nummer 3 <button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></div>
    <div id="ID_4">Nummer 4 <button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></div>
</div>

/mvh
Avatar billede olebole Juniormester
10. september 2004 - 22:31 #7
insertAdjacentElement er en proprietær IE-metode - men da det er et CMS, går jeg udfra, du udelukkende skriver til IE  :)
Avatar billede nemitz Nybegynder
10. september 2004 - 22:44 #8
Ohhh my god!

Takker uendeligt mange gange...
Det var da det lækreste lille script jeg har set længe!

Endnu engang mange tak og smid lige et svar så du kan få dine velfortjente point!

/Thomas
Avatar billede nemitz Nybegynder
10. september 2004 - 22:59 #9
Hehe når du nu alligevel kigger forbi efter dine point...

Hvordan tildeler vi så nemmest et form felt i hver div, row/række nummeret den ligger på?

Thomas
Avatar billede olebole Juniormester
10. september 2004 - 23:26 #10
Jeg skal lige vide, om du mener: "... når siden gemmes"? I så fald kunne det gøres sådan:

<script type="text/JavaScript">
var d=document;
function gE(id){return d.getElementById(id)}
function gA(o,tag){return o.getElementsByTagName(tag)}

function mySave() {
    var inpts, divs = gA(gE("cont"), "DIV");
    for ( i=0; i<divs.length; i++ ) {
        inpts = gA(divs[i], "INPUT");
        for ( j=0; j<inpts.length; j++ ) {
            if (inpts[j].className=="showInxInp") {
                inpts[j].value = i;
                break;
            }
        }
    }
}

function myMove(elm, dir) {
    var elmHTML, elmID, prevElm, nextElm, newElm;
    elm = elm.parentNode;
    elmHTML = elm.innerHTML
    elmID = elm.id;
    newElm = d.createElement("DIV");
    newElm.id = elmID;
    newElm.innerHTML = elmHTML;
    if (dir=="up" && elm.previousSibling) {
        prevElm = elm.previousSibling;
        gE("cont").removeChild(elm);
        prevElm.insertAdjacentElement("BeforeBegin", newElm);
    }
    else if (dir=="down" && elm.nextSibling) {
        nextElm = elm.nextSibling;
        gE("cont").removeChild(elm);
        nextElm.insertAdjacentElement("AfterEnd", newElm);
    }
}
</script>

<style type="text/css">
#cont div {
    padding: 5px 10px;
    margin: 3px;
    background-color: #6699ff;
    border: 1px solid #003399;
}
</style>

<div id="cont">
    <div id="ID_0">Nummer 0 <input type="text" class="showInxInp"><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></div>
    <div id="ID_1">Nummer 1 <input type="text" class="showInxInp"><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></div>
    <div id="ID_2">Nummer 2 <input type="text" class="showInxInp"><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></div>
    <div id="ID_3">Nummer 3 <input type="text" class="showInxInp"><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></div>
    <div id="ID_4">Nummer 4 <input type="text" class="showInxInp"><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></div>
</div>

<button onclick="mySave()">Save</button>

... er det noget, du kan bruge?
Du må selv lave felterne om til type="hidden". Nu er de af typen "text", så du kan se, hvad der sker.
Du har også mulighed for at have flere felter i hvert div. Scriptet rører kun ved det felt i hvert div, der har fået sat klassen 'showInxInp'.
/mvh
Avatar billede nemitz Nybegynder
10. september 2004 - 23:38 #11
Jamen jamen.... endnu engang tak, det var bare perfekt.

Så ser det jo ud til at vi(læs du) har fået det til at virke!

Tak tak, og smid så lige et svar :D
Avatar billede olebole Juniormester
10. september 2004 - 23:46 #12
Selvtak  :)

Lige en kort forklaring: Som du kan se skriver jeg øverst:

var d=document;
function gE(id){return d.getElementById(id)}
function gA(o,tag){return o.getElementsByTagName(tag)}

Det er blot nogle wrappers, fordi jeg er doven og ikke gider skrive laaaange udtryk, når det kan undgåes - og hvis de skal skrives ofte.

At skrive gE("cont") svarer således til at skrive:
  document.getElementById("cont")

At skrive gA(gE("cont"), "DIV") svarer til at skrive (hold fast):
  document.getElementById("cont").getElementsByTagName("DIV")

/mvh
Avatar billede nemitz Nybegynder
11. september 2004 - 00:30 #13
Hej Ole!

Når vi nu bruger "this" som parameter til functionen, får vi et problem da vi ligger knapperne "UP" and "Down" i en span. Så kommer "this" jo til at repræsentere span'en istedet for den div vi ønsker at flytte...

Hvordan kan man smartest putte den rigtige ID eller reference med functions kaldet?

På forhånd tak og hermed point.

Thomas
Avatar billede olebole Juniormester
11. september 2004 - 00:42 #14
Ja, det kunne man godt tro, men det har jeg taget højde for. Så snart, vi rammer funktionen, bliver referencen sat til knappens 'parentNode' = div'et. Lad os lige tage funktionen fra toppen:

function myMove(elm, dir) {
  // Deklarer funktionens private variabler (så er det gjort ét sted)
    var elmHTML, elmID, prevElm, nextElm, newElm;

  // Sæt elm = knappens omkransende element (div'et)
    elm = elm.parentNode;

  // Læs div'ets indhold og gem det i en variabel
    elmHTML = elm.innerHTML

  // Læs div'ets id og gem den i en variabel
    elmID = elm.id;

  // Opret et nyt element og giv det indhold og id
  // Vi klistrer ikke elementet ind endnu
    newElm = d.createElement("DIV");
    newElm.id = elmID;
    newElm.innerHTML = elmHTML;

  // Hvis up-knappen blev klikket og div'et ikke er det første i rækken
    if (dir=="up" && elm.previousSibling) {
      // Find elementet før div'et og gem en reference til det i en variabel
        prevElm = elm.previousSibling;
      // Slet det oprindelige div
        gE("cont").removeChild(elm);
      // Indsæt det nye element på det rigtige sted
        prevElm.insertAdjacentElement("BeforeBegin", newElm);
    }
    else if (dir=="down" && elm.nextSibling) {
        nextElm = elm.nextSibling;
        gE("cont").removeChild(elm);
        nextElm.insertAdjacentElement("AfterEnd", newElm);
    }
}

Sidste if-sætning skulle du så nok kunne hitte ud af  ;o)
Hjalp det på forståelsen?
/mvh
Avatar billede olebole Juniormester
11. september 2004 - 00:46 #15
Lidt mere forklaring: Ordet 'sibling' betyder på engelsk 'søskende'.

'ELEMENT.previousSibling' er således et elements foranliggende 'søskende' (elementet før).

'ELEMENT.nextSibling' er derfor elementets efterfølgende 'søskende' (elementet efter).
Avatar billede nemitz Nybegynder
11. september 2004 - 00:59 #16
Hvis jeg forstår dig ret, siger du at der er taget højde for at vi putter knapperne i en span inden i diven? Sttrukturen ser sådan her ud...
<div><span><input type="text"> text her </span><span> knapper </span></div>

Når vi bruger din function og HTML kode som det er giver det ingen problemer, men så snart vi sætter spans omkring fejler det...

Jeg skal vel så der hvor du deklarerer "elm = elm.parentNode;" bruge dens parent af parent eller hvad? og hvordan d..... gør man det?
Som du nok har fundet ud af er JS ikke lige vores stærke side.

Thomas
Avatar billede nemitz Nybegynder
11. september 2004 - 01:12 #17
Dohhh den har jeg så selv løst... Du siger ingenting... :D
"elm = elm.parentNode.parentNode;"

Hehe takker  for forklaringen og al hjælpen, må sige at DOM og JS kan nogle lidt fede ting..
Avatar billede olebole Juniormester
11. september 2004 - 01:40 #18
Ja, der er zq vitaminer i JS/DOM  ;o)
Avatar billede olebole Juniormester
11. september 2004 - 01:42 #19
PS: og jeg overså fuldstændig detaljen med span'ene, men det fandt du jo heldigvis selv ud af ... sorry  :)
Avatar billede nemitz Nybegynder
11. september 2004 - 02:38 #20
Hej igen.
Håber du stadig kigger på denne post OleBole.
Vi har nemlig fundet et lille skummelt problem, for det viser sig nemlig at funktionen fint nok gemmer innerhtml'en fra div'en der flyttes, men da der nu ligger 2 spans i denne div, tæller de åbenbart ikke med som "innerhtml" da de er et child til div'en...

Er der en måde hvorpå vi kan få scriptet til at tage koden med fra de 2 spans?

Lover at jeg nok snart skal lade dig få lidt fred... hehe

Thomas
Avatar billede olebole Juniormester
11. september 2004 - 03:05 #21
Hej igen, Thomas  :)
Jeg har altså ingen probs med det her:

<script type="text/JavaScript">
var d=document;
function gE(id){return d.getElementById(id)}
function gA(o,tag){return o.getElementsByTagName(tag)}

function mySave() {
    var inpts, divs = gA(gE("cont"), "DIV");
    for ( i=0; i<divs.length; i++ ) {
        inpts = gA(divs[i], "INPUT");
        for ( j=0; j<inpts.length; j++ ) {
            if (inpts[j].className=="showInxInp") {
                inpts[j].value = i;
                break;
            }
        }
    }
}

function myMove(elm, dir) {
    var elmHTML, elmID, prevElm, nextElm, newElm;
    elm = elm.parentNode.parentNode;
    elmHTML = elm.innerHTML
    elmID = elm.id;
    newElm = d.createElement("DIV");
    newElm.id = elmID;
    newElm.innerHTML = elmHTML;
    if (dir=="up" && elm.previousSibling) {
        prevElm = elm.previousSibling;
        gE("cont").removeChild(elm);
        prevElm.insertAdjacentElement("BeforeBegin", newElm);
    }
    else if (dir=="down" && elm.nextSibling) {
        nextElm = elm.nextSibling;
        gE("cont").removeChild(elm);
        nextElm.insertAdjacentElement("AfterEnd", newElm);
    }
}
</script>

<style type="text/css">
#cont div {
    padding: 5px 10px;
    margin: 3px;
    background-color: #6699ff;
    border: 1px solid #003399;
}
</style>

<div id="cont">
    <div id="ID_0"><span><input type="text" class="showInxInp"> Nummer 0 </span><span><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></span></div>
    <div id="ID_1"><span><input type="text" class="showInxInp"> Nummer 1 </span><span><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></span></div>
    <div id="ID_2"><span><input type="text" class="showInxInp"> Nummer 2 </span><span><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></span></div>
    <div id="ID_3"><span><input type="text" class="showInxInp"> Nummer 3 </span><span><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></span></div>
    <div id="ID_4"><span><input type="text" class="showInxInp"> Nummer 4 </span><span><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></span></div>
</div>

<button onclick="mySave()">Save</button>

/mvh
Avatar billede nemitz Nybegynder
11. september 2004 - 03:09 #22
kigger lige på det...

Måske prob ligger i at vi forsøger at floate den ene div left og den anden right.??..
Avatar billede nemitz Nybegynder
11. september 2004 - 03:21 #23
Du har ret, virker fint, problemet opstår når vi forsøger "float: left;" på den første og "float: right;" på den sidste span.

Fatter det ikke, har samme kode på en side jeg lavede sidste dag og der er der ingen problemer med min opbygning.

Tjekker lige om det kunne være de der store lede knapper :D  men tror nu nærmere det er noget med stylen eller noget den får galt i halsen.
Avatar billede olebole Juniormester
11. september 2004 - 04:14 #24
oki ... ellers må du komme tilbage med noget, jeg kan kikke på  :)
Avatar billede nemitz Nybegynder
11. september 2004 - 04:43 #25
Hej igen Ole.

Mange tak for hjælpen i aften/nat, vi stopper nu og har indtil videre fået det til at køre som det skal. Problemet var noget så simpelt som den padding der var på div'en der indeholdt de 2 spans.
Af en eller anden grund "stak" spansne udenfor div'en og lavede derfor en ikke tilsigtet ombrydning.

Vi har flere vilde planer med dit lille script, men de må vente til i morgen, nu skal der soves lidt.

Go'nat
Avatar billede nemitz Nybegynder
11. september 2004 - 17:18 #26
Hej OleBole er du stadig tilstede?

Har fundet et nyt problem i scriptet, eller det er vel nærmere en udbygning af det.
Når man creater den nye DIV, har den tilsyneladende ikke de samme egenskaber som den DIV den genskaber.
Jeg mener; når vi fjerner en DIV og indsætter den et andet sted, har den nye DIV ikke den gamle divs "class" med.
Så er spørgsmålet hvordan sætter jeg class på det nye element til f.eks. "newclass".

//Ny DIV skabes
newElm = d.createElement("DIV");
//Den nye DIV tildeles ID fra den gamle
newElm.id = elmID;
// Her forsøger jeg så at sætte classen til newclass
newElm.class = "newclass";

Hvad er der galt??

Håber du stadig kigger & på forhånd tak

Thomas
Avatar billede olebole Juniormester
11. september 2004 - 17:36 #27
newElm.className = "newclass";  ;o)

Men i stedet for at give det et bestemt klasse-navn, så hold i stedet scriptet generisk:

newElm.className = elm.className;
Avatar billede nemitz Nybegynder
11. september 2004 - 17:41 #28
newElm.className
haha fandt det også lige selv, men selvf. er det smartere at bruge den tidligere classe.

Endnu endnu... engang tak
Avatar billede olebole Juniormester
11. september 2004 - 17:44 #29
Hehe ... selvtak  ;o)
Avatar billede nemitz Nybegynder
11. september 2004 - 17:45 #30
Det bliver dælme for nice det her...
Nu virker det flawless!

skal du lige ha et sneak peak OleBole? Så smid en mail til bokser@wanadoo.dk
Avatar billede olebole Juniormester
11. september 2004 - 21:44 #31
... og her er den så i en mere X-browser version. Den funker i Win/IE, Win/Moz, Win/Opera, men er ikke testet i Firefox - eller under MacOs  :)

<script type="text/JavaScript">
var d=document;
function gE(id){return d.getElementById(id)}
function gA(o,tag){return o.getElementsByTagName(tag)}

function mySave() {
    var inpts, divs = gA(gE("cont"), "DIV");
    for ( i=0; i<divs.length; i++ ) {
        inpts = gA(divs[i], "INPUT");
        for ( j=0; j<inpts.length; j++ ) {
            if (inpts[j].className=="showInxInp") {
                inpts[j].value = i;
                break;
            }
        }
    }
}
function findParObj(elm, tag) {
    for (i=0; elm.tagName!=tag; elm = elm.parentNode);
    return elm;
}
function myMove(elm, dir) {
    var newElm, aDivs, cont=gE("cont");
    elm = findParObj(elm, "DIV");
    newElm = elm.cloneNode(true);
    aDivs = gA(cont, "DIV");
    if (dir=="up") {
        for ( i=1; i<aDivs.length; i++ ) {
            if ( aDivs[i]==elm ) {
                cont.removeChild(elm);
                cont.insertBefore(newElm, gA(cont, "DIV")[i-1]);
            }
        }
    }
    else if (dir=="down") {
        for ( i=1; i<aDivs.length; i++ ) {
            if ( aDivs[i-1]==elm ) {
                cont.removeChild(elm);
                if (aDivs.length>i) cont.insertBefore(newElm, gA(cont, "DIV")[i]);
                else cont.appendChild(newElm);
                break;
            }
        }
    }
    if (navigator.userAgent.toLowerCase().indexOf("opera")==-1) cont.innerHTML = cont.innerHTML + ""
}
</script>

<style type="text/css">
#cont div {
    padding: 5px 10px;
    margin: 3px;
    background-color: #6699ff;
    border: 1px solid #003399;
}
</style>

<div id="cont">
    <div id="ID_0"><span><input type="text" class="showInxInp"> Nummer 0 </span><span><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></span></div>
    <div id="ID_1"><span><input type="text" class="showInxInp"> Nummer 1 </span><span><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></span></div>
    <div id="ID_2"><span><input type="text" class="showInxInp"> Nummer 2 </span><span><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></span></div>
    <div id="ID_3"><span><input type="text" class="showInxInp"> Nummer 3 </span><span><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></span></div>
    <div id="ID_4"><span><input type="text" class="showInxInp"> Nummer 4 </span><span><button onclick="myMove(this, 'up')">Up</button><button onclick="myMove(this, 'down')">Down</button></span></div>
</div>

<button onclick="mySave()">Save</button>

/mvh
Avatar billede nemitz Nybegynder
12. september 2004 - 00:01 #32
Det virker umiddelbart fint i FireFox. Du er en helt olebole ;-)
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