Avatar billede webstuff Nybegynder
08. februar 2008 - 15:16 Der er 13 kommentarer og
1 løsning

DOM resize tabel ved drag med mus

Hejsa

Er der nogen herinde der kan komme med nogle guldkorn til hvordan man nemmest laver et script der kan ændre bredden på kolonner i en tabel når man trækker i kanten af en kolonne med musen.

Jeg bruger DOM til at oprette tabellerne, og de kan maks indeholde een række hver.

    function CreateTable()
    {
        var num_c = document.getElementById("cols").value;
        var td  = new Array();
       
        var mother = document.getElementById("AppendHere");
        var table = document.createElement("TABLE");
        var tbody = document.createElement("TBODY");
        var row = document.createElement("TR");   
       
        for(var i=0; i<num_c; i++)
        {
            td[i] = document.createElement("TD");
            td[i].appendChild(document.createTextNode('hej'+(i+1)));
            row.appendChild(td[i]);
        }
        tbody.appendChild(row);
        table.appendChild(tbody);
        table.setAttribute("border", "1");
        mother.appendChild(table);
    }

Mvh. Andreas
Avatar billede webstuff Nybegynder
08. februar 2008 - 16:17 #1
Jeg fandt i et gammelt spørgsmål et svar fra roenvig der foreslog at sætte en 1-2px bred celle i mellem hver af cellerne som holder styr på om der bliver trykket og hevet i den, og derefter regner bredden ud for den pågældende celle før.
Avatar billede roenving Novice
09. februar 2008 - 14:18 #2
Ja, og det er sikkert affødt af, at man ikke kan registrere handlinger specielt på en border ...
Avatar billede webstuff Nybegynder
09. februar 2008 - 16:55 #3
Men du har ikke andre kvalificerede bud på hvordan det kan løses?
Avatar billede olebole Juniormester
09. februar 2008 - 17:05 #4
<ole>

Der er ikke forskel på en tabel, oprettet med DOM - og én, der bare er skrevet i dokumentet. Du kan vel bare bruge roenvings eksempel i DOM ... omend det kan være vanskeligt at kode sig udenom memory leaks i bl.a. cirkulære referencer, når man bruger events i forbindelse med DOM. I den forbindelse er det i øvrigt klogt at gøre tingene i en anden rækkefølge:

    function CreateTable()
    {
        var num_c = document.getElementById("cols").value;
        var td  = new Array();
       
        var mother = document.getElementById("AppendHere");
        var table = document.createElement("TABLE");
        mother.appendChild(table);
        table.setAttribute("border", "1");
        var tbody = document.createElement("TBODY");
        table.appendChild(tbody);
        var row = document.createElement("TR");
        tbody.appendChild(row); 
       
        for(var i=0; i<num_c; i++)
        {
            td[i] = document.createElement("TD");
            row.appendChild(td[i]);
            td[i].appendChild(document.createTextNode('hej'+(i+1)));
        }
    }

/mvh
</bole>
Avatar billede webstuff Nybegynder
11. februar 2008 - 08:55 #5
Hej Ole

Det var nu ikke fordi jeg ikke kunne bruge roenvigs idé heller - det var mere for at høre om der var andre gode ideer til hvordan det kunne løses, da jeg stadig mangler lidt forståelse for hvordan det helt præcist skal gøres.

Og mange tak for opdateringen af koden :-)
Avatar billede webstuff Nybegynder
11. februar 2008 - 11:14 #6
Jeg har pt. dette script som kun virker i FF og kun hvis man tast <= 5 antal kolonner ind af gangen.

----------------------------------------------------------------------------
<html>
<style>
.tabel { width: 100%; }
</style>
<head>
<script type="text/javascript">
var c=0;
var draggin = false;
    function CreateTable()
    {
        var num_c = document.getElementById("cols").value;
        var td  = new Array();
        var dd  = new Array();
       
        var mother = document.getElementById("AppendHere");
        var table = document.createElement("TABLE");
        var tbody = document.createElement("TBODY");
        var row = document.createElement("TR");   
       
        for(var i=0; i<(num_c*2); i+=2)
        {
            /* Creating all the cells */
            td[i] = document.createElement("TD");
            td[i].appendChild(document.createTextNode('hej'+(i+1)));
            td[i].setAttribute("id", "cell_"+c+"_"+i);
            row.appendChild(td[i]);
           
           
            /*here creating all the div in between the cells to drag and drop */
            td[(i+1)] = document.createElement("TD");
           
            dd[(i+1)] = td[(i+1)].appendChild(document.createElement("DIV"));
            dd[(i+1)].setAttribute("onmousemove", "startDrag(this.id, event.clientX);");
            dd[(i+1)].setAttribute("onmousedown", "setDragTrue();");
            dd[(i+1)].setAttribute("onmouseup", "setDragFalse();");
            dd[(i+1)].setAttribute("onmouseover", "activeBg(this.id);");
            dd[(i+1)].setAttribute("onmouseout", "inactiveBg(this.id);");
            dd[(i+1)].setAttribute("style", "width: 2px; background-color: #000;");
            dd[(i+1)].setAttribute("id", "drags_"+c+"_"+i);
            dd[(i+1)].appendChild(document.createTextNode('|'));
           
            row.appendChild(dd[(i+1)]);
           
        }
       
        /* Creating the rest of the <table> */
        tbody.appendChild(row);
        table.appendChild(tbody);
        table.setAttribute("border", "1");
        table.setAttribute("id", "table"+c);
        mother.appendChild(table);
       
        for(var i=0; i<=c; i++)
        {
            /* Setting all the <table> elements to className = "tabel" */
            document.getElementById("table"+i).className = "tabel";
        }
       
        c++;
    }
    function activeBg(elm)
    {
        document.getElementById(elm).style.cursor = 'e-resize';
    }
    function inactiveBg(elm)
    {
        document.getElementById(elm).style.cursor = 'default';
    }
    function setDragTrue()
    {   
        draggin = true;
    }
    function setDragFalse()
    {
        draggin = false;
    }
    function startDrag(elm, mx)
    {
        if(draggin)
        {
            var cell = document.getElementById('cell_'+elm[6]+'_'+elm[8]);
            cell.style.width = (mx-cell.offsetLeft)-15 + "px";
        }
       
    }
</script>
</head>
<body>
<div id="AppendHere">

</div>
Cols: <input type="text" name="cols" id="cols" value="1" /><br />
<input type="button" value="Table it" onclick="CreateTable();" />
</body>
</html>
----------------------------------------------------------------------------

Jeg ved godt hvad der forårsager at det ikke virker i IE, og at det ikke virker med mere end 5 kolonner, så det er ikke det spørgsmålet går ud på.
Men som i kan se, har jeg næsten fået scriptet til at virke, dog på ingen måde optimalt.
Så vil høre om der er nogen der kan pointe mig i den rigtige retning til en bedre løsning.
Avatar billede olebole Juniormester
11. februar 2008 - 19:00 #7
Jeg ville tage det i en anden rækkefølge for at undgå leaks:

1) opret en table
2) opret en tbody og append den til tabellen
3) opret en tr og append den til tbody
4) opret i en løkke de ønskede td'er og append dem til tr
5) append din table til et element i dokument træet
6) sæt i en ny løkke event-handlers på de ønskede elementer

onmousemove event'en skal aftastes på dokument objektet - ellers 'taber' du hele tiden 'move elementet'.

Event-handlers må ikke sættes med setAttribute, men sættes med attachEvent i IE og addEventListener i andre DOM-kompatible browsere
Avatar billede webstuff Nybegynder
12. februar 2008 - 09:28 #8
Mange tak for svaret ole.
Kan du forklare lidt om hvorfor man ikke må sætte event handlers via setAttribute?
Avatar billede webstuff Nybegynder
12. februar 2008 - 11:56 #9
Jeg har fundet ud af det ved at bruge jQuery i stedet.
Lægger I et svar begge to?
Avatar billede olebole Juniormester
12. februar 2008 - 21:11 #10
Du har mulighed for at sætte forskellige attributter på et tag (altså det, du skriver i et dokument - og som implementerer et element i dokumentets DOM-træ). Nogle af disse attributter implementerer event handlers på de elementer, som tagget implementerer.

Attributter/properties på DOM-elementer sættes og læses normalt med set-/getAttribute, men der er undtagelser. F.eks. må dynamiske properties, som 'value' og 'checked' på input elementer ikke kunne læses med getAttribute. Den må i følge standarden kun returnere, hvad der står skrevet i selve tagget. Faktisk findes der idag ikke en DOM-metode til aflæsning af dynamiske properties på DOM-elementer(!) I stedet er man nødt til at bruge IDL

Event-handlers er som sagt en anden undtagelse. De sættes med addEventListener, men IE bruger den ikke standardiserede attachEvent
Avatar billede webstuff Nybegynder
14. februar 2008 - 20:55 #11
mange tak for info ole.

roenvig, vil du have points?
Avatar billede roenving Novice
15. februar 2008 - 12:47 #12
Nah, ellers tak, det er jo ole, der har lavet arbejdet i denne tråd !-)
Avatar billede webstuff Nybegynder
15. februar 2008 - 17:09 #13
helt i orden.
men i hvertfald tak for hjælpen begge to :-)
Avatar billede olebole Juniormester
15. februar 2008 - 17:33 #14
Selvtak - og tak for points  ;o)
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