Możliwość sortowania elementów w UI metodą „przeciągnij i upuść” może być przydatną funkcjonalnością w wielu przypadkach. Gdziekolwiek mamy galerie, listy elementów czy nawet tak złożone rozwiązania jak visual builder, wprowadzenie sortowania metodą drag & drop rozszerza możliwości aplikacji a już na pewno przyspiesza pracę użytkownikowi niezależnie od charakteru projektu.
W tym tutorialu pokażę jak zintegrować popularną bibliotekę SortableJS z aplikacją PHP, która z jakiegoś powodu chce przechować kolejność elementów, przykładowo w bazie danych. Zgodnie z zasadą KISS, najpierw zajmiemy się stworzeniem samego interfejsu a dopiero potem będziemy się zajmować zapisem kolejności elementów w bazie danych.
Każda aplikacja, którą można napisać w JavaScript, zostanie ostatecznie napisana w JavaScript.
Jeff Atwood
1. Interfejs listy z funkcją zmiany kolejności
Stwórzmy prosty kod HTML listy, którą będziemy chcieli sortować za pomocą metody drag & drop:
<div id="lista"> <div data-id="1">Przykład 1</div> <div data-id="2">Przykład 2</div> <div data-id="3">Przykład 3</div> <div data-id="4">Przykład 4</div> <div data-id="5">Przykład 5</div> </div>
Może to być dowolna konstrukcja – równie dobrze mogłem użyć tagów listy nieuporządkowanej czyli <ul> oraz <li>. Jedyne o czym musimy pamiętać to dodatkowy atrybut z unikalnym id. Choć możemy mu nadać dowolną nazwę, wykorzystam „data-id” – dokładnie taki przykład jest w dokumentacji SortablesJS.
Całość po dodaniu marginesów i obramowania powinna wyglądać mniej-więcej tak:

Aby sortowanie działało, musimy dodać bibliotekę SortableJS. Biblioteka ta nie wymaga żadnych zależności, dlatego przed znacznikiem zamykającym </body> dodajemy odnośnik do pliku sortable.js lub sortable.min.js, który znajduje się w głównym folderze projektu:
<script src="sortable.min.js"></script>
Ostatnią rzeczą jaką trzeba wykonać jest inicjalizacja funkcji sortowania. Dodajemy własny skrypt:
var sortable = new Sortable(lista, { dataIdAttr: 'data-id', animation: 250, });
Opcja animation jest oczywiście opcjonalna jednakże bez niej, nie ma tego płynnego efektu sortowania w trakcie przeciągania obiektów:
To wszystko jeśli chodzi o samą interakcję i jedyne co musimy jeszcze opanować po stronie front-endu to zwrócenie kolejności jaką ustalił użytkownik i wysłanie jej do skryptu PHP.
Aby otrzymać ostatecznie ustaloną przez użytkownika kolejność obiektów, używamy metody toArray(); Dla naszego przykłądu będzie to:
sortable.toArray();
JavaScript zwróci nam w konsoli coś takiego:
sortable.toArray(); (5) ["1", "4", "3", "5", "2"] 0: "1" 1: "4" 2: "3" 3: "5" 4: "2" length: 5 __proto__: Array(0)
Jest to tablica z kolejnymi wartościami w data-id. Nie pozostaje nic innego jak stworzyć własną funkcję, która będzie po każdej aktualizacji wysyłać AJAXem dane JSON do naszego skryptu update.php
Aby móc zapisać i aktualizować kolejność elementów potrzebujemy funkcji, która będzie wywoływana za pomocą przycisku „Aktualizuj” lub po samej integracji. Zdecyduję się na drugie rozwiązanie, bo jest wygodniejsze z perspektywy użytkownika. Do listy opcji dodaję zatem onUpdate, co będzie wyzwalać naszą funkcję updateDb();
onUpdate: function (evt) { updateDb(); }
Dodajemy teraz definicję i kod funkcji updateDb(). Dane zapiszemy sobie do zmiennej sortableData a opakowane w format JSON do zmiennej sortableJson. Skoro korzystamy z SortableJS bez zależności od jQuery całą resztę kodu zapiszemy w czystym JavaScript.
function updateDb(){ let sortableData = sortable.toArray(); let sortableJson = JSON.stringify(sortableData); var httpRequest = new XMLHttpRequest() httpRequest.onreadystatechange = function (data) { if (this.readyState == 4 && this.status == 200) { console.log(this.responseText); } } httpRequest.open('POST', 'update.php'); httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') httpRequest.send('sortable' + encodeURIComponent(sortableJson)); }
2. Aktualizacja kolejności po stronie back-endu
Cała reszta to już tylko formalność, bo po stronie PHP otrzymamy JSONa w polu $_POST[„sortable”]; Zakładając, że obiekty pochodzą z tabeli o nazwie obiekty, i w polu obiekt_order przechowujemy ich kolejność, kod powinien wyglądać mniej-więcej w ten sposób:
<?php if (isset($_POST["sortable"])){ $sort = $_POST["sortable"]; $sort_array = json_decode($sort, true); foreach($sort_array as $key => $value){ if(mysqli_query($connection, "UPDATE obiekty SET obiekt_order = '$key' WHERE obiekt_id = '$value'")){ echo "Zmieniono kolejność"; } } }
Zalety Sortable JS
- brak zależności od jQuery,
- mnóstwo opcji dodatkowych,
- gotowe wsparcie dla jQuery, Vue, React, Angular, Knockout, Meteor, Polymer, Ember,
- możliwość tworzenia kolejności z zagnieżdżeniem (nestable),
- niska waga 42,2 KB.
Podsumowanie
Jak widać sortowanie elementów metodą przeciągnij i upuść w aplikacji webowej to nic trudnego. Wystarczy użyć gotowej biblioteki z mnóstwem opcji. Biblioteka taka jak SortableJS umożliwia wdrożyć tego typu interakcję i łatwo pobrać kolejność elementów.
Odpowiedz lub skomentuj