Для решения задачи сортировки уже давно применяют 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' ); // удаляется название класса } }