Модуль UI Sortable — сортировка элементов

Модуль UI Sortable позволяет сортировать элементы с помощью мыши. Для загрузки модуля переходим на страницу http://jqueryui.com/download. Оставляем установленными флажки UI Core, Draggable, Sortable, 1.7.2, а затем щелкаем на кнопке Download. Распаковываем архив в отдельную папку. Из этого архива для работы модуля необходимы следующие файлы:

  • jquery-1.3.2.min.js (папка js);
  • jquery-ui-1.7.2.custom.min.js (папка js).

Все указанные файлы необходимо подключить к скрипту в том порядке, в котором они перечислены. В качестве примера рассмотрим функциональные возможности модуля с параметрами, принятыми по умолчанию, а также применение опции connectToSortable (листинг 12.7).

Листинг 12.7. Модуль UI Sortable, сортировка элементов списка

<!doctype html>
<html>
<head>
<title>Модуль UI Sortable. Сортировка элементов списка</title>
<meta charset="utf-8">
<script src="js/jquery.js"></script>
<script src="js/jquery-ui-1.7.2.custom.min.js"></script>
<style>
body { font-size:10pt; font-family:Verdana, sans-serif; }
ul { margin:0; padding:0; list-style-type:none; }
li { margin: 0 3px 3px 20px; padding: 5px 5px 5px 20px;
     width:200px; height:18px;
     font-size:16px; font-family:Verdana, sans-serif; 
     border: 1px solid #000000; color:#000000; font-weight:bold; }
.itemColor1 { background-color:#fff4dd; }
.itemColor2 { background-color:#d5dee7; }
</style>
<script>
$(document).ready(function() {
   $("#sortable").sortable().disableSelection();
   $("#draggable li").draggable({
      helper: "clone", // Перемещение копии элемента
      // Пункты можно добавить в список с id=sortable
      connectToSortable: "#sortable"
   }).disableSelection(); // Запрещаем выделение текста пунктов
});
</script>
</head>
<body>
<span style="font-weight:bold;">Сортируемый список</span><br><br>
<ul id="sortable">
<li class="itemColor1">Пункт 1</li>
<li class="itemColor1">Пункт 2</li>
<li class="itemColor1">Пункт 3</li>
<li class="itemColor1">Пункт 4</li>
</ul><br><br>
<span style="font-weight:bold;">Из этого списка можно добавить пункты
в сортируемый список</span><br><br>
<ul id="draggable">
<li class="itemColor2">Пункт 1</li>
<li class="itemColor2">Пункт 2</li>
<li class="itemColor2">Пункт 3</li>
<li class="itemColor2">Пункт 4</li>
</ul>
</body>
</html>

Для того чтобы элементы можно было сортировать с помощью мыши, необходимо применить метод sortable(). Формат метода:

sortable([<Объект с опциями>])

Параметр <Объект с опциями> представляет собой объект, состоящий из пар "опция/значение". Могут быть указаны следующие опции.

  • items — определяет, какие элементы должны быть сортируемыми. В качестве значения указывается селектор jQuery. Значение по умолчанию — "> *".
  • axis — позволяет ограничить перемещение элемента. Могут быть указаны следующие значения:
  • x — перемещение только по горизонтали;
  • y — перемещение только по вертикали;
  • false — без ограничения (значение по умолчанию).
  • revert — если указано значение true, то после "сброса" элемента перемещение на новое место будет происходить с анимацией. Значение по умолчанию — false.
  • containment — позволяет ограничить перемещение в пределах указанных границ. В качестве значения можно указать DOM-элемент, селектор jQuery или одно из значений:
  • parent — в пределах родительского элемента;
  • window — в пределах окна;
  • document — в пределах всего документа.

Значение по умолчанию — false.

  • opacity — задает степень прозрачности элемента во время перемещения. Может быть указано вещественное число от 0.01 до 1. Значение по умолчанию — false.
  • cursor — вид курсора при перемещении элемента. Указывается одно из значений атрибута cursor в CSS. Значение по умолчанию — auto;
  • cursorAt — задает местоположение курсора при перемещении элемента. В качестве значения указывается объект с комбинацией следующих свойств:
  • top — положение относительно верхней границы;
  • left — положение относительно левой границы;
  • right — положение относительно правой границы. При положительных значениях курсор сдвигается внутрь элемента, а при отрицательных значениях — наружу от элемента справа;
  • bottom — положение относительно нижней границы. При положительных значениях курсор сдвигается внутрь элемента, а при отрицательных значениях смещается от элемента вниз.

Значение по умолчанию — false (при перемещении элемента курсор располагается в том месте, где был произведен щелчок мышью).

Рассмотрим несколько примеров. Во время перемещения курсор будет находится над верхней границей элемента.

cursorAt: { top: 0 }

Курсор будет расположен в левом верхнем углу.

cursorAt: { top: 0, left: 0 }

Курсор будет расположен на одном уровне с верхней границей, но сдвинут на 5 px от элемента относительно правой границы.

cursorAt: { top: 0, right: -5 }

Курсор будет смещен на 5 px ниже нижней границы и на 5 px от левой границы элемента.

cursorAt: { bottom: -5, left: -5 }
Обратите внимание
  • delay — позволяет задать задержку в миллисекундах перед началом перемещения элемента. Используется для предотвращения нежелательного перемещения при случайном щелчке на элементе. Значение по умолчанию — 0.
  • distance — расстояние в пикселях, после прохождения которого начинается перемещение элемента. Используется для предотвращения нежелательного перемещения при случайном щелчке на элементе. Значение по умолчанию — 1.
  • grid — устанавливает шаг перемещения по горизонтали и вертикали (в пикселях). В качестве значения указывается массив с двумя элементами.
[<Шаг по горизонтали>, <Шаг по вертикали>]

Рассмотрим пример.

grid: [40, 20]

Значение по умолчанию — false.

  • scroll — если указано значение false, то перемещение элемента за границы окна не будет приводить к автоматической прокрутке документа. Значение по умолчанию — true.
  • scrollSensitivity — расстояние (в пикселях) от края окна, при котором будет происходить прокрутка документа. Обратите внимание на то, что расстояние отсчитывается от указателя мыши, а не от границы перемещаемого элемента. Значение по умолчанию — 20.
  • scrollSpeed — скорость прокрутки документа. Значение по умолчанию — 20.
  • helper — позволяет указать элемент, который будет перемещаться. Могут быть указаны следующие значения:
  • original — перемещается сам элемент (значение по умолчанию);
  • clone — перемещается копия элемента.

В качестве значения может быть указана ссылка на функцию. В этом случае функция должна возвращать DOM-элемент.

  • appendTo — ссылка на элемент-контейнер, в конец которого будет вставляться элемент, указанный в опции helper или если значение опции helper равно clone. Значение по умолчанию — parent (для вставки используется родительский элемент).
  • zIndex — значение CSS-атрибута z-index при перемещении элемента. Значение по умолчанию — 1000.
  • tolerance — определяет, в каком случае "сбрасывание" будет успешным. Могут быть указаны следующие значения:
  • intersect — если перемещаемый элемент на 50% расположен над новой позицией (значение по умолчанию);
  • pointer — если указатель мыши находится над новой позицией.
  • handle — позволяет указать один или несколько элементов внутри блока, захватив которые можно переместить весь блок. В качестве значения указывается селектор jQuery или ссылка на элемент. Значение по умолчанию — false (т.е. переместить можно, захватив любой элемент, кроме указанных в опции cancel).
  • cancel — позволяет указать один или несколько элементов внутри блока, захватив которые нельзя будет переместить весь блок. В качестве значения указывается селектор jQuery. Значение по умолчанию — ":input,option".
  • placeholder — позволяет указать стилевой класс для элемента, служащего "заглушкой" при перемещении пункта списка. Значение по умолчанию — false. Чтобы понять смысл этой опции, рассмотрим все на примере. Итак, например, есть список с двумя элементами.
<ul id="sortable">
<li class="itemColor">Пункт 1</li>
<li class="itemColor">Пункт 2</li>
</ul>

В начале перемещения второго пункта исходный HTML-код списка будет выглядеть следующим образом.

<ul id="sortable" class="ui-sortable" unselectable="on">
<li class="itemColor">Пункт 1</li>
<li class="itemColor" style="width:200px;height:18px;
    position:absolute;z-index:1000">Пункт 2</li>
<li class="itemColor ui-sortable-placeholder" 
    style="visibility:hidden"></li>
</ul>

Как видно из примера, перемещаемый элемент получает абсолютное позиционирование, а на его место вставляется скрытая "заглушка".

<li class="itemColor ui-sortable-placeholder" 
    style="visibility:hidden"></li>

Если в опции placeholder указан стилевой класс (например, cls1), то исходный код "заглушки" будет выглядеть так.

<li class="cls1"></li>
  • forcePlaceholderSize — если указано значение true, то для "заглушки" будет указана высота. Например, при параметрах
placeholder: "cls1",
forcePlaceholderSize: true

исходный код "заглушки" будет выглядеть так.

<li class="cls1" style="height:18px"></li>

Значение по умолчанию — false.

  • connectWith — позволяет указать ссылку на сортируемый список, в который можно переместить элементы текущего списка. В качестве значения указывается селектор jQuery. Значение по умолчанию — false (элементы между списками переместить нельзя).
  • dropOnEmpty — если указано значение false, то элементы из списка в другой пустой список добавить нельзя. Значение по умолчанию — true.

Пример создания сортируемых списков с различными вариантами параметров настройки приведен в листинге 12.8.

Листинг 12.8. Модуль UI Sortable, различные варианты параметров настройки

<!doctype html>
<html>
<head>
<title>Модуль UI Sortable. Различные варианты настроек</title>
<meta charset="utf-8">
<script src="js/jquery.js"></script>
<script src="js/jquery-ui-1.7.2.custom.min.js"></script>
<style>
body { font-size:10pt; font-family:Verdana, sans-serif; }
ul { margin:0; padding:0; list-style-type:none; }
li { margin: 0 3px 3px 20px; padding: 5px 5px 5px 20px; 
     width:200px; height:18px;
     font-size:16px; font-family:Verdana, sans-serif; 
     border: 1px solid #000000; color:#000000; font-weight:bold;
}
.itemColor1 { background-color:#fff4dd; }
.itemColor2 { background-color:#d5dee7; }
.cls1 { border: dotted 1px black; background-color:#ffe9b3; }
</style>
<script>
$(document).ready(function() {
   $("#sortable1").sortable({
      items: "li", // Перемещаем элементы LI
      axis: "y", // Перемещение только по вертикали
      cursor: "s-resize", // Вид курсора при перемещении
      cancel: "span", // За элемент SPAN переместить нельзя
      // Куда можно переместить
      connectWith: "#sortable2,#sortable3",
      delay: 200 // Задержка перед перемещением
   }).disableSelection();
   $("#sortable2").sortable({
      revert: true, // Перемещение с анимацией
      containment: "window", // Перемещение в пределах окна
      opacity: 0.5, // Степень прозрачности
      helper: "clone", // Перемещение копии пункта списка
      placeholder: "cls1", // Класс для "заглушки"
      // Куда можно переместить
      connectWith: "#sortable1,#sortable3", 
      // Добавить элементы в пустой список нельзя
      dropOnEmpty: false, 
      cursorAt: { top: 0 } // Перемещение за верхнюю границу
   }).disableSelection();
   $("#sortable3").sortable({
      // Куда можно переместить
      connectWith: "#sortable1,#sortable2"
   }).disableSelection();
});
</script>
</head>
<body>
<span style="font-weight:bold;">Сортируемый список 1</span><br>
За красный прямоугольник переместить элемент нельзя<br><br>
<ul id="sortable1">
<li class="itemColor1">Пункт 1
<span style="background-color:red;">&nbsp;&nbsp;&nbsp;&nbsp;</span>
</li>
<li class="itemColor1">Пункт 2</li>
<li class="itemColor1">Пункт 3</li>
<li class="itemColor1">Пункт 4</li>
</ul><br><br>
<span style="font-weight:bold;">Сортируемый список 2</span><br><br>
<ul id="sortable2">
<li class="itemColor2">Пункт 1</li>
<li class="itemColor2">Пункт 2</li>
<li class="itemColor2">Пункт 3</li>
<li class="itemColor2">Пункт 4</li>
</ul><br><br>
<span style="font-weight:bold;">Сортируемый список 3</span><br>
Добавить элементы в этот пустой список можно только 
из списка 1<br><br>
<ul style="background-color:#fff4dd;margin:5px;padding:5px;width:250px;"
id="sortable3">
</ul>
</body>
</html>

Чтобы изменить или получить значения опций уже после создания, необходимо использовать второй формат метода sortable(). Для этого в первом параметре указывается значение "option", во втором — название опции, а в третьем — новое значение.

$("#sortable").sortable("option", "delay", "200");

Если необходимо получить значение опции, то третий параметр указывать не нужно. В качестве примера получим значение опции delay.

alert($("#sortable").sortable("option", "delay"));

Второй формат метода sortable() позволяет также управлять элементом. Для этого в первом параметре указываются следующие значения.

  • serialize — получает позиции всех сортируемых элементов и составляет строку, которую можно отправить на сервер с помощью технологии AJAX. Формат метода:
sortable("serialize"[, <Объект с опциями>])

Если параметр <Объект с опциями> не указан, то по умолчанию строка составляется из значений параметров id. Для этого идентификатор элемента должен быть в следующем формате.

<Название>_<Число>

Например:

id="item_1"

В качестве разделителя, вместо символа подчеркивания, можно использовать знак равенства (=) или дефис (-). Если идентификаторы равны item_1, item_2, item_3, то в результате получим следующую строку.

item[]=1&item[]=2&item[]=3

В параметре <Объект с опциями> можно дополнительно указать объект со следующими свойствами.

  • attribute — параметр, из значений которого будет составляться строка. Значение по умолчанию — "id".
  • key — название, которое будет использоваться, например, вместо item[] при значении параметра "item_1".
  • expression — позволяет указать регулярное выражение (объект RegExp) для разбора значения параметра, указанного в свойстве attribute. Значение по умолчанию — /(.+)[-=_](.+)/. Следует учитывать, что при одновременном использовании свойств expression и key в регулярном выражении должна быть только одна подмаска, в противном случае — две.

Рассмотрим пример использования параметра <Объект с опциями>.

$("#sortable").sortable("serialize", {
   attribute: "id",
   key: "myParam[]",
   expression: /_(.+)/
});

Если идентификаторы равны item_1, item_2, item_3, то в результате получим следующую строку.

myParam[]=1&myParam[]=2&myParam[]=3
  • toArray — возвращает массив значений всех идентификаторов сортируемых элементов. Нумерация начинается с 0. Формат метода:
sortable("toArray"[, <Объект с опциями>])

Если идентификаторы равны item_1, item_2, item_3, то в результате выполнения кода

var arr = $("#sortable").sortable("toArray");
var msg = "";
for (var i=0, j=arr.length; i<j; i++)
   msg += "[" + i + "] => " + arr[i] + "\n";
alert(msg);

получим следующий массив.

[0] => item_1
[1] => item_2
[2] => item_3

В параметре <Объект с опциями> с помощью свойства attribute можно указать атрибут тега, значения которого необходимо вернуть.

var arr = $("#sortable").sortable("toArray", {attribute: "id"});
  • cancel — позволяет отменить последнюю сортировку.
  • disable — временно запрещает сортировку элементов.
  • enable — разрешает сортировку элементов, если ранее она была запрещена с помощью метода disable.
  • destroy — удаляет всю функциональность и возвращает все элементы в первоначальное состояние.

Обработать события, происходящие с сортируемым списком, можно двумя способами.

sortable({
   <Событие>: <Функция обратного вызова>
});

или

bind(<Событие>, <Функция обратного вызова>)

В параметре <Событие> могут быть указаны следующие события (в скобках указано значение для метода bind()).

  • start (sortstart) — наступает в начале сортировки.
  • activate (sortactivate) — возникает в начале перемещения элемента любого связанного списка.
  • sort (sort) — срабатывает постоянно в процессе сортировки.
  • out (sortout) — наступает, когда элемент покидает пределы списка или в конце перемещения.
  • over (sortover) — возникает, когда элемент возвращается в пределы списка или только начал движение внутри списка.
  • change (sortchange) — наступает в процессе сортировки, когда позиция элемента внутри списка изменилась.
  • beforeStop (sortbeforeStop) — возникает в конце сортировки, но при данном событии еще доступны элемент "заглушка" и перемещаемый элемент (копия элемента, если опция helper имеет значение clone).
  • receive (sortreceive) — наступает при добавлении элемента из другого списка.
  • update (sortupdate) — возникает после события beforeStop, если позиция элемента изменилась (если позиция осталась прежней, то событие не возникает).
  • remove (sortremove) — наступает, когда пункт списка был перемещен в другой список.
  • deactivate (sortdeactivate) — возникает в конце перемещения элемента любого связанного списка.
  • stop (sortstop) — наступает в конце сортировки.

В параметре <Функция обратного вызова> указывается ссылка на функцию следующего формата.

function <Название функции>([<Объект event>[, <Объект UI>]]) {
   // ...
}

Через параметр <Объект UI> доступны следующие свойства.

  • item — ссылка (объект jQuery) на оригинал перемещаемого элемента.
  • helper — ссылка (объект jQuery) на копию элемента (если опция helper равна clone) или на сам элемент (если опция helper равна original).
  • placeholder — ссылка (объект jQuery) на элемент "заглушка".
  • sender — ссылка (объект jQuery) на связанный список, из которого перемещается элемент. Если элемент перемещается внутри одного списка, то объект не доступен.
  • position — текущая позиция перемещаемого объекта относительно родительского элемента. Доступны два свойства:
  • top — положение сверху;
  • left — положение слева.
  • offset — текущая позиция перемещаемого объекта относительно окна. Доступны два свойства:
  • top — положение сверху;
  • left — положение слева.

Пример обработки различных событий приведен в листинге 12.9.

Листинг 12.9. Модуль UI Sortable, обработка событий

<!doctype html>
<html>
<head>
<title>Модуль UI Sortable. Обработка событий</title>
<meta charset="utf-8">
<script src="js/jquery.js"></script>
<script src="js/jquery-ui-1.7.2.custom.min.js"></script>
<style>
div { margin: 0; padding: 0; }
body { font-size:10pt; font-family:Verdana, sans-serif; }
h2 { background-color: #ffe9b3; font-size: 12pt;
   padding: 3px 3px 3px 10px; margin: 0 0 5px 0;
}
.section {
   margin: 0 0 15px 5px; width: 300px; height: 100px;
   background-color: #fffbef; border: 1px solid #000000;
   color: #000000; font-weight: bold;
}
#sections, #sections2 { width: 400px; }
</style>
<script>
$(document).ready(function() {
   $("#sections").sortable({
      items: "div", // Сортируемые элементы
      handle: "h2", // Перемещение только за заголовок
      revert: true, // Перемещение с анимацией
      connectWith: "#sections2", // Куда можно переместить
      start: function(e, ui) {
         $("#div1").html("Событие start<br>");
         ui.helper.find("h2").css("background-color", "#ff0000");
      },
      sort: function() { $("#div1").append("Событие sort<br>"); },
      change: function() { $("#div1").append("Событие change<br>"); },
      beforeStop: function(e, ui) {
         $("#div1").append("Событие beforeStop<br>");
         ui.helper.find("h2").css("background-color", "#ffe9b3");
      },
      stop: function() {$("#div1").append("Событие stop<br>"); },
      update: function() { $("#div1").append("Событие update<br>"); },
      receive: function(e, ui) {
         $("#div1").append("Событие receive<br>");
         ui.item.find("p")
           .html("Элемент перемещен из другого списка");
      },
      remove: function() { $("#div1").append("Событие remove<br>"); },
      over: function() { $("#div1").append("Событие over<br>"); },
      out: function() { $("#div1").append("Событие out<br>"); },
      activate: function() {
         $("#div1").append("Событие activate<br>");
      },
      deactivate: function() {
         $("#div1").append("Событие deactivate<br>");
      }
   });
   $("#sections2").sortable({
      items: "div", // Сортируемые элементы
      handle: "h2", // Перемещение только за заголовок
      connectWith: "#sections" // Куда можно переместить
   });
   $("#btn1").click(function() {
      $("#sections").sortable("disable");
   });
   $("#btn2").click(function() {
      $("#sections").sortable("enable");
   });
   $("#btn3").click(function() {
      $("#sections").sortable("cancel");
   });
   $("#btn4").click(function() {
      alert($("#sections").sortable("serialize", { attribute: "id", 
         key: "myParam[]", expression: /_(.+)/ }));
      var arr = $("#sections").sortable("toArray", 
                                        { attribute: "id" });
      var msg = "";
      for (var i=0, count=arr.length; i<count; i++)
         msg += "[" + i + "] => " + arr[i] + "\n";
      alert(msg);
   });
});
</script>
</head>
<body>
<input type="button" value="Запретить" id="btn1">
<input type="button" value="Разрешить" id="btn2">
<input type="button" value="Отменить сортировку списка 1" id="btn3">
<input type="button" value="Положение элементов списка 1" id="btn4">
<br><br>
Переместить элементы можно только за заголовок<br><br>
<table border="0"><tr><td valign="top">
<div id="sections">
<div class="section" id="item_1">
<h2>Секция 1</h2><p> Содержимое секции 1</p></div>
<div class="section" id="item_2">
<h2>Секция 2</h2><p> Содержимое секции 2</p></div>
<div class="section" id="item_3">
<h2>Секция 3</h2><p> Содержимое секции 3</p></div>
</div>
</td><td valign="top">
<div id="sections2">
<div class="section" id="item_4">
<h2>Секция 4</h2><p> Содержимое секции 4</p></div>
<div class="section" id="item_5">
<h2>Секция 5</h2><p> Содержимое секции 5</p></div>
<div class="section" id="item_6">
<h2>Секция 6</h2><p> Содержимое секции 6</p></div>
</div></td><td valign="top">
<div id="div1"></div>
</td></tr></table>
</body>
</html>

Самоучитель по jQuery
Самоучитель по jQuery Учебник по jQuery 3.5.1 и AJAX в формате PDF

Помощь сайту

Yandex-деньги: 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

Поиск по сайту в Яндексе