Динамическая сортировка меню с использованием метода Ajax.
01.12.2011 Рубрика: Обучение \ PHP

От автора: если Вы работали с CMS WordPress, то, наверное, знакомы с такой штукой, как виджеты WordPress. В данном случае виджеты – это блоки, которые можно перемещать в режиме Drag and Drop («тащи и бросай»). При этом, после перемещения блока, он сохраняет свою позицию, т.е., к примеру, в сайдбаре сайта у нас имеется блок поиска, под которым размещен блок с произвольным текстом… мы захотели поменять их позиции… нет ничего проще – перетащили блок с поиском под блок с текстом и… вуаля – на сайте эти изменения расположения блоков вступили в силу. Согласитесь, быстро, удобно и эффектно. Сегодня мы научимся делать подобное.
План урока:
1. Постановка задач. Создание БД (9:42)
2. Выводим меню из БД (11:09)
3. Реализуем сортировку без сохранения (11:48)
4. Обращаемся к методу ajax (6:47)
5. Реализуем сохранение сортировки (7:07)
6. Логика работы скрипта (7:59)
7. Добавляем юзабельности (15:38)
![]() |
Автор: Андрей КудлайЗовут меня Андрей Кудлай. Родом я из Украины, живу в Днепропетровске. Веб-программированию учился сам. Неплохо знаю HTML, CSS, PHP. Немного разбираюсь в JavaScript’e – в свободное время как раз занимаюсь его изучением. |
1. Постановка задач. Создание БД
Для начала сформулируем задачу. Вместо блоков у нас будет меню, пункты которого у нас и будут перетаскиваемыми блоками. Для чего вообще это нужно? Допустим, мы хотим изменить сортировку пунктов меню, т.е. сделать так, чтобы из БД пункты меню выводились не отсортированными по идентификатору пункта меню, а по, к примеру, полю position. Для этого, конечно же, можно написать несложный скрипт, который будет выводить текущую позицию каждого из пунктов меню в числовом виде (1, 2, 3 и т.д.). Далее мы сможем для конкретного пункта задать новую числовую позицию и сохранить изменения в БД. Но гораздо быстрее и красивее будет выглядеть реализация, когда мы просто возьмем пункт меню и перетащим его на новое место… все – он сохранит свою позицию.
Итак, мы создаем меню и через административную часть сайта сможем изменять позицию его пунктов. Давайте теперь определимся с тем, что нам понадобится. Прежде всего, нам понадобятся 2 библиотеки jQuery:
собственно сама библиотека jQuery;
библиотека jQuery User Inteface.
Взять их можно на офф сайте jQuery. Также Вы найдете эти скрипты в исходниках к уроку. Также нам понадобится файл стилей для оформления пунктов меню, который Вы можете сгенерировать на сайте jQuery в разделе jQueryUI или найти в исходниках к уроку (или написать стили для пунктов меню самостоятельно в зависимости от дизайна Вашего сайта).
У нас будет 2 файла. Первый файл (index.php) – это страница сайта для общего доступа. Второй файл (admin.php) – это страница админки, на которой мы сможем изменять позицию пунктов меню. Конечно же, доступ к админке должен быть ограничен (как это сделать Вы можете узнать из предыдущих уроков). Основное отличие файла admin.php состоит в том, что мы подключили в него 2 указанных скрипта:
<script src="scripts/jquery-1.6.2.min.js" type="text/javascript"></script> <script src="scripts/jquery-ui-1.8.14.custom.min.js" type="text/javascript"></script>
В файл index.php эти библиотеки подключать не нужно.
Также в оба файла мы подключим файл стилей:
<link type="text/css" href="css/jquery-ui-1.8.14.custom.css" rel="stylesheet" />
И напишем несколько правил в стилях на странице index.php:
<style>
#sortable { list-style-type: none; margin: 0; padding: 0; width: 200px; }
#sortable li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 1.4em; height: 15px; cursor: pointer;}
#sortable li span { position: absolute; margin-left: -1.3em; }
</style>
И на странице admin.php:
<style>
#sortable { list-style-type: none; margin: 0; padding: 15px 40px 15px 0; width: 200px; }
#sortable li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 1.4em; height: 15px; cursor:move}
#sortable li span { position: absolute; margin-left: -1.3em; }
.block{/*border:1px solid #ccc;*/ width:200px;}
</style>
Следующее, что нам понадобится – это БД, в которой будут храниться названия каждого из пунктов меню и их текущая позиция на сайте. Чтобы не создавать БД вручную, Вы можете импортировать дамп БД из исходников (файл test.sql).
БД я назову test и создам в ней таблицу sortable, для которой понадобится всего 3 поля:
id, тип INT, первичный ключ, автоинкремент;
name, тип VARCHAR, длина 255 символов;
position, тип INT.
Теперь занесем в созданную таблицу 3 тестовых пункта меню:
Пункт 1 с позицией 1;
Пункт 2 с позицией 2;
Пункт 3 с позицией 3;
Отлично! БД готова.
2. Выводим меню из БД
БД создана и теперь можно вывести меню на сайт. Прежде, чем сделать это создадим файл с подключением к БД. Этот файл мы будем включать на индексную и админскую страницы сайта. Я назову файл db.php. Как подключаться к серверу БД и выбирать необходимую для работы БД мы уже знаем, поскольку неоднократно это делали:
<?php
mysql_connect("localhost", "root", "") or die("No connect to server");
mysql_select_db("test") or die("No select DB");
?>
Теперь подключим этот файл в самом верху индексной и админской страницы:
<?php require_once 'db.php'; ?>
Отлично! Теперь выведем пункты меню на сайт. Для этого создадим заявку (запрос), которой выберем из таблицы sortable все, что там есть, и отсортируем выбранное по полю position в порядке возрастания (таким образом, пункты меню будут выведены традиционно – 1, 2, 3). С запросами мы уже также работали, поэтому ничего нового здесь быть для Вас не должно.
Открываем конструкцию PHP в том месте, где должно быть выведено меню и пишем код:
<?php
$res = mysql_query("SELECT * FROM `sortable` ORDER BY `position`") or die(mysql_error());
echo "<ul id='sortable'>\r\n";
while($row = mysql_fetch_assoc($res)){
echo "<li id='{$row['id']}' class='ui-state-default'>{$row['name']}</li>\r\n";
}
echo "</ul>";
?>
Здесь мы выводим пункты меню списком. При этом стоит обратить внимание на то, что каждый из пунктов имеет свой идентификатор, значением которого является идентификатор конкретного поля в БД. Этот идентификатор нам понадобится для того, чтобы уникализировать каждый из пунктов меню.
Отлично!
Пункты меню выбраны из БД и появились на сайте.
3. Реализуем сортировку без сохранения
С файло index.php мы закончили и теперь можно перейти к админке. Для начала просто скопируем код вывода меню из индексного файла. Теперь, если посмотреть в браузере страницу admin.php, то увидим аналогичное меню за одним исключением – при наведении на пункты меню курсор приобретает крестовидную форму, что говорит о том, что данные пункты можно перетаскивать. Реализуется такая форма курсора правилом в стилях:
cursor:move
Это правило мы прописали ранее. Курсор изменяет свою форму, но пункты меню пока что невозможно перетаскивать. Для того, чтобы это было возможно сделать, пропишем простой скрипт в блоке head:
<script type="text/javascript">
$(document).ready(function(){
$('#sortable').sortable({
});
});
</script>
Все…
Теперь мы уже можем перетаскивать пункты меню. Это реализовано благодаря работе тех двух библиотек, которые мы подключили ранее. Здесь же мы просто взяли в набор jQuery элемент с идентификатором sortable и вызвали для него метод sortable. Если Вы не знакомы с основами jQuery, то рекомендую Вам обратиться к предыдущим урокам на сайте, где мы знакомились с основами работы jQuery. Сам метод sortable, к которому мы обратились, описан в библиотеке jQuery UI. Он имеет множество параметров, событий и методов, некоторыми из которых мы сейчас и воспользуемся. Прежде всего, давайте ограничим перемещение блоков только осью Y (только по вертикали). Для этого обратимся к опции axis:
<script type="text/javascript">
$(document).ready(function(){
$('#sortable').sortable({
axis: 'y'
});
});
</script>
Теперь давайте уменьшим непрозрачность перетаскиваемого элемента до 50%:
<script type="text/javascript">
$(document).ready(function(){
$('#sortable').sortable({
axis: 'y',
opacity: 0.5
});
});
</script>
Отлично!
Теперь надо сделать так, чтобы мы могли получить текущую позицию каждого из элементов после того, как мы завершим перемещение. Для этого обратимся к событию stop и методу (функции) toArray:
<script type="text/javascript">
$(document).ready(function(){
$('#sortable').sortable({
axis: 'y',
opacity: 0.5,
stop: function(){
var arr = $('#sortable').sortable("toArray");
alert(arr);
}
});
});
</script>
Итак, что мы здесь сделали? После наступления события stop (когда завершено перетаскивание элемента) мы обращаемся к элементу с id sortable (это наше меню) и вызываем функцию toArray. Данная функция получает id каждого из отсортированных элементов и помещает его в массив в виде строки, где значения разделены запятой. Результат помещаем в переменную arr. Таким образом, если мы изменим изначальную позицию пунктов 1 и 2, то в переменной arr будет содержаться вот такая строка – 2, 1, 3. Для наглядности можно вывести методом alert значение переменной arr после каждого из перетаскиваний.
4. Обращаемся к методу ajax
Мы выполнили часть задачи – пункты меню можно теперь перетаскивать. Но они не сохраняют своей позиции в БД и после обновления страницы, все встает на круги своя. Для того, чтобы обновления были внесены в БД, необходимо передать значение переменной arr в скрипт PHP, который бы занес обновленные данные в БД. Сделать это, обратившись к методу jQuery под названием ajax(). Итак, пропишем его со всеми необходимыми нам параметрами:
<script type="text/javascript">
$(document).ready(function(){
$('#sortable').sortable({
axis: 'y',
opacity: 0.5,
stop: function(){
var arr = $('#sortable').sortable("toArray");
//alert(arr);
$.ajax({
url: 'save.php',
type: 'POST',
data: {masiv:arr},
error: function(){
$('#res').text("Ошибка!");
},
success: function(){
$('#res').text("Сохранено!");
}
});
}
});
});
</script>
Пройдемся по параметрам:
url: указываем имя файла, который примет данные из скрипта (аналог атрибута action в форме);
type: тип передаваемых данных (аналог атрибута method в форме);
data: передаваемые данные в формате {переменная:значение};
error и success: события ошибки и успеха запроса соответственно.
Таким образом, мы передаем значение переменной masiv методом POST в файл save.php. В случае успеха в блок с идентификатором res будет добавлен текст "Сохранено!", в случае ошибки – «Ошибка!».
Все просто…
5. Реализуем сохранение сортировки
Осталось написать скрипт для файла save.php, который бы принимал данные. Создадим файл save.php и запишем в него следующий код:
<?php
require_once 'db.php';
$pos_new = 1;
foreach($_POST['masiv'] as $item){
$res = mysql_query("UPDATE `sortable` SET `position`='{$pos_new}' WHERE `id`='{$item}'");
$pos_new++;
}
?>
Теперь давайте попробуем разобраться в работе того, что мы написали только что.
6. Логика работы скрипта
Поскольку мы принимаем массив данных – используем цикл foreach для того, чтобы пройтись по каждому из элементов массива. До начала цикла создадим переменную $pos_new со значением 1, которая будет новым значением позиции для каждого из пунктов меню. В теле цикла мы будем с каждым шагом цикла увеличивать значение переменной на единицу. Таким образом, ее значение последовательно будет изменяться от 1 до 3. Также в теле цикла указываем запрос, которым устанавливаем текущее значение переменной $pos_new значением поля position. Но делаем мы это для того поля, в котором значение поля id будет равно текущему значению перебираемого элемента массива, который мы получили. Здесь важно понять саму логику работы запроса. Поскольку мы передаем в массиве идентификаторы каждого из пунктов меню, то логично, что они будут соответствовать идентификаторам пунктов меню в БД. Именно поэтому для полученного идентификатора мы установим текущее значение переменной $pos_new в БД.
Вам проще будет уяснить работу скрипта, если Вы при помощи метода alert будете видеть что отсылается и наблюдать изменения в БД.
7. Добавляем юзабельности
Осталось добавить некоторые улучшения, которые сделают более приятной работу со скриптом. Например, мы можем после каждого сохранения только на время показывать текст "Сохранено!", а затем сделать так, чтобы он исчезал. Также сделаем так, чтобы место блока, который мы захватили, подсвечивалось:
<script type="text/javascript">
$(document).ready(function(){
$('#sortable').sortable({
axis: 'y',
opacity: 0.5,
placeholder: 'ui-state-default',
containment: '.block',
stop: function(){
var arr = $('#sortable').sortable("toArray");
//alert(arr);
$.ajax({
url: 'save.php',
type: 'POST',
data: {masiv:arr},
error: function(){
$('#res').text("Ошибка!");
},
success: function(){
$('#res').show().text("Сохранено!").fadeOut(1000);
}
});
}
});
});
</script>
Теперь гораздо лучше. Вот и все. Наша задача реализована.
Заключение
Пункты меню после перетаскивания сохраняют свою позицию в БД. Стоит только напомнить о безопасности. В принципе, об этом я уже неоднократно говорил в предыдущих уроках, но напомню основное правило безопасности: все данные, принимаемые от пользователя, должны соответствующим образом быть обработаны. Здесь, конечно, в этом особого смысла нет, поскольку работа с БД осуществляется на уровне админки, но если бы мы принимали данные из пользовательской части, то каждый из элементов массива необходимо было бы привести к явному целочисленному типу функцией (int) или intval(), чтобы в запрос гарантированно попадало число.
На этом наш урок завершен. Ваши вопросы и отзывы всегда будем рады видеть в комментариях. Удачи в Ваших разработках и до новых встреч!
Автор: Кудлай Андрей. Команда webformyself.
| Подписаться |
|
Поделиться |
|
Метки: сортировка меню
Популярные записи
Монетизация сайта с помощью ссылочных бирж.
Как создать свой первый профессиональный дизайн сайта с нуля.
На пути к монетизации сайта: увеличиваем рейтинг сайта через наращивание ссылочной массы.
Загибающийся флеш-уголок для сайта.
Создание шаблона для отдельной страницы WordPress.





















Спасибо, как всегда пошаговая и подробная инструкция. Урок пригодится.
Нравится или не нравится:
2
1
Очень интересно!
Спасибо!!!
Теперь не успокоюсь, пока где-нибудь не опробую!
Нравится или не нравится:
1
0
Спасибо за очень добротно сделанный и полезный урок.
Нравится или не нравится:
1
0
Понравилось, как всегда всё понятно, но пока ещё придётся разбираться, как я поняла.
Нравится или не нравится:
1
0
Андрей, подскажите, пожалуйста, как на Вордпресс сделать Популярные записи картинками, как у вас, а не просто заголовок статьи.
Нравится или не нравится:
2
0
Если не ошибаюсь, то в этом Вам поможет плагин WordPress Related Posts. Также можете посмотреть плагин WordPress Popular Posts и другие похожие.
Нравится или не нравится:
3
0
Да, как сказал Андрей, я использовал плагин WordPress Popular Posts, но не в читом виде, так как он картинки не выводит, а дописывал его немного, чтобы он выводил картинки. Картинки которые выводятся нужно делать миниатюрами – в эту сторону копать нужно, если хотите подобное сделать.
Нравится или не нравится:
2
0
Супер урок!!! Побольше бы таких про ajax!!!
Нравится или не нравится:
0
0
Спасибо за урок! Автору ОГРОМНЫЙ респект!!!
Нравится или не нравится:
0
0
О да.. Давно хотел сделать, но с аяксом не особа знаком.. Сделал сортировку вотографий в фотоальбоме, потом ужаснулся… Так низя
Если в альбоме больше 100 фоток, представляете что будет? Сколько будет инсертов в БД внутри цикла?
Нравится или не нравится:
0
0
Логично
Этот способ хорош для незначительного количества информации – блоки, пункты меню и т.п.
Нравится или не нравится:
0
0
Скажем так, раз они перемещаются, сохраняя позицию и без записи, то впринципе сабмит можно повесить на кнопку. Хотя наверное логичнее менять местами 2 цифры каждый раз.. Вот это было бы идеально. Где бы ещё пример реализации найти для ознакомления..
Нравится или не нравится:
0
0
Кстати, как бы проверить откуда пришёл запрос? Куда всавить переменну, или идентификатор, чтобы он и массиву не мешал и можно было проверить его наличие в скрипте сохраниения.
Нравится или не нравится:
0
0