Position von sortable divs speichern

Kizetsu

Grünschnabel
Hallo,

ich versuche aktuell eine User-startseite so aufzubauen, dass die Informationsquellen in Form von Newsfeeds als, vom User selbst sortierbare Widgets erscheinen. Das Sortieren stellt an sich kein Problem da aber das Speichern...
Hier mal mein Code:

Code:
!~ indexSuccess.php
    $(function() {
        $( "#sortable" ).sortable({
            stop: function(evt, ui) {
                alert("New position: " + ui.item.index());   /* Ausgabe des Index zu Testzwecken */
                alert("Item Attribute: " + ui.item.attr('id'));   /* Ausgabe der ID zu Testzwecken */
                $.ajax({
                    type: 'post',
                    url: 'myhome/widgets',
                    data: {
                        widgetid: $("#sortable div.widget").index(ui.item),
                        widgetname: ui.item.attr('id')
                    },
                    success: function(msg) {
                        alert("Eintrag erfolgreich: \n" + msg);
                    }
                });
            }
        }).disableSelection();
    });
</script>


<div id="sortable" class="twelve columns">
                    <?php
                    foreach($widgets as $widgetform) {
                        echo "<div id='" . $widgetform['name'] . "' class='four columns widget'>";
                        echo "! - " . $widgetform['name'] . " - " . $widgetform['widgetid'] . " - !";
                        echo "<p class='ui-state-default short'>" . $widgetform['content'] . "</p>";
                        echo "</div>";
                    }
                    ?>
</div>

Code:
!~actions.class.php
public function executeWidgets() {
        $this->user_id = '00000001';

//Widgets
        $widgetid = $_POST['widgetid'];
        $widgetname = $_POST['widgetname'];
        
        $watch = Doctrine::getTable('widgets')
                ->findOneByName($widgetname);
        $watchid = $watch['widgetid'];

        try {

            $updatewidget = Doctrine::getTable('widgets')
//                    ->findOneById($this->user_id)
//                    ->createQuery()
//                    ->where("user_id = ?", $this->user_id)
//                    ->addwhere("widgetname = ?", $widgetname);
                    ->findOneByName($widgetname);

            $updatewidget->setWidgetid($widgetid);

            $updatewidget->save();

            echo json_encode(array("state" => "OK"));
        } catch (Exception $e) {
            echo json_encode(array("state" => "ERROR widget Table"));
        }



        //Alle WidgetIds updaten
//        $widgetname = $_POST['widgetname'];

        $o = '1';

        if($watchid < $widgetid) {
        $widgetna = $widgetname + $o;
        try {

            $updatewidgets = Doctrine::getTable('widgets')
                    ->findOneByName($widgetna);
            
            $rechner = $updatewidgets['widgetid'];
            $result = $rechner - $o;

            $updatewidgets->setWidgetid($result);

            $updatewidgets->save();

            echo json_encode(array("state" => "OK"));
        } catch (Exception $e) {
            echo json_encode(array("state" => "ERROR widget update"));
        }
        }
        if($watchid > $widgetid) {
        $widgetna = $widgetname - $o;
        try {

            $updatewidget = Doctrine::getTable('widgets')
                    ->findOneByName($widgetna);
            
            $rechner = $updatewidget['widgetid'];
            $result = $rechner + $o;

            $updatewidget->setWidgetid($result);

            $updatewidget->save();

            echo json_encode(array("state" => "OK"));
        } catch (Exception $e) {
            echo json_encode(array("state" => "ERROR widget update"));
        }
        }
    }

Aufgebaut ist das ganze Optisch etwa so:
[0] [1] [2]
[3] [4] [5]

Wenn ich nun Div #4 zwischen #0 und #1 schiebe wird der Index von #4 zu 1 aber der Index der Anderen ändert sich nicht. Somit habe ich zwar nun die Divs in dieser Reihenfolge stehen:
[0] [4] [1]
[2] [3] [5]
aber nach einem Neuladen der Seite stehen sie so:
[0] [1] [4]
[2] [3] [5]

Das Problem ergibt sich, da das Auslesen aus der Datenbank ja Zeile für Zeile geschieht und trotz der Sortierung nach Index steht #1 nunmal weiter oben in der Liste als #4. Ich habe hier einige Lösungsansätze durchprobiert und habe es auch geschafft, das Problem zu beheben wenn man die divs nur um eine Stelle verschiebt aber sobald man sie um mehr stellen verschiebt bekomme ich es nicht hin.
Nun habe ich überlegt ob es vielleicht möglich ist die gesammte Liste (div name und div id) an mein php script zu übergeben statt nur die von einem. Leider habe ich hierzu noch keinen wirklichen Lösungsansatz gefunden...

Kann mir jemand weiterhelfen?
 
Hi,

ich habe das Problem nun selbst gelöst. Die Lösung war simpler als gedacht und ich möchte sie euch hier präsentieren:

Ich habe drei PHP-Dateien. Zwei als Template und eine für die Funktionen.
Im ersten Template befindet sich folgender Code:
PHP:
<script type="text/javascript" src="/js/jquery-ui-1.9.0.custom.min.js"></script>


<script type="text/javascript">    
    $(function() {
        $( "#sortable" ).sortable({
            stop: function(evt, ui) {
                var widgetid = document.getElementById("sortable");
                var widget = widgetid.getElementsByTagName("div").length;
                var widgetname = widgetid.getElementsByTagName("div");
                
                var transportname = widgetname[0].id;
                for(i=1;i<widget;i++) {
                    var transportname = transportname + "," + widgetname[i].id;
                }
                $.ajax({
                    type: 'post',
                    url: 'myhome/widgets',
                    data: {
                        transport: transportname
                    },
                    success: function(msg) {
                        alert("Eintrag erfolgreich: \n" );
                    }
                });
            }
        }).disableSelection();
    });
</script>

<style>
    #sortable { list-style-type: none; margin: 0; padding: 0; width: 100%; }
    .short { font-size: 0.88em; margin-top: 10px;}
    .widget { height: 290px; }
</style>

...

<div id="sortable" class="twelve columns">
    <?php
    $widgetnumber = '0';
     foreach ($widgets as $widgetform) {
        echo "<div id='" . $widgetform['name'] /*. $widgetnumber */. "' class='four columns widget'>";
        echo "<table><tr>";
        echo "<td class='panel'>" . $widgetform['name'] . "</td></tr>";
        echo "<tr><td>" . $widgetform['content'] . "</td></tr>";
        if($widgetform['link']!="")
            echo "<tr><td class='alert'><a href='" . $widgetform['link'] . "'>Mehr lesen...</a></td></tr>";
            echo "</table></div>";
            $widgetnumber++;
    }
    ?>
</div>

Im zweiten Template befindet sich nur ein Kommentar. Die Seite bekommt der User niemals zu gesicht. Sie ist nur für den Post.

In meiner dritten PHP stehen nun folgende Funktionen:
PHP:
    public function executeIndex() {

        ...

        /* Auslesen der Widgetposition */
        $this->widgets = Doctrine_Core::getTable('widgets')
                ->createQuery()
                ->select("*")
                ->where("user_id = ?", $this->user_id)
                ->orderBy("widgetid ASC")
                ->execute();

       ...

    }

    public function executeWidgets() {
        /* Updaten der Widgetposition */
        
        $widgetfolge = $_POST['transport'];
        $widgets = explode(",", $widgetfolge);
        $check = '0';
        foreach($widgets as $wf) {
            try {
                $updatewidget = Doctrine::getTable('widgets')
                        ->createQuery()
                        ->where("user_id = ?", $this->user_id)
                        ->andwhere("name = ?", $wf)
                        ->execute();

                $updatewidget[0]->setWidgetid($check++);
                $updatewidget[0]->save();

                echo json_encode(array("state" => "OK"));
            } catch (Exception $e) {
                echo json_encode(array("state" => "ERROR"));
            }
        }
    }
 
Zurück