Hierarchie in Array packen

Oh ja, kaum hat man etwas einigermaßen im Griff, muss man dafür auch noch eine Benutzeroberfläche schreiben, eine lästige Aufgabe.

Ich drück' mich im Moment auch etwas davor.
Meine derzeitige Idee ist, mit Parent und Previous zu arbeiten. Dem Nutzer würde ich dann eine Liste mit entsprechenden Links zur Auswahl anbieten.
Ungefähr so (id, titel), die roten Pfeile sollen dann die Links sein:
Code:
# (1, Food)
|   <- [parent=1, previous=1]
+---# (2, Fruit)
|   |   <- [parent=2, previous=2]
|   +---# (3, Cherry)
|   |   <- [parent=2, previous=3]
|   +---# (4, Banana)
|       <- [parent=2, previous=4]
|   <- [parent=1, previous=2]
+---# (5, Meat)
    |   <- [parent=5, previous=5]
    +---# (6, Pork)
    |   <- [parent=5, previous=6]
    +---# (7, Beef)
        <- [parent=5, previous=7]
    <- [parent=1, previous=5]
Wenn Parent==Previous, ist der neue lft-Wert=lft des parent + 1
sonst ist der neue lft-Wert=rgt des Previous + 1

Zu prüfen ist, ob es die Elemente mit den IDs gibt und ob parent==previous oder ob der Vater des Previous-Element wirklich die mit Parent übergebene ID hat.

Soweit im Moment meine Idee, nach der ich zumindest schon mal das Insert habe. Über das Userinterface denke ich aber noch nach. Das muss man natürlich deutlich übersichtlicher, als hier in den Code-Tags darstellen, aber wie?

Gruß hpvw
 
Hi,

Also ich habe es im Moment in zwei Sites gesplittet...
Die erste gefällt mir schon ganz gut (und erscheint auch logisch), aber die zweite macht mir noch Sorgen... Ein 0815 Anwender kann mit Begriffen wie "Kind" wahrscheinlich nichts anfangen. Anbei die beiden Screenshots.

Und die Sache mit verschieben habe ich auch schon (halbwegs) gelöst. Ich nutze einfach eine eigenes Flag "temporary_disabled" in der DB für den zu verschiebenden Baum. Damit werden diese Knoten in die Berechnung nicht mit einbezogen und ich kann sie sauber nummerieren.

Vielleicht kommen wir ja gemeinsam auf einen grünen Zweig was die GUI angeht?

Ciao,
Mike
 

Anhänge

  • screen1.jpg
    screen1.jpg
    96,4 KB · Aufrufe: 122
  • screen2.jpg
    screen2.jpg
    24 KB · Aufrufe: 72
Mik3e hat gesagt.:
Also ich habe es im Moment in zwei Sites gesplittet...
So hatte ich es auch gedacht.
Mik3e hat gesagt.:
Die erste gefällt mir schon ganz gut (und erscheint auch logisch), aber die zweite macht mir noch Sorgen... Ein 0815 Anwender kann mit Begriffen wie "Kind" wahrscheinlich nichts anfangen. Anbei die beiden Screenshots.
Die erste Ansicht gefällt mir auch. Allerdings würde ich in einer finalen Version die Anzeige von ID und Parent weglassen.

In der zweiten Ansicht würde ich den Baum erneut darstellen und, wie oben (miserabel) angedeutet, entsprechende Links mit Pfeilen oder Beschriftung "hier hin verschieben" zwischen die Elemente setzen. Als weitere Idee schwebt mir noch vor, den Baum in einem Drop-Down-Menü mit Einrückungen darzustellen und das was in dem anderen Beispiel die Links waren, als eingerückte Options-Punkte in das Drop-Down-Menü einzufügen.

Die "Vor-Nach-Kind-Variante" finde ich sehr unübersichtlich. In irgendeiner Anwendung hatte ich mal etwas ähnliches und fand es sehr mühsam mich damit zurecht zu finden. Außerdem glaube ich, dass es nicht eindeutig ist und unterschiedlich verstanden werden kann.

Mik3e hat gesagt.:
Und die Sache mit verschieben habe ich auch schon (halbwegs) gelöst. Ich nutze einfach eine eigenes Flag "temporary_disabled" in der DB für den zu verschiebenden Baum. Damit werden diese Knoten in die Berechnung nicht mit einbezogen und ich kann sie sauber nummerieren.
Kleine Warnung: Verenn' Dich nicht. Am Ende kommt ein Verwaltungsattribut nach dem anderen hinzu.

Gruß hpvw
 
Ja, wie gesagt.. ich finde diese VOR-NACH Geschichte auch nicht optimal...
Aber angenommen der Anwender hat 150 Knoten und möchte den letzen in die erste Kategorie verschieben... Der klickt sich dann einen Wolf bis es dort ist wo es sein soll ;)
Natürlich würde mir eine Variante mit kleine netten Pfeilchen auch besser gefallen...

Die Hierarchie (in vertikaler Form) wir derzeit auch schon in einem Drop-Down Feld abgebildet (siehe aktuellen Screenshot, hat im alten gefehlt).

Hat Du das Problem schon irgendwie in einer Art GUI gelöst oder bisher gar nicht?

Ich schreib mir übrigens grad selbst ein umfangreiches Tutorial zur MOVE-Funktion ;) Könnten wir ja hier im Tuts-Bereich veröffentlichen!?

Ciao,
Mike
 

Anhänge

  • screen2.jpg
    screen2.jpg
    28 KB · Aufrufe: 58
Mik3e hat gesagt.:
Ja, wie gesagt.. ich finde diese VOR-NACH Geschichte auch nicht optimal...
Aber angenommen der Anwender hat 150 Knoten und möchte den letzen in die erste Kategorie verschieben... Der klickt sich dann einen Wolf bis es dort ist wo es sein soll ;)
Natürlich würde mir eine Variante mit kleine netten Pfeilchen auch besser gefallen...
Man könnte auch mit CSS oder JavaScript die Unterkategorien aufklappen lassen. Ist aber auch nur eine Idee. Klicken muss er bei meiner Idee übrigens nicht ewig, eher noch viel mehr scrollen... Nicht, dass wir uns falsch verstanden haben.

Mik3e hat gesagt.:
Hat Du das Problem schon irgendwie in einer Art GUI gelöst oder bisher gar nicht?
Nein, ich habe bisher in meinen Testklassen immer manuell die Parent- und Previous-IDs in Formularfelder eingetragen

Gruß hpvw
 
Hm.. am optimalsten wäre natürlich eine Drag&Drop Lösung wie sie z.B. bei der Directory Struktur vom Explorer implementiert ist.. Das geht aber leider nicht... (oder nur sehr eingeschränkt mit mächtig großen Javascripts...

Ansonsten bin ich mit meinem Latein eigentlich ziemlich am Ende....
 
Eine Idee hab' ich noch:
Man könnte noch eine weitere "Entscheidungsstufe" einführen. Im ersten Schritt wird der Parent ausgewählt, dann werden nur dessen direkte Kinder (den Begriff musst Du dem User gegenüber ja nicht erwähnen) angezeigt und die Position unter Brüdern festgelegt.

Gruß hpvw

EDIT:
Mik3e hat gesagt.:
Hm.. am optimalsten wäre natürlich eine Drag&Drop Lösung ...
Die Idee hatte ich auch schon mal. Dafür hatte ich auch schon eine Testseite, allerdings nur innerhalb einer Ebene und bestimmt noch nicht optimal dargestellt. Außerdem ist es noch nicht valide, weil ich die Idee doch verworfen und nicht mehr zuende gearbeitet habe. Hier mein Code-Ansatz, falls Du die Idee weiter verfolgen willst:
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
<head>
<meta http-equiv="Content-Type"
    content="application/xhtml+xml; charset=UTF-8" />
<title>Drag-Drop-Test</title>
<style type="text/css" media="screen">
body,html {
    margin:0;
    padding:0;
    font-family:Arial, sans-serif;
}
h1 {
    margin:10px;
}
#dragdrop {
    list-style-type:none;
    margin:10px;
    padding:0;
    border:2px #000 solid;
}
#dragdrop li {
    margin:0;
    padding:0;
}
#dragdrop div.item {
    display:block;
    background:#eee;
    margin:0;
    padding:0.1em;
    line-height:1em;
}
#dragdrop div.drop {
    display:block;
    margin:0;
    padding:0.3em 0 0 0;
    background:#ddd;
}
#dragdrop div.lastDrop {
    display:block;
    margin:0;
    padding:0;
    height:0.3em;
    line-height:0.3em;
    background:#ddd;
    overflow:hidden;
}
</style>
<script type="text/javascript">
var dropactive=false;
var dropid=null;
var oldpos=null;

function startDrag(id,pos,sender) {
    dropactive=true;
    dropid=id;
    oldpos=pos;
    document.getElementsByTagName("body")[0].style.cursor="move";
}
function drop (pos,sender) {
    if (dropactive && pos!=oldpos && pos!=oldpos+1) {
        sender.style.background="#ddd";
        document.getElementsByTagName("body")[0]
            .style.cursor="default";
        
        Check = confirm("Move id ("+dropid
            +") from position ("+oldpos
            +") before position ("+pos+")?");
        if (Check) {
            /* Hier neue Seite mit Parameter aufrufen! */
            alert("doit");
        }
        stopDrag();
    }
}
function dragOver (pos,sender) {
    if (dropactive && pos!=oldpos && pos!=oldpos+1) {
        sender.style.background="#000";
    }
}
function dragOut (pos,sender) {
    if (dropactive && pos!=oldpos && pos!=oldpos+1) {
        sender.style.background="#ddd";
    }
}
function stopDrag() {
    dropactive=false;
    dropid=null;
    oldpos=null;
    document.getElementsByTagName("body")[0]
        .style.cursor="default";
}
document.onmouseup=stopDrag;
</script>
</head>
<body onselectstart="if (dropactive) return false;">
<h1>Edit the Menu</h1>
<ul id="dragdrop"><li>
<div class="drop"
    onmouseout="javascript:dragOut(1,this);"
    onmouseover="javascript:dragOver(1,this);"
    onmouseup="javascript:drop(1,this);"><div
    id="item1"
    class="item"
    onmousedown="javascript:startDrag(1,1,this);">Item
    1</div></div></li>
<li><div class="drop"
    onmouseout="javascript:dragOut(2,this);"
    onmouseover="javascript:dragOver(2,this);"
    onmouseup="javascript:drop(2,this);"><div
    id="item2"
    class="item"
    onmousedown="javascript:startDrag(2,2,this);">Item
    2</div></div></li>
<li><div class="drop"
    onmouseout="javascript:dragOut(3,this);"
    onmouseover="javascript:dragOver(3,this);"
    onmouseup="javascript:drop(3,this);"><div
    id="item3"
    class="item"
    onmousedown="javascript:startDrag(3,3,this);">Item
    3</div></div></li>
<li><div class="drop"
    onmouseout="javascript:dragOut(4,this);"
    onmouseover="javascript:dragOver(4,this);"
    onmouseup="javascript:drop(4,this);"><div
    id="item4"
    class="item"
    onmousedown="javascript:startDrag(4,4,this);">Item
    4</div></div><div
    class="lastDrop"
    onmouseout="javascript:dragOut(5,this);"
    onmouseover="javascript:dragOver(5,this);"
    onmouseup="javascript:drop(5,this);"></div></li>
</ul>
</body>
</html>
 
Zuletzt bearbeitet:
Hm..
Noch eine Idee (die auf Deiner aufbaut):

Der User wählt zuerst jenen Knoten, den er verschieben möchte. Danach bekommt er alle Kategorien Pro Ebene angezeigt und kann sich dann bis zu der Ebene durchklicken, auf der er den Knoten einfügen möchte (ähnlich Explorer).

Ich hab übrigens das Tut für "MOVE 2 NEW CHILD OF...." fertig.. Kann ich dir das irgendwie mailen?

Ciao
 
Zum "durch hierarchische Strukturen klicken" gibt es ja bereits diverse JavaScripts und als alternative eine PHP-Variante anzubieten sollte auch kein Problem sein. Bei besonders vielen Elementen ist das sicher keine schlechte Idee, um die Länge der Auswahlseite zu reduzieren.

Gruß hpvw
 
Stimmt.. Der Nachteil: Wenn Du nicht auswendig weißt, unter welchen Knoten sich der gewünschte befindet, kannst Du Dich auf die Suche machen... Wenn würde es nur mit einer "doppelten Ansicht" ähnlich Explorer gehen....

Ich hab dir das TUT per Mail geschickt.. die Algorithmen können sicher noch verbessert werden...
 
Zurück