Datensätze positionieren

Hampfibius

Mitglied
Hi Leute!

Ich hab eine tabelle die ich sortieren möchte (keine ORDER BY funktion).

Die Tabelle:
Code:
ID, name, position
1, Test1, 1
2, Test2, 2
3, Test3, 3
4, Test4, 4

nun brauch ich eine oberfläche in der ich die tabelle reinlade mit pfeilen oder drag and drop die reihnfolge verändern kann.

zB so:
Code:
ID, name, position
1, Test1, 1
4, Test4, 2
3, Test3, 3
2, Test2, 4

hoffe ihr könnt mir helfen
greetz
HambfibiuS
 
Zuletzt bearbeitet:
Mit Pfeilen (ich habe die mal durch Texte ersetzt) geht das mit PHP und HTML:
Die Ausgabe müsste dann folgendes (oder ähnlich) ergeben:
HTML:
<table>
<tr>
  <td></td>
  <td>ID</td>
  <td>Name</td>
  <td>Position</td>
</tr>
<tr>
  <td>
    <a href="move.php?setPos[1]=2&amp;setPos[2]=1">move down</a>
  </td>
  <td>1</td>
  <td>Test1</td>
  <td>1</td>
</tr>
<tr>
  <td>
    <a href="move.php?setPos[2]=1&amp;setPos[1]=2">move up</a>
    <a href="move.php?setPos[2]=3&amp;setPos[3]=2">move down</a>
  </td>
  <td>2</td>
  <td>Test2</td>
  <td>2</td>
</tr>
<tr>
  <td>
    <a href="move.php?setPos[3]=2&amp;setPos[2]=3">move up</a>
    <a href="move.php?setPos[3]=4&amp;setPos[4]=3">move down</a>
  </td>
  <td>3</td>
  <td>Test3</td>
  <td>3</td>
</tr>
<tr>
  <td>
    <a href="move.php?setPos[4]=3&amp;setPos[4]=4">move up</a>
  </td>
  <td>4</td>
  <td>Test4</td>
  <td>4</td>
</tr>
In move.php müsste dann etwas in der Art ausgeführt werden:
PHP:
foreach($_GET['setPos'] AS $id => $newPos) {
    mysql_query("UPDATE tabelle SET position="
        .$newPos." WHERE id=".$id);
}
Für die Abfrage (um die HTML-Tabelle zu erzeugen) wirst Du trotzdem mit ORDER BY nach der Position sortieren müssen!

Eine Lösung mit Drag-Drop ist IMHO nur über JavaScript möglich und müsste als Reaktion auf entsprechende Events eine URL mit Parametern (eine ID und ihre neue Position) aufrufen. In dem aufgerufenen Skript müsstest Du dann zunächst ermitteln, welche IDs alle verschoben werden müssen und alle Werte mit einem Update einzeln setzen. Eventuell geht das auch mit einem Query mit entsprechend intelligenter WHERE-Klausel.

Gruß hpvw
 
Ich habe noch eine Drag-Drop-Variante mit JavaScript gemacht.

Das Auswerten und die Ermittlung der neuen Positionen wird in PHP vermutlich etwas tricky, dafür ist es mir jetzt allerdings zu spät.

An der Stelle, wo jetzt eine Meldung kommt muss dann auf eine enstsprechend parametrisierte URL verwiesen werden.

Probleme:
Es wirkt manchmal etwas hakelig. Der Cursor wird in einigen Browsern erst zurückgesetzt, wenn man die Maus wieder ein Stück bewegt. Beim Drag-Drop wird noch Text ausgewählt. In einigen Browsern wird sich das vermutlich nicht verhindern lassen, für die anderen Browser müßte noch mal ein JavaScript-Experte ran. Vielleicht findet der dann auch Lösungen für die anderen kleinen Problemchen und kann das Script noch verbessern.

Ich würde auch empfehlen, zusätzlich die Pfeile zu implementieren, damit auch User ohne Javascript, wenn auch etwas unkomfortabler, die Seite benutzen können.

Nun aber genug um den heißen Brei geredet, hier das Skript:

getestet mit IE 6.0, FF 1.0, OP 8.0, NS 7.1
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>
<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>
Gruß hpvw
 
@hpvw
DANKE

Hab aber noch ne Frage:
Wie kann ich die links (zB. move.php?setPos[1]=2&amp;setPos[2]=1) automatisch generieren?

Sprich
move.php?setPos[$ID]=2&amp;setPos[$nächsteID]=1 :confused:

greetz
HampfibiuS
 
Ich würde es so machen:
PHP:
$result=mysql_query("SELECT id, name,position FROM tabelle "
    ."ORDER BY position");
echo "<table>";
echo "<tr><td></td><td>ID</td><td>Name</td><td>Position</td></tr>\n";
$temp=array();
while ($row=mysql_fetch_assoc($result)) {
    $row['up']=$row['position']-1;
    $row['down']=$row['position']+1;
    $temp[]=$row;
}
for ($i=0;$i<count($temp);$i++) {
    echo "<tr><td>";
    if ($temp[$i]['up']>0) {
        echo '<a href="move.php?setPos['
            .$temp[$i]['id']
            .']='
            .$temp[$i]['up']
            .'&amp;setPos['
            .$temp[$i-1]['id']
            .']='
            .$temp[$i-1]['down']
            .'">move up</a>';
    }
    if ($temp[$i]['down']<count($temp)) {
        echo '<a href="move.php?setPos['
            .$temp[$i]['id']
            .']='
            .$temp[$i]['down']
            .'&amp;setPos['
            .$temp[$i+1]['id']
            .']='
            .$temp[$i-1]['up']
            .'">move up</a>';
    }
    echo "</td><td>";
    echo $row['id'];
    echo "</td><td>";
    echo $row['name'];
    echo "</td><td>";
    echo $row['position'];
    echo "</td></tr>\n";
}
echo "</table>";
Gruß hpvw
 
@hpvw
Danke

nun noch die letzte Frage:
Wie kann ich dieses Schema auf diese Tabelle (selbe wie oben +pid)anwenden
Code:
ID, pid, name, position
1, 0, Test1, 1
2, 0, Test2, 2
3, 1, sub3, 1
4, 1, sub4, 2

das heißt die Ausgabe müsste so sein:

gruppe 0
down/up, ID, Text
down, 1, Test1
up, 2, Test2

gruppe 1
down/up, ID, Text
down, 3, sub1
up, 4, sub2

Hab das Problem selbst gelöst! :-)
Hier der Code:

PHP:
$sql = 'SELECT *
        FROM '.$dbtable.'
        ORDER BY `pid` ASC , `pos` ASC';
        
$sql2 = 'SELECT `pid`, COUNT(*) AS `pid_anzahl`
        FROM '.$dbtable.'
        GROUP  BY  `pid`';

$result = mysql_query($sql) OR die(mysql_error());
$result2 = mysql_query($sql2) OR die(mysql_error());

while ($row = mysql_fetch_array($result))
{
    $row['up'] = $row['pos']-1;
    $row['down'] = $row['pos']+1;
    $temp[] = $row;
}

while ($row2 = mysql_fetch_array($result2))
{
    $temp2[] = $row2;
}

for ($int=0;$int<count($temp2);$int++) {

echo '<table width="270" border="0" cellpadding="2" cellspacing="0" bordercolor="#BEBEBE" style="border: 1px solid #BEBEBE; padding: 0">
	<tr class="tdh">
		<td align="center" height="25" bgcolor="#F8F8F8" width="22" class="txt">
		&nbsp;</td>
		<td align="center" height="25" bgcolor="#F8F8F8" width="22" class="txt">
		&nbsp;</td>
		<td align="center" height="25" bgcolor="#F8F8F8" width="22" class="txt">
		ID</td>
		<td align="center" height="25" bgcolor="#F8F8F8" width="204" class="txt">
		Text</td>
	</tr>';

    for ($i=0;$i<count($temp);$i++){

    if ($temp[$i]['pid']==$int)
    {
    echo '<tr class="txt">';

    if ($temp[$i]['down']<=count($temp2)) {
        echo '<td align="center" height="25" bgcolor="#F8F8F8" width="22">
        <a href="move.php?setPos['
        .$temp[$i]['ID'].']='
        .$temp[$i]['down'].'&amp;setPos['
        .$temp[$i+1]['ID'].']='
        .$temp[$i]['pos'].'"><img border="0" src="../images/arrow_down.gif" width="22" height="22"></a>
        </td>';
    }else {
        echo '<td align="center" height="25" bgcolor="#F8F8F8" width="22"></td>';
    }
    if ($temp[$i]['up']>0) {
        echo '<td align="center" height="25" bgcolor="#F8F8F8" width="22">
        <a href="move.php?setPos['
        .$temp[$i]['ID'].']='
        .$temp[$i]['up'].'&amp;setPos['
        .$temp[$i-1]['ID'].']='
        .$temp[$i]['pos'].'"><img border="0" src="../images/arrow_up.gif" width="22" height="22"></a>
        </td>';
    }else {
        echo '<td align="center" height="25" bgcolor="#F8F8F8" width="22"></td>';
    }
    echo'
    <td align="center" height="25" bgcolor="#F8F8F8" width="22">
	' . $temp[$i]['ID'] . '</td>
	<td align="center" height="25" bgcolor="#F8F8F8" width="204">
	' . $temp[$i]['txt'] . '</td>
    </tr>';
    
    }
  
  }
echo '</table>';
echo '<table width="270" cellpadding="2" cellspacing="0" bordercolor="#BEBEBE" style="border-left:1px solid #BEBEBE; border-right:1px solid #BEBEBE; padding:0; " height="25">
				<tr>
					<th height="25" background="../images/cellpic3.gif" colspan="2" align="left">
					&nbsp;</th>
					<th height="25" background="../images/cellpic3.gif" colspan="2" width="25" align="right" valign="top">
					&nbsp;</th>
				</tr>
</table>';
}

greetz
HampfibiuS
 
Zuletzt bearbeitet:
Zurück