В статье нет демо (но есть возможность скачать исходный код), поэтому вот вам гифка с конечным результатом:

Понравилось? Тогда приступим.

Подготовка БД с тестовыми данными для примера

Для примера будем использовать таблицу с тестовыми данными, структура:

1 id int(11)
2 name varchar(255)
3 position int(11)

Дамп таблицы:

CREATE TABLE IF NOT EXISTS `sortable` (
  `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `name` varchar(255) NOT NULL,
  `position` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SQL запрос для заполнения таблицы тестовыми данными:

INSERT INTO `sortable` (`id`, `name`, `position`) VALUES
(1, 'Информационная заметка 1', 0),
(2, 'Информационная заметка 2', 1),
(3, 'Информационная заметка 3', 2),
(4, 'Информационная заметка 4', 3),
(5, 'Информационная заметка 5', 4),
(6, 'Информационная заметка 6', 5),
(7, 'Информационная заметка 7', 6),
(8, 'Информационная заметка 8', 7),
(9, 'Информационная заметка 9', 8),
(10, 'Информационная заметка 10', 9);

Данные для тестов подготовили, теперь можем приступить.

Вывод данных

Перед тем как приступить к сортировке данных нужно реализовать вывод данных. Для этого создадим файл index.php со стандартной html разметкой:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>PHP + jQuery, Сортировка списка с сохранением при помощи jQuery Sortable - кодер.укр</title>
</head>
<body>
</body>
</html>

Для начала подключим к проекту jQuery и jQuery UI, их необходимо скачать или подключить из источника:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>

Также для красоты вывода данных будем использовать bootstrap, скачайте его (http://getbootstrap.com/getting-started/) и подключите или подключите из источника Bootstrap CDN:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

В итоге получим:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>PHP + jQuery, Сортировка списка с сохранением при помощи jQuery Sortable</title>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
</body>
</html>

Перед выводом списка вынесем подключение к БД в отдельный файл, db_connection.php:

<?php

$link = mysqli_connect(
    'localhost',
    'root',
    '',
    'db_name');

if (!$link) {
    printf("Невозможно подключиться к базе данных. Код ошибки: %s\n", mysqli_connect_error());
    exit;
}

Теперь можем приступить непосредственно к выводу списка, и оформлению внешнего вида:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>PHP + jQuery, Сортировка списка с сохранением при помощи jQuery Sortable</title>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>

<?php
include('db_connection.php');
?>

<div class="container">
    <div class="jumbotron">
        <h1>PHP + jQuery</h1>
        <p>Сортировка списка с помощью jQuery Sortable</p>
    </div>

    <?php
    if ($result = mysqli_query($link, 'SELECT * FROM sortable ORDER BY position')) {
        ?>
        <ul class="list-group">
            <?php
            while ($row = mysqli_fetch_assoc($result)) {
                echo '<li class="list-group-item">' . $row['name'] . '</li>';
            }
            ?>
        </ul>
        <?php
        mysqli_free_result($result);
    }

    mysqli_close($link);
    ?>

</div>
</body>
</html>

Вот что получится:

Подключаем jQuery Sortable

Теперь инициализируем плагин sortable, добавим кнопку "Сохранить сортировку" для отправки и сохранения данных в БД, отправку данных о сортировке для сохранения в файл save.php и информер о состояние дел.

Добавляем кнопку "Сохранить сортировку":

<button class="save btn btn-success">Сохранить сортировку</button>

Добавляем блок с информацией о сохранении:

<div class="alert alert-success" id="response" role="alert">Отсортируйте и сохраните :)</div>

Перед инициализацией jQuery Sortable добавим в тег <ul> списка записей класс sortable:

<ul class="list-group sortable">
//...
</ul>

И к списку <li> добавим id записи для ее идентификации:

<?php
//...
echo '<li class="list-group-item" id=item-' . $row['id'] .'">' . $row['name'] . '</li>';

Теперь можем выполнить инициализацию jQuery Sortable, отправку данных о сортировке для сохранения в файл save.php и вывод информации в блок response:

<script type="text/javascript">
    var ul_sortable = $('.sortable');

    ul_sortable.sortable({
        revert: 100,
        placeholder: 'placeholder'
    });

    ul_sortable.disableSelection();

    var btn_save = $('button.save'),
        div_response = $('#response');

    btn_save.on('click', function(e) {
        e.preventDefault();
        var sortable_data = ul_sortable.sortable('serialize');
        div_response.text('Сохраняем');
        $.ajax({
            data: sortable_data,
            type: 'POST',
            url: 'save.php',
            success:function(result) {
                div_response.text(result);
            }
        });
    });
</script>

Для улучшения внешнего вида сортировки добавим и подключим файл style.css со следующим содержимым:

ul.sortable {
    width: 100%; 
    float: left; 
    margin: 20px 0; 
    list-style: none; 
    position: relative !important;
}

ul.sortable li {
    cursor: move;
}

ul.sortable li.ui-sortable-helper {
    border-color: #3498db;
}

ul.sortable li.placeholder {
    height: 50px; 
    background: #eee; 
    border: 2px dashed #bbb; 
    display: block; 
    opacity: 0.6;
    border-radius: 2px;
    -moz-border-radius: 2px;
    -webkit-border-radius: 2px;
}

В итоге файл index.php примет вид:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>PHP + jQuery, Сортировка списка с сохранением при помощи jQuery Sortable</title>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <link href="css/style.css" rel="stylesheet">
</head>
<body>

<?php
include('db_connection.php');
?>

<div class="container">
    <div class="jumbotron">
        <h1>PHP + jQuery</h1>
        <p>Сортировка списка с помощью jQuery Sortable</p>
    </div>
    <button class="save btn btn-success">Сохранить сортировку</button>
    <br />
    <br />
    <br />
    <div class="alert alert-success" id="response" role="alert">Отсортируйте и сохраните :)</div>

    <?php
    if ($result = mysqli_query($link, 'SELECT * FROM sortable ORDER BY position')) {
        ?>
        <ul class="list-group sortable">
            <?php
            while ($row = mysqli_fetch_assoc($result)) {
                echo '<li class="list-group-item" id=item-' . $row['id'] .'">' . $row['name'] . '</li>';
            }
            ?>
        </ul>
        <?php
        mysqli_free_result($result);
    }
    mysqli_close($link);
    ?>

</div>

<script type="text/javascript">
    var ul_sortable = $('.sortable');

    ul_sortable.sortable({
        revert: 100,
        placeholder: 'placeholder'
    });

    ul_sortable.disableSelection();

    var btn_save = $('button.save'),
        div_response = $('#response');

    btn_save.on('click', function(e) {
        e.preventDefault();
        var sortable_data = ul_sortable.sortable('serialize');
        div_response.text('Сохраняем');
        $.ajax({
            data: sortable_data,
            type: 'POST',
            url: 'save.php',
            success:function(result) {
                div_response.text(result);
            }
        });
    });
</script>
</body>
</html>

Остался последний по списку, но не по значению файл, save.php, который отвечает за сохранение позиции записи в списке:

<?php

if (isset($_POST)) {
    include('db_connection.php');
    $arrayItems = $_POST['item'];
    $order = 0;

        foreach ($arrayItems as $item) {
            $sql = "UPDATE sortable SET position='$order' WHERE id='$item'";
            mysqli_query($link, $sql);
            $order++;
        }

    echo 'Сохранено!';
    mysqli_close($link);
}

Вот что получится:

Думаю из кода все понятно. Если вы не используете bootstrap, то замените стиль на свой, код попрежнему будет работать. Приятного использования!

Скачать исходный код