jQuery UI Sortable, a następnie zapisz porządek w bazie danych

125

Chcę użyć sortablefunkcji interfejsu użytkownika jQuery, aby umożliwić użytkownikom ustawienie zamówienia, a następnie zmianę, zapisanie go w bazie danych i zaktualizowanie. Czy ktoś może napisać przykład, jak by to zrobić?

Złupić
źródło
4
toArraydałby ciąg posortowanych identyfikatorów, myślę, że może to być pomocne. api.jqueryui.com/sortable/#method-toArray
MahanGM
1
Czy rozwiązałeś swój problem?
Knelis
Pod pewnymi względami takie pytania są najlepsze w SO. Jednak to pytanie zostanie zmiażdżone w 2020 roku.
Parapluie

Odpowiedzi:

223

Funkcja interfejsu użytkownika jQuery sortablezawiera serializemetodę służącą do tego. To naprawdę proste. Oto krótki przykład, który wysyła dane pod określony adres URL, gdy tylko element zmieni położenie.

$('#element').sortable({
    axis: 'y',
    update: function (event, ui) {
        var data = $(this).sortable('serialize');

        // POST to server using $.post or $.ajax
        $.ajax({
            data: data,
            type: 'POST',
            url: '/your/url/here'
        });
    }
});

To, co robi, to tworzenie tablicy elementów przy użyciu elementów id. Więc zwykle robię coś takiego:

<ul id="sortable">
   <li id="item-1"></li>
   <li id="item-2"></li>
   ...
</ul>

Kiedy użyjesz tej serializeopcji, utworzy ona ciąg zapytania POST w następujący sposób: item[]=1&item[]=2itd. Więc jeśli użyjesz - na przykład - identyfikatorów bazy danych w idatrybucie, możesz po prostu iterować po tablicy POST i odpowiednio zaktualizować pozycje elementów .

Na przykład w PHP:

$i = 0;

foreach ($_POST['item'] as $value) {
    // Execute statement:
    // UPDATE [Table] SET [Position] = $i WHERE [EntityId] = $value
    $i++;
}

Przykład na jsFiddle.

Knelis
źródło
7
Aby automatycznie wygenerować identyfikatory, możesz użyć$("#element").children().uniqueId().end().sortable({...
Taylan
12
Dokumentacja mówi, że aby użyć opcji serializacji, powinieneś zdefiniować id jako format nazwa_numer .
parisssss
5
Możesz również użyć tych innych znaków zgodnie z dokumentacją: Możesz użyć podkreślenia, znaku równości lub łącznika, aby oddzielić zestaw od liczby. Na przykład „foo = 1”, „foo-1” i „foo_1” są serializowane do „foo [] = 1”.
lhoess
2
Nie wydaje mi się, aby to działało, jeśli przekazuję wiele zmiennych danych.
PBwebD
11

Pomyślałem, że to też może pomóc. A) został zaprojektowany, aby ograniczyć ładunek do minimum podczas wysyłania z powrotem na serwer po każdym sortowaniu. (zamiast wysyłać wszystkie elementy za każdym razem lub iterować przez wiele elementów, które serwer może wyrzucić) B) Musiałem odesłać niestandardowy identyfikator bez narażania identyfikatora / nazwy elementu. Ten kod pobierze listę z serwera asp.net, a następnie po posortowaniu zostaną odesłane tylko 2 wartości: identyfikator bazy danych sortowanego elementu i identyfikator bazy danych elementu, obok którego został usunięty. Na podstawie tych 2 wartości serwer może łatwo zidentyfikować nową pozycję.

<div id="planlist" style="width:1000px">
    <ul style="width:1000px">
       <li plid="listId1"><a href="#pl-1">List 1</a></li>
       <li plid="listId2"><a href="#pl-2">List 1</a></li>
       <li plid="listId3"><a href="#pl-3">List 1</a></li>
       <li plid="listId4"><a href="#pl-4">List 1</a></li>
    </ul>
    <div id="pl-1"></div>
    <div id="pl-2"></div>
    <div id="pl-3"></div>
    <div id="pl-4"></div>
</div>
<script type="text/javascript" language="javascript">
    $(function () {
        var tabs = $("#planlist").tabs();
        tabs.find(".ui-tabs-nav").sortable({
            axis: "x",
            stop: function () {
                tabs.tabs("refresh");
            },
            update: function (event, ui) {
                //db id of the item sorted
                alert(ui.item.attr('plid'));
                //db id of the item next to which the dragged item was dropped
                alert(ui.item.prev().attr('plid'));

                //make ajax call
            }
        });
    });
</script>
Kalpesh Popat
źródło
4
Tagi ASP mogą być mylące dla osób, które ich nie znają, i jest to wyłącznie problem z jQuery / HTML.
ggdx
1
Dwa lata później! Byłem zajęty?
ggdx
Co się stanie, jeśli przeniesiony element zostanie upuszczony jako pierwszy element listy?
Edson Horacio Junior
1
jeśli jakikolwiek element zostanie upuszczony, to „obok” id = 0, action = del i plid = id elementu, na którym działa, w przeciwnym razie action = sort i są 2 parametry, element jest sortowany i obok którego jest upuszczany . to minimum informacji, których serwer może użyć do wykonania pozostałych operacji. jest to wypróbowany i testowy wzór. mam nawet dodawanie i wstawianie według tego samego wzorca - po prostu gra akcji i pozostałe 2 parametry.
Kalpesh Popat
9

Masz szczęście, używam dokładnie tego w moim CMS

Jeśli chcesz zapisać zamówienie, po prostu wywołaj metodę JavaScript saveOrder(). Spowoduje to POSTwysłanie żądania AJAX do saveorder.php, ale oczywiście zawsze możesz wysłać to jako zwykły formularz.

<script type="text/javascript">
function saveOrder() {
    var articleorder="";
    $("#sortable li").each(function(i) {
        if (articleorder=='')
            articleorder = $(this).attr('data-article-id');
        else
            articleorder += "," + $(this).attr('data-article-id');
    });
            //articleorder now contains a comma separated list of the ID's of the articles in the correct order.
    $.post('/saveorder.php', { order: articleorder })
        .success(function(data) {
            alert('saved');
        })
        .error(function(data) { 
            alert('Error: ' + data); 
        }); 
}
</script>
<ul id="sortable">
<?php
//my way to get all the articles, but you should of course use your own method.
$articles = Page::Articles();
foreach($articles as $article) {
    ?>
    <li data-article-id='<?=$article->Id()?>'><?=$article->Title()?></li>
    <?
}               
?>   
</ul>
   <input type='button' value='Save order' onclick='saveOrder();'/>

W saveorder.php; Pamiętaj, że usunąłem całą weryfikację i sprawdzanie.

<?php
$orderlist = explode(',', $_POST['order']);
foreach ($orderlist as $k=>$order) {
  echo 'Id for position ' . $k . ' = ' . $order . '<br>';
}     
?>
Hugo Delsing
źródło
7

To jest mój przykład.

https://github.com/luisnicg/jQuery-Sortable-and-PHP

Musisz złapać kolejność w wydarzeniu aktualizacji

    $( "#sortable" ).sortable({
    placeholder: "ui-state-highlight",
    update: function( event, ui ) {
        var sorted = $( "#sortable" ).sortable( "serialize", { key: "sort" } );
        $.post( "form/order.php",{ 'choices[]': sorted});
    }
});
luisnicg
źródło
0

Mogę zmienić wiersze, postępując zgodnie z zaakceptowaną odpowiedzią i powiązanym przykładem na jsFiddle. Ale z nieznanych powodów nie mogłem uzyskać identyfikatorów po akcjach „zatrzymaj lub zmień”. Ale przykład opublikowany na stronie interfejsu użytkownika JQuery działa dobrze. Możesz sprawdzić ten link tutaj.

Web Developer
źródło
0

Spróbuj z tym rozwiązaniem: http://phppot.com/php/sorting-mysql-row-order-using-jquery/ gdzie nowe zamówienie jest zapisywane w jakimś elemencie HMTL. Następnie przesyłasz formularz z tymi danymi do jakiegoś skryptu PHP i iterujesz przez niego za pomocą pętli for.

Uwaga: musiałem dodać kolejne pole db typu INT (11), które jest aktualizowane (oznaczane znacznikiem czasu) przy każdej iteracji - służy skryptowi, aby wiedzieć, który wiersz jest ostatnio aktualizowany, w przeciwnym razie otrzymasz pomieszane wyniki.

TomoMiha
źródło