Menüleiste sortieren

hoizwurm

Erfahrenes Mitglied
Hallo Leute!

Wende mich mit einem Problem an Euch (Na was wohl sonst :rolleyes: ).
Es geht um folgendes:

Ich habe eine Homepage mit einem kleinen CMS dahinter. In diesem sind die
ganzen verschiedenen Beiträge in Kategorien unterteilt. Diese Kategorien bilden
dann wieder die einzelnen Menüpunkte.
Momentan ist es so, das die Menüpunkte einfach nach Ihrer entsprechenden ID in
der Datenbank sortiert ausgegeben werden. Ich habe also keine Möglichkeit, das
ich z.B. zwischen 1tem und 2tem Menüpunkt einen Neuen einschiebe.

Ich habe mir das so überlegt, das ich in der Tabelle mit den Kategorien eine
weitere Spalte anlege mit der ich die Reihenfolge festlege. Bis zu dem Punkt auch
kein Problem.

Ich möchte es aber jetzt möglich machen, das ich mir die Kategorien (also die
Menüpunkte) in einer Tabelle auflisten lasse und daneben, dann noch jeweils
einen kleinen Button der mir dann den Menüpunkt um eine Stelle nach oben rückt.

Das alleine ist auch noch nicht das Problem, aber wenn ich jetzt hergehe, und
eine Kategorie aus welchen Gründen auch immer herauslösche, dann habe ich
ja "Löcher" in der Reihenfolge.

Ja und genau an dem Punkt habe ich jetzt so ziemlich einen großen Knopf im
Hirn und der will einfach nicht so recht aufgehen.

Ich hoffe ich habe mich nicht zu umständlich ausgedrückt.
Wäre nett wenn mir da jemand einen Denkanstoß geben könnte wie ich das am
geschicktesten anstelle, das ich da auf eine funktionierende Lösung komme.

mfg Hoizwurm
 
Also, wenn ich etwas manuell sortieren möchte, mache ich das immer so, dass ich in der Tabelle wo die zu sortierenden Daten liegen eine neue Spalte mit dem namen "sortid" anlege und die Reihenfolge dann manuell bestimme.

Beim Auslesen, natürlich: ...ORDER BY sortid...

Naja, zu deinem konkreten Problem fällt mir grade auch nichts ein... ;)

PHP:
$i=1;
$query=mysql_query("SELECT * FROM tabelle ORDER BY sortid'");
while($data=mysql_fetch_array($query))
{
  if($i!=$data[sortid])
  {
    //sortid der folgenden Einträge jeweils um einen abziehen
  }
  $eintraege++;
}
Ungetestet und schnell runtergetippt ;)

Ist mir grade so in den Kopfgeschossen, vieleicht hilfts ja weiter...
 
Hallo Lars!

Das mit der Ausgabe, ist genau das wie ich es am Ende haben möchte.

Beim durchlesen deines Posts, ist mir jetzt eine Idee gekommen, die Einträge
in der Spalte sortid brauchen ja gar nicht von 1...n durchgehend sein oder?

Also würde es ja reichen wenn ich jetzt z.B. die Kategorie 3 vor die Kategorie 2
legen möchte, einfach deren sortid Einträge vertausche, und dann ist das ganze nicht mehr die große Hexerei.

Werde das heute Abend mal abchecken und wen´s funktioniert hier nochmal
reinposten.

Danke hat mir fürs erste mal geholfen.

mfg Hoizwurm
 
Man kann ja bei jedem Löschen die Sortierung neu schreiben. Da auf Rubriken wohl am meisten lesend zugegriffen wird, kann man diesen Aufwand noch verschmerzen (unter Umständen müssen alle Rubriken angepasst werden).

Wichtig dabei ist dann vielleicht, dass du die Tabelle für schreibende Zugriffe sperrst:
LOCK TABLES tabelle WRITE

Am Ende kannst du die Sperre wieder rauswerfen:

UNLOCK TABLES

Während der Sperre kann nur der aktuelle Thread (also im wesentlichen das Script mit der DB Connection, die die Sperre veranlasst hat) schreiben.

-------------------

Andere Möglichkeit: Du ermittelst immer den nächsten Sort Wert in der entsprechenden Richtung (Up oder Down) und vertauschst bei beiden Rubriken den entsprechenden Wert. Problem: Wenn du ganz oben bist, darf es nicht weiter gehen, wenn du am Ende bist sollte der Sort Wert ebenfalls nicht erhöht werden.
Ein weiteres Problem an dieser Methode sind komische Sprünge. Durch dumme Zufälle oder Fehler in der Programmierung können mehrere DB Einträge die selbe Sortiernummer aufweisen. Kommt dann nun eine Rubrik von unten nach oben, wechselt es die Sortiernummer mit dem letzten Eintrag dieses Blocks aus selben Nummern. Beim nächsten Schritt überspringt es allerdings die ganzen anderen Einträge vor ihm, da sie ja ebenfalls die selbe Nummer hatten.....

Naja, also ich wäre dafür, beim Löschen immer wieder das Loch zu schließen. Du kannst das mit nem einfachen Query machen:

UPDATE tabelle SET sort = sort - 1 WHERE sort > XXX

Für XXX muss die sort Nummer der gelöschten Rubrik rein. Falls du da einen Baum in deiner Datenbank verwaltest, musst du natürlich das Query noch anpassen.

Ciao, Jörg
 
Beim durchlesen deines Posts, ist mir jetzt eine Idee gekommen, die Einträge
in der Spalte sortid brauchen ja gar nicht von 1...n durchgehend sein oder?

Also würde es ja reichen wenn ich jetzt z.B. die Kategorie 3 vor die Kategorie 2
legen möchte, einfach deren sortid Einträge vertausche, und dann ist das ganze nicht mehr die große Hexerei.

Klar, so mache ich es bisher auch :)
Nur treten durchs Löschen schon mal Lücken auf und es wirkt ja wesentlich professioneller, wenn das nicht passieren kann ;)

Also, ich bin auch an der Lösung interessiert, werd dass dan gleich in meine Scripts einarbeiten :)
 
F.o.G. hat gesagt.:
Naja, also ich wäre dafür, beim Löschen immer wieder das Loch zu schließen.
Du kannst das mit nem einfachen Query machen:

UPDATE tabelle SET sort = sort - 1 WHERE sort > XXX

Für XXX muss die sort Nummer der gelöschten Rubrik rein. Falls du da einen
Baum in deiner Datenbank verwaltest, musst du natürlich das Query noch
anpassen.

Ciao, Jörg

Also das wird glaube ich genau mein Ding werden. Melde mich morgen wenn ich
es habe (hoffentlich) ;)

mfg Hoizwurm
 
Hallo Leute!

Also ich habe mit Eurer Hilfe das Problem gelöst. Ist wahrscheinlich nicht gerade
sehr elegant, aber es funktioniert.
Als erstes mal einen Überblick über die Tabelle:

ID | section | farbe | logo | seite | beschreibung | sortid

Die Spalte Seite ist bei mir deshalb, da mehrere Seiten mit dem einen Script verwaltet werden, die gar nichts miteinander zu tun haben. Ansonsten ist glaube
ich alles klar.

Hier die Seite wo die Kategorien angezeigt und verschoben werden können:

PHP:
 <table align="left">
<tr>
<td height="15">sortid</td>
<td width="120" height="15">Kategorienname</td>
<td colspan="3" height="15">Funktionen</td>
</tr>

<?
// Abfrage aller in KAtegorien für diese Seite sortiert nach der Spalte sortid
@$outcome=mysql_query("SELECT * FROM sections WHERE seite=$seite ORDER BY sortid");
require("failure.php");

// Schleife zum ausgeben ist eh klar
while ($access=mysql_fetch_array($outcome))
{
$id=$access["ID"];
$section=$access["section"];
$sortid=$access["sortid"];


echo"
<tr>
<td>$sortid</td>
<td class=\"font1\">$section</td>
<td><a href=\"editkategorie.php?id=$id\"><img border=\"0\" src=\"images/tool_smedit.png\" height=\"10\" alt=\"Kategorie bearbeiten\"></a></td>
<td><a href=\"modify.php?command=8&id=$id\" onclick=\"return confirm('$textconfirm[6]')\"><img border=\"0\" src=\"images/tool_smdel.png\" height=\"10\" alt=\"Kategorie löschen\"></a></td>
<td>";
    
// Wenn sortid=1 ist, dann keine Möglichkeit zum raufschieben ansonsten schon
if ($sortid=="1") 
	{
	echo "top";
	}
	
else 
	{
	echo "<a href=\"modify.php?command=24&sortid=$sortid\">oben</a>";
	}
    
echo "</td>
    </tr>";
}

// Beim erstellen einer neuen Kategorie muss natürlich klar sein, welche sortid jetzt vergeben werden soll
// darum wird auch die letzte sortid (=die höchste) mitübergeben und beim anlegen der Kategorie um 1 erhöht.
?>
<tr>
<td colspan="4" align="left"><br><a href="addkategorie.php?sortid=<? echo $sortid; ?>">Neue Kategorie erstellen</a></td>
</tr>
</table>

Wenn eine Kategorie nach oben verschoben wird, wird die sortid an die
Datei modify.php übergeben. Und in der modify.php steht folgendes:

PHP:
if ($command==24) //  schiebt eine Sektion um eine Sektion nach oben
    {
	//die sortid um 1 verringern (=neue position)
	$sortidup=$sortid-1;
	
	// Abfragen der Id der Sektion oberhalb
	@$outcome=mysql_query("SELECT ID from sections WHERE sortid='$sortidup'");
    require("failure.php");
    $access=mysql_fetch_array($outcome);
	$id=$access["ID"];
	
	// Abfragen der Id der zu ändernden Sektion
	@$outcome=mysql_query("SELECT ID from sections WHERE sortid='$sortid'");
    require("failure.php");
    $access=mysql_fetch_array($outcome);
	$id2=$access["ID"];
	   
    //Die Datensätze abändern.
    //Die Ansprache über die Id´s ist wichtig, da sonst die zweite Änderung nicht 
    //mehr funktionieren würde.
 	@$outcome=mysql_query("UPDATE sections SET sortid='$sortid' WHERE ID='$id'");
    require("failure.php");
    @$outcome=mysql_query("UPDATE sections SET sortid='$sortidup' WHERE ID='$id2'");
    require("failure.php");
 	   
    }

So, das ändern der Positionen, wäre damit gelöst. Bleibt nur noch das Problem
mit der durchgehenden Nummerierung der Spalte Sortid.
Also, wenn eine Kategorie gelöscht wird, dann schaut das folgendermassen aus:
Es wird die ID der Kategorie an die modify.php übergeben und hier der Code:

PHP:
if ($command==8) // Löscht eine Kategorie
    {
    //Vorher noch Abfragen welcher Seite und welche sortid diese Kategorie hat
    @$outcome=mysql_query("SELECT sortid,seite from sections WHERE ID='$id'");
    require("failure.php");
    $access=mysql_fetch_array($outcome);
	$sortid=$access["sortid"];
	$seite=$access["seite"];
	
	//Jetzt wird die Kategorie gelöscht
    @$outcome=mysql_query("DELETE FROM sections WHERE ID='$id'");
    require("failure.php");
    //Und jetzt werden alle darunter liegenden KAtegorien mit der selben Seiten Zuordnung aktualisiert
    @$outcome=mysql_query("UPDATE sections SET sortid=sortid-1 WHERE seite='$seite' AND sortid>'$sortid'");
    require("failure.php");
    }

So das war´s im großen und ganzen. Wenn ich es unklar beschrieben
habe tut´s mir leid. Einfach nachfragen.

Danke nochmal für Eure Hilfe

mfg Hoizwurm
 
Zurück