Для решения задачи сортировки уже давно применяют JavaScript, вместо того, чтобы заново генерировать код перезагружая страницу.
Задача состоит в том, чтобы сортировать блоки в алфавитном порядке, либо по числам, в обоих направлениях — по убыванию и возрастанию. При этом необходимо, чтобы код корректно работал во всех браузерах, включая Internet Explorer и Safari. Предполагается, что будет использоваться не чистый JavaScript, а именно сортировка jQuery.
HTML — скелет таблицы
Для реализации примера взяты элементы таблицы Менделеева, где есть буквенное обозначение элемента и его порядковый номер.
Сортируемая таблица строится с помощью блочной верстки.
<div class="order">
<div class="header row">
<div class="col-md-6" data-orderby="element">Element</div>
<div class="col-md-6" data-orderby="number">Number</div>
</div>
<div class="list">
<div class="row">
<div class="col-md-6"><span data-name="element">Be</span></div>
<div class="col-md-6"><span data-name="number">4</span></div>
</div>
<div class="row">
<div class="col-md-6"><span data-name="element">Ag</span></div>
<div class="col-md-6"><span data-name="number">47</span></div>
</div>
<div class="row">
<div class="col-md-6"><span data-name="element">C</span></div>
<div class="col-md-6"><span data-name="number">6</span></div>
</div>
</div>
</div>
Элемент с классом header будет являться заголовком таблицы, в которой будут располагаться элементы управления сортировкой. Элементы управления определяются наличием атрибута data-orderby. В данном случае в качестве элемента управления указан блок всей ячейки, для того, чтобы сортировка происходила при щелчке на всем блоке, а не только на слове.
Далее идет блок с классом list, что дает возможность определить контейнер, в котором будут сортироваться блоки. Блоки, которые будут в последствии сортироваться имеют класс row.
Текст, по которому будет определяться порядок сортировки определяется наличием атрибута data-name, и значение этого атрибута должно совпадать со значением управляющего элемента. То есть при щелчке на элементе [data-orderby=element] должна производиться сортировка по элементам [data-name=element].
CSS — определение внешнего вида таблицы и элементов сортировки
Чтобы визуально таблица выглядела хорошо, перед тем, как будет осуществлена сортировка jQuery, следует написать следующий CSS код, при условии, что не используется Bootstrap:
.row {
width: 100%;
}
.row:begin, .row:after {
content: " ";
display: block;
clear: both;
width: 100%;
}
.row > div {
float: left;
border-bottom: 1px solid #ccc;
}
.col-md-6 {
width: 50%;
}
Следующие свойства определяют внешний вид стрелочек, указывающих на то, что пользователь может осуществлять сортировку по данному столбцу:
.header > div {
position: relative;
background: #eee;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.header > div:after {
position: absolute;
content: "";
display: inline-block;
border: 5px solid transparent;
border-top-color: #000;
width: 0;
height: 0;
top: 100%;
right: 25px;
margin-top: -10px;
}
.header > div.up:after {
border-top-color: transparent;
border-bottom-color: #000;
margin-top: -15px;
}
JavaScript — функционал, сортировка jQuery
Для корректной работы в IE необходимо правильно создать массив, так как довольно часто при создании массива другим способом данный массив не работает в IE. Поэтому мы применяем способ new Array().
Необходимо создать глобальную переменную orderdirection, которая будет являться массивом и будет хранить текущее направление сортировки для каждого столбца.
var orderdirection = new Array();
Для вызова функции сортировки jQuery необходимо создать обработчик события, например щелчка мыши по управляющему элементу. В обработчике следует вызвать функцию, которая будет иметь входные данные: ключ сортировки, контейнер блоков, блок, флаг, указывающий на то, что данные следует сортировать как числа.
$('[data-orderby]').on('click', function () {
var orderby = $(this).data( 'orderby' ); // создана локальная переменная, содержащая имя признака сортировки
switch ( orderby ) // условие, определяющее - нужно ли считать данные сортировки числом
{
case 'number': flag = 1; break; // данные с признаком number надо сортировать как числа
default: flag = 0; // по умолчанию сортировка будет по алфавиту
}
oi_div_order( orderby, '.list', '.row', flag );
});
Если сортировать числа в алфавитном порядке, то последовательность числе 6,47,4 будет отсортирована как 4, 47, 6, а не как 4, 6, 47.
Чтобы указать на то, что данные следует сортировать как числа, нужно эти данные сделать не строковыми, а числовыми. Для этого используется функция parseFloat, которая преобразует строку в число с плавающей точкой, так как вероятно, что сортировке будут подвергаться не только целые числа.
function is_num( text, flag )
{
if( flag == 0 )
{
return text;
}else
{
return parseFloat( text );
}
}
Теперь для осуществления сортировки необходимо написать функцию самой сортировки. Для обеспечения корректной работы в браузере Safari необходимо правильно написать условие перестановки, с указанием возвращаемого числа: 1, -1, 0.
function oi_div_order( selector, container, block, flag )
{
block = container + ' ' + block; // формирование селектора блока, содержащего селектор контейнера
// создается локальная переменная, хранящая нумерованный список объектов - блоков, осуществляется сортировка
var ordered_dives = $( block ).sort(function (a, b)
{
a = $(a).find( '[data-name=' + selector + ']' ).text(); // текст из 1-го элемента, по которому сортируем
b = $(b).find( '[data-name=' + selector + ']' ).text(); // текст из 1-го элемента, по которому сортируем
// если направление сортировки не определено или равно 0, производится соответствующая перестановка элементов
if( orderdirection[ selector ] == undefined || orderdirection[ selector ] == 0 )
{
return ( is_num( a, flag ) > is_num( b, flag ) ) ? 1 : ( is_num( a, flag ) < is_num( b, flag ) ) ? -1 : 0;
}else{
return ( is_num( a, flag ) < is_num( b, flag ) ) ? 1 : ( is_num( a, flag ) > is_num( b, flag ) ) ? -1 : 0;
}
});
// выводится массив отсортированных элементов в контейнер
$( container ).html( ordered_dives );
// если направление сортировки не определено или равно 0
if( orderdirection[ selector ] == undefined || orderdirection[ selector ] == 0 )
{
orderdirection[ selector ] = 1; // указывается текущее направление сортировки
$( '[data-orderby=' + selector + ']' ).addClass( 'up' ); // добавляется название класса
}else{
orderdirection[ selector ] = 0; // указывается текущее направление сортировки
$( '[data-orderby=' + selector + ']' ).removeClass( 'up' ); // удаляется название класса
}
}
(
(