css, html, php, javascript, jQuery, ajax … – решения, примеры, рецепты
28 Янв
Внимание! Эта статья устарела. Новая статья по этой теме: «jQuery UI – плагин Sortable». Давайте используем возможности jQuery для создания сортируемого с помощью drag-and-drop списка. Возможность сортировать список с помощью простого перетаскивания мышкой его пунктов, наверняка сможет произвести впечатление на Ваших пользователей. Только не забывайте одну важную вещь: применение всех этих «фишек» должно быть целесообразным и соответствовать ожиданиям пользователя. Не стоит применять такие эффекты сплошь и рядом – можно получить совсем не тот результат, на который Вы рассчитывали. Это было небольшое лирическое отступление, а теперь – к делу.
Как обычно, первым делом рассмотрим работу пары примеров.
Меню слева работает с опциями, установленными по умолчанию. Все, что нужно для создания такого меню (разумеется, кроме библиотеки jQuery и своего HTML-кода), это написать следующее:
$("#menuList").sortable();
где #menuList – это идентификатор списка.
В меню справа использованы некоторые дополнительно установленные опции. Код конечно немного посложнее, но и в нем нет абсолютно ничего страшного.
Вы можете скачать исходный код примера, и при наличии библиотеки jQuery воспроизвести это пример на своем сайте.
А теперь разберем примеры более подробно. Этот пример для своей корректной работы требует подключения достаточно большого количества различных вспомогательных файлов.
<script src="js/jquery-1.2.1.js" type="text/javascript"></script> <script src="js/jquery.dimensions.js" type="text/javascript"></script> <script src="js/ui.mouse.js" type="text/javascript"></script> <script src="js/ui.draggable.js" type="text/javascript"></script> <script src="js/ui.draggable.ext.js" type="text/javascript"></script> <script src="js/ui.droppable.js" type="text/javascript"></script> <script src="js/ui.droppable.ext.js" type="text/javascript"></script> <script src="js/ui.sortable.js" type="text/javascript"></script>
Все файлы уже знакомы по предыдущим примерам. Добавился только один файл ui.sortable.js, который (как и все остальные) мы подключаем в разделе HEAD нашей страницы.
Из таблицы стилей остановлюсь только на небольшом моменте, поскольку это по большому счету дело вкуса.
.dragStyle {
background:#CFD4E6;
border:1px solid #727EA3;
}
Класс dragStyle используется во втором примере и применяется в момент перемещения элемента, отображая то место, на которое перемещаемый элемент будет «сброшен».
Далее полностью приведен кусок кода, который и отвечает за работу обоих списков.
<script type="text/javascript">
$(document).ready(function(){
$("#menuList").sortable(); // 1-ый спискок
$("#menuList2").sortable({ // 2-ой список
hoverClass: "dragStyle",
start: function(ev, ui) {
var text = $(ui.draggable.element).text();
$("#result").text("Перемещаем " + text);
},
stop: function(ev, ui) {
$("#result").text("Перемещение окончено!");
}
});
});
</script>
Вот так просто. За работу первого списка отвечает всего-навсего одна строка кода. Для второго списка мы используем некоторые дополнительные опции.
hoverClass – опция содержит название класса, который будет применен в процессе перемещения одного из пунктов списка, чтобы указать место, куда перемещаемый пункт будет «сброшен».
start – здесь указываем функцию, которая выполнится в момент старта перемещения элемента списка. В этой функции мы обращаемся к перемещаемому элементу, получаем его содержимое в виде текста и записываем в переменную text. Затем отыскиваем элемент #result и вставляем текст туда.
stop – указываем функцию, которая выполнится в момент, когда произошел «сброс» элемента на нужную позицию (независимо от того изменилась ли фактическая позиция элемента). Тут тоже все предельно просто – вставляем текст сообщения в элемент #result.
Я использовал для примера всего несколько опций, а их полный список опций можно найти на сайте разработчиков библиотеки.
Буду рад, если найдете возможность оставить свой комментарий или задать вопросы.
Отзывов (63) на «Пользовательские интерфейсы jQuery: drag-and-drop сортируемый список.»
А переносить элементы из списка в список можно?
Где-то видел такой вариант, но это несколько другая история. Если найду – попробую рассказать в следующих статьях. Разве я что-то упустил. Можете посмотреть источник:
http://docs.jquery.com/UI/Sortables
В правом списке случился баг – объект дропается вместо другого, а «пустое место» под него так и остаётся пустым.
завтра ещё гляну…
а вот еще бы узнать, как получать порядковый номер элемента, котрый переместили.. какой номер был и какой стал
Статья была написана 28 января. На тот момент последней версией библиотеки jQuery была 1.2.1, а сейчас уже 1.2.6. На тот момент приходилось подключать еще от 4 до 6 дополнительных файлов, а теперь плагин sortable зависит (ну, кроме самой jQuery понятно) только от ui.core.js
Сам плагин тоже не стоял на месте и развивался – появились дополнительные возможности.
Об этом постараюсь рассказать в будущем, а кто хочет разобраться сам, пожалуйста:
Страница плагина
Демонстрация функциональности
Спасибо, только сейчас пришло в голову..наверное через DOM можно)
Я столкнулся с проблемой, мне нужно использовать sortable одновременно с resizable. Вобщем хочу сделать по типу как iGoogle, только так, чтобы каждому окошку (sortable элементу) можно было изменять размер. Скорее всего два файла ui.sortable.js и ui.resizable.js переопределяют одни события мыши и каким-то образом их портят.
Я слил эти два файла в один, и когда resizable определяется выше по коду, то не работает sortable и наоборот.
Вы не сталкивались с таким? Если Вам не трудно подсказать, то помогите мне.
Я бы Вам посоветовал для начала взять вот отсюда http://ui.jquery.com/download_builder/ нужные файлы (последнюю stable версию). Во-первых – гарантия «свежести», во вторых закачка настраиваемая, т.е. у Вас сразу в одном файле получится все то, что требуется для задуманного Вами.
Спасибо большое, я так сделал, но не помогло, возможно проблема не в этом. Буду бороться.
(в качестве дополнения к моему предыдущему посту)
Дело в том, что самая последняя стабильная версия – 1.52 не работает по данному вопросу, а релиз кандидат 1.6RC позволяет совместить sortable и resizable, хотя делает он это коряво, к тому же 1.6RC работает некорректно в тех местах, где 1.52 работает хорошо. Легче изменить немного подход и избежать ресайза, чем расчитывать на релиз, который неизвестно когда выйдет.
Спасибо за внимание )
Здравствуйте, Геннадий!
Скажите, а в Вашем разделе Downloads сложены дистрибутивы какой давности? Скажем так, Вы следите и обновляете дистрибутивы, или же на этом сайте лежат только те версии файлов, которые использованы в примерах?
В разделе downloads выложены именно те версии, которые использованы в примерах. Поскольку библиотека развивается достаточно быстро и в плагины для нее тоже вносятся изменения, то самые свежии версии плагинов лучше искать непосредственно на сайте jQuery. Либо в разделе официальных плагинов – http://docs.jquery.com/UI, либо среди вообще всех плагинов к jQuery – http://plugins.jquery.com/
Здравствуйте Gennady! Подскажите пожалуйста почему неудается перетягивать пункты меню если они были подгружены посредством Ajax.
Изеняюсь, нашел подходящую статью http://www.linkexchanger.su/2008/73.html
Если в Опере 9,63 ткнуть в ссылку «Вы можете скачать исходный код примера..», то перетаскивание в примере работать перестаёт.
Подскажите, пожалуйста, столкнулся с такой проблемой.
Если список представляет из себя картинки с ссылками. То при попытке перетащить картинку сразу переходишь по ссылке. Пробовал
start: function(event, ui){
$j(«.a»).click(function(){ return false; });
}, Тогда ссылка становится не активной еще до перемещения.
HTML-разметка:
<ul id=»First»>
<li><a href=»axis.html»><img src=»1.jpg» /></a></li>
<li><a href=»cancel.html»><img src=»2.jpg» /></a></li>
<li><a href=»opacity.html»><img src=»3.jpg» /></a></li>
<li><a href=»revert.html»><img src=»4.jpg» /></a></li>
<li><a href=»axis.html»><img src=»5.jpg» /></a></li>
</ul>
JS-код простейший:
$('#First').sortable();Работает как часы – т.е. по клику идет куда надо, а если схватить и тащить – тащится…
как получить перетаскиваемый элемент понятно
это ui.item
а как получить элемент который мы заменили другим?
Заменили в каком смысле? Где? Это списки – тут изменяется всего лишь позиция элемента. Другое дело, что эту позицию можно узнать, вызвав по событию callback-функцию, которая например вернет индекс элемента в jQuery-наборе.
P.S. я действительно не очень въехал, что значит «заменили» применительно к этой статье…
А подскажите пожалуйста как узнать порядковый номер каждого элемента в списке после каждого изменения…
Знаете, статья очень старая (полтора года), да и очень краткая. Sortable очень изменился с тех пор, а написать новую статью никак не могу выбрать время. Попробуйте посмотреть тут:
http://docs.jquery.com/UI/API/1.7.1/Sortable
или даже тут (есть примеры):
http://jqueryui.com/demos/sortable/
правда все на англ.яз.
http://jqueryui.com/demos/sortable/ – тут нету того чего я хочу((((
Пожалуйста помогите очень нужно!!!
—как узнать порядковый номер каждого элемента в списке после каждого изменения…—
Ну, если уж там нет …
Давайте попробуем прикинуть, как такую проблему можно порешать. Наверное надо в опции stop определить callback-функцию (считать-то элементы надо по окончании перемещения, верно?). Значит теперь прикинем саму функцию. Она должна отобрать в набор все элементы li в соответствующем ul, дальше по ним можно будет пробежаться, примерно так:
stop: function(ev, ui) { // ev и ui - если нужны $('#menuList2 li').each(function(i){ alert(i + ' - ' + $(this).text()); }); }в результате при окончании перемещения по идее должно появиться столько алертов, сколько li в списке. i – по сути порядковый номер (от 0 и далее), а через тире – текст очередного элемента li.
Gennady – большое спасибо!!! помогли!
Gennady
а возможно такое:
после каждого изменения вывести id всех li…?
т. е.
Понедельник
Среда
Вторник
после всех изменений результат должен быть таким:
231
Надеюсь все понятно ….
(li id=»2″) Понедельник
(li id=»1″) Среда
(li id=»3″) Вторник
или даже не id, а value каждого элемента li
я пробовал так:
alert(i + ‘ – ‘ + $(this).value());
но ничего не вышло…=(
А Вы где-то видели у элемента li value??? В этом смысле выступает текст, содержащийся внутри тэга li (в примере я так и набросал). А id можно получить так:
$('#menuList2 li').each(function(i){ alert(i + ' - ' + $(this).attr('id')); });Gennady – большое спасибо!!! Даже с value работает, то что надо!!!
Подскажите пожалуйста, как бы так сделать.
вопрос номер 1
Есть 2 списка, надо построить их в виде таблички, при этом чтобы можно было перетаскивать из одного в другой элементы. Пробую делать float:left элементам, выстраиваеться как надо, но при этом не работает коннект между списками =(, убираю флоат и все нормально.
Вопрос номер2
Как бы сделать так, чтобы в этих табличках (списках) оставалось одинаковое количество ячеек, т.е. есть пустые клетки, есть заполенные, перетаскиваем заполненную в пустую, при этом она становиться заполненной, а в 1м списке она становилась пустой.
Вопрос номер 3
Как сделать так, чтобы было разделение на заполненные и пустые и чтобы перемещать можно было б только в пустые клетки.
задача примерно такая, экран разбит на 2 части, в левой части опубликованные фото и количество ячеек, сколько можно еще опубликовать, в правой что закачено + пустые ячейки, чтобы показать сколько можно еще закачать.
Михаил, я по последнему абзацу сужу – мне кажется, что использование плагина в принципе здесь не очень оправдано. Наверное такую задачу надо решать используя draggable() и droppable(). В общем конечно это по своей сути те же плагины, но мне думается, что получится лучше, в том смысле, что тут Вы сможете уже как угодно «заточить» все под решение своей задачи.
Собственно говоря, промучавшись порядка 4х часов и не получив болей менее удовлетварительного для сей задачи результата, тоже пришел к такому выводу, чту про них.
За статью спасибо огромное, заставила поковырять эту бублиотечку. Уверен процентов на 100, что пригодиться в дальнейшем.
Начал работать со списками и столкнулся с такой проблемой. В Вашем примере есть строка, где выдергивается содержимое перемещаемого в данный момент элемента:
var text = $(ui.draggable.element).text();
Видимо, это было актуально для старой версии библиотеки. На данный момент такой фокус у меня не проходит. Посему интересует вопрос: что это за объект – UI и какие у него есть свойства? В описании библиотеки, к сожалению, таких сведений не нашел.
Денис, UI это некий объединяющий объект свойственный для всех библиотек из набора UI.
по поводу получения текста текущего объекта, посмотрел новую библиотечку и пришел к выводу, что надо писать так:
var text = $(event.target).text();
Да, спасибо, Михаил
Я уже и сам разобрался. Просто невнимательно листал АПИ.
ui.helper – текущий элемент-хелпер
ui.position – текущее положение элемента-хелпера
ui.offset – текущее абсолютное положение хелпера
ui.item – перетаскиваемый в данный момент элемент
ui.placeholder – плэйсхолдер (в русском не смог подобрать подходящее слово. Это выделенное место, куда воткнется перетаскиваемый элемент)
ui.sender – sortable-лист, откуда принесли элемент (причем это свойство есть только когда мы тащим элементы между связанными списками)
Еще бы разобраться, что это за хелпер такой
А вот теперь у меня затык. Есть у кого-то мысли, как использовать одновременно Sortable и Droppable?
Идея в том, что есть список элементов, который должен сортироваться тасканием. Но помимо этого должна быть возможность Дропа одного элемента на другой.
Здравствуйте.
Перемещая элементы на странице, мне необходимо «закрепить» эти перемещения в HTML-коде. Подскажите, пожалуйста, в каком направлении мне смотреть.
Спасибо.
Игорь, что значит «закрепить»? Перетаскиваем элемент, обновляем страницу, а он отрисовывается там, где мы его оставили? Тогда скорее всего в сторону XML. Еще вариант, хранить код страницы в БД и при изменении менять запись в БД. Я, например, в одном из проектов хранил в БД JSON-представление необходимой мне части сайта, ну и парсил его потом.
Нет, Денис, не совсем так. Вот смотрите: мы перемещаем Пункт меню №1. Смотрим после перемещения на исходный код. Там все остается на месте, как при исходной верстке. А мне бы хотелось, чтобы и там (в HTML-коде) положение элемента li, «отвечающего» за этот пункт меню №1 тоже переместилось.
Путано, конечно, объясняю, но я пока не очень владею компьютерным сленгом. «Чайник» в общем
Игорь, так оно и изменится.
Если визуально вы видите этот элемент в другом месте, значит в модели DOM элемент так же поменял положение. Просмотром исходного кода ничего не добьетесь
Установите браузер Firefox и поставьте к нему плагин Firebug. После установки нажмите правой кнопкой по любому элементу страницы и выберите пункт «Inspect Element». Внизу откроется панелька со структурой страницы, узнаете сразу. Вот там уже можно в реальном времени отслеживать все изменения DOM-структуры.
Спасибо, Денис.
«Есть у кого-то мысли, как использовать одновременно Sortable и Droppable?»
Денис, видимо стоит перейти на модули draggable и droppable. В draggable есть такая опция как connectToSortable, т.е. будет именно сортироваться все также + можно будет дропать.
http://docs.jquery.com/UI/Draggable#option-connectToSortable
в примере вызова sortable наткнулся на следующий код:
$(document).ready(function(){
$(«#sortable»).sortable();
});
бла-бла
соотв, возникло предположение, что sortable можно сделать не только элементы списка , но и строчные элементы для div-а!
так ли это?
прошу прощения, код вставил с ошибкой:
$(document).ready(function(){
$(«#sortable»).sortable();
});
бла-бла
гм… код видимо при выдаче на форму режет визуально div-ы… вобщем бла-бла должно быть обернуто в div c id sortable
Код действительно порезан, поэтому могу предположить, что Вам попался пример портлета. Посмотрите тут:
http://jqueryui.com/demos/sortable/#portlets
портлеты – это немного не то.
Я пробовал вместо списка использовать горизонтальную таблицу с рисунками (разметка div-ами и span-ами) – ячейки с рисунками таскаются, но вкупе все это работает совершенно дико (позиционирование перетаскиваемой ячейки относительно курсора мыши и т.д.).
Не посоветуете что-нибудь? (крайне лень писать уйму обработчиков для draggable/droppable… которые тоже работаю отнюдь не как часы!)
Извините, может я совсем тупой, но прочитал посты и не понял как получить назад порядок расположения элементов списка.
У меня содержимое списка вызывается из базы и сортируется в соответствии с порядковым номером каждого элемента (через ПХП). После перетаскивания порядок меняется. Так как получить соответствие элемента и его положения в списке и передать в ПХП?
К несчастью не очень силён в JS.:-(
Знаете, если говорить о конкретном посте, то он конечно устарел – все-таки полтора года. Я бы Вам посоветовал посмотреть современные примеры:
http://jqueryui.com/demos/sortable/
А принципиально – когда Вы создаете список, Вы же используете php для заполнения элементов списка текстом, так? Почему бы не заполнить атрибут например id (или еще какой) скажем идентификатором из БД или чем-то подобным?
Тогда, по окончании сортировки (опция stop см. пример, можно даже в этом посте) Вам надо будет написать функцию, которая бы «собрала» все значения атрибутов id (или других) этого списка.
Примерно так:
stop: function(){ var newOrder = new Array(); $("#myList li").each(function(){ newOrder.push($(this).attr("id")); }); alert(newOrder.join(",")); }Ес-но вместо alert можно тут же организовать ajax-запрос к серверу, чтобы передать ему новый порядок элементов…
Спасибо за оперативный ответ. Примерно так и поступил. Только с той разницей, что новый порядок ID занёс в куки, а потом из PHP их считал и обновил в базе.
К несчастью на сайте http://jqueryui.com/demos/sortable/ не нашёл примера с передачей параметров в ПХП.
Кто-нибудь видел похожий плагин, но что бы работал со списками второго уровня.
ps Мой первый комент и я просто не могу добавить, что это отличный портал, спасибо создателю. =)
Так он работает со списками и второго и следующих уровней.
хм, я имею ввиду – есть структура
X
X
X
X
Y
Y
Y
Y
Y
X
…..
нужно что бы «Y» «DRAG&DROP-лись» между собой а «X» меджу собой. Ну и соответственно если ты переносишь «Х» с вложенным в него «Y», «Y» тоже переносились вслед за родительским .
Заранее спасибо за ответ =)
ps в прошлом посте хотел написать
«ps Мой первый комент и я просто не могу НЕ добавить, что это отличный портал, спасибо создателю. =)»
Не учел что теги не влезут( X это «li» первого уровня а Y это «li» второго уровня.
У меня второй уровень (Y) между собой не перемещается тк он идет как li первого уровня и перемещается относительно первого списка одним целым.
Проще говоря, то что с восклицательным знаком в графе «удалить»(разделы) должны «шафлиться» между собой, а то что со знаком «стоп»(подразделы) должны «шафлиться» между собой.
http://img215.imageshack.us/img215/7952/72606437.png
ps извините за флуд в 3 поста)
Эта статья старая уж больно – больше полутора лет… Сильно изменилась библиотека. Вы «первоисточник» не смотрели?
http://jqueryui.com/demos/sortable/
Может что-то похожее там найдется…
Gennady – к сожалению, в демках, нечего подходящего не нашел. Надеялся, что может тут кто сталкивался с похожей проблемой.
finkel,
может вот это пригодится:
http://news.kg/wp-content/uploads/tree/
может целиком, а может так, идею посмотреть…
Кстати, у меня вопрос к Вам – я так понимаю у Вас доступ в интернет – 4G через yota.ru? Просто хотел услышать отзыв человека, который это реально использует.
Gennady,
У нас на работе роутер, в нем yota на 10 компьютеров. Конечно не шик, но работает неплохо. У одного товарища личный модем, он доволен.
За ссылку спасибо, сейчас буду разбираться.
To finkel:
), а вот если внутри зданий связь ничего (ну понятно там – в зоне покрытия конечно), то наверное стоит попробовать… Мобильность + хорошая скорость очень нужна, но все сомневаюсь, стоит ли пробовать. А то в BeeLine WiFi я например разочаровался…
Еще побеспокою Вас… А тот товарищ у которого личный модем не может поделиться информацией, как насчет качества связи именно внутри зданий? На улице-то не особо нужно (и на 120 км/ч в общем тоже
Столкнулся с такой проблемой: мне нужно, чтобы объект Sortable также обрабатывал событие Click. В IE и Opera работает нормально, а в Firefox вызывает Click еще и при окончании перетаскивания… Как быть?
Проблема решена (пробился три дня)!
Установлена опция helper:’clone’, т.о. событие Click, видимо, не попадает на сам объект.
Оставьте отзыв