346
 

Постраничная навигация на jQuery

В последнее время мне пришлось столкнуться с проблемой постраничной навигации (pagination), и, дабы не изобретать велосипед, я сразу же решил поискать готовые решения. Как оказалось, их не так уж и много. В конце концов, я остановил свой выбор на приемлемом для меня решении, о котором и пойдет речь в этой статье. Сие решение представляет собой скрипт, использующий jQuery и способный обеспечивать быструю и простую навигацию используя AJAX. Я несколько изменил исходный скрипт, чтобы получить таблицу с одинаковым количеством строк (в исходном варианте таблица всегда имела размер в зависимости от количества получаемых данных), плюс я добавил эффекты затухания при прорисовке.

Пагинатор на jQuery

Чтобы получить представление о конечном результате этого туториала, предлагаю вам взглянуть на демо.

Создание постраничной навигации начнем собственно с таблицы, которую мы будем заполнять данными:

<table id="list" width="100%" cellspacing="0">
	<caption>Таблица 1: Некоторые произвольные данные</caption>
	<thead>
		<tr>
			<th scope="col">Название</th>
			<th scope="col">Автор</th>
			<th scope="col">Дата</th>
			<th scope="col">ID</th>
		</tr>
	</thead>
	<tbody>
	<tr><td scope="row" class="spec"><span></span></td><td><span></span></td><td><span></span></td><td><span></span></td></tr>
	<!-- еще девять таких же строк -->
	</tbody>
	<tfoot>
		<tr>
			<td colspan="4">
				<ul class="paginator"></ul>
			</td>
		</tr>
	</tfoot>
</table>

Как видите, это самая обыкновенная пустая таблица, внутри каждой ячейки которой находится элемент <span>. Сразу же после загрузки страницы, эта таблица будет заполняться данными получаемыми из AJAX запроса. Пустой контейнер ul с классом paginator будет использоваться для хранения ссылок навигации. Эти ссылки будут обновляться после каждого обновления таблицы.

Далее подключаем скрипт пагинатора:

jQuery.fn.pageinate = function (settings) {

	// Настройки по умолчанию
	var settings = jQuery.extend({
		row: function (container, item, i) {},
		page: function (i) {},
		url: "",
		show: 10,
		start_page:1
	}, settings);

	// элемент, который будет использоваться для пагинатора
	settings.pagelist_selector = jQuery(settings.pagelist_selector);

	return this.each(function(_, element){
		// jQuery-wrap element
		element = $(element);

		var page_link_callback_creator = function(i) {
			return function() {
				$(this).html(' ');
				$(this).attr('class','waiting');
				update(i);
			}
		};

		var update = function (page) {

			jQuery.getJSON(settings.url, {page:page, show:settings.show}, function(data){
				// Обрабатываем результаты JSON запроса
				pages = data['pages'];
				posts = data['posts'];

				// прорисовка строк таблицы
				for (var i=0; i < settings.show; i++) {
					if (posts[i])
						settings.row(element, posts[i], i);
					else
						settings.row(element, false, i);
				}

				settings.pagelist_selector.fadeOut(100, function(){
					settings.pagelist_selector.html("");
					// создание пагинатора
					for (i=1; i <= pages; i++) {
						selected = page==i
						page_link = settings.page(i, selected);
						settings.pagelist_selector.append(page_link);

						if(!selected) {
							page_link.click(page_link_callback_creator(i));
						}
					}
					settings.pagelist_selector.fadeIn(100);
				});
			});
		};

		// Первоначальное получение данных
		update(settings.start_page);
	});
}

Код пагинатора реализован в виде jQuery плагина. В самом начале определяются настройки пагинатора - количество строк на странице (show), с какой страницы начинать просмотр (start_page), url для AJAX запросов (url). Однако основными параметрами в этих опциях являются обработчики row и page, которые нужны для прорисовки строк таблицы и пагинатора.

Плагин работает следующим образом: в самом последней строке плагина вызывается функция update(), которая выполняет AJAX запрос к серверу (адрес указан в опции url). Полученные от сервера данные в формате JSON обрабатываются и добавляются в таблицу:

// прорисовка строк таблицы
for (var i=0; i < settings.show; i++) {
	if (posts[i])
		settings.row(element, posts[i], i);
	else
		settings.row(element, false, i);
}

После этого происходит прорисовка пагинатора, используя эффекты затухания (fadeOut и fadeIn).

Теперь рассмотрим скрипт в котором мы будем использвать созданный нами плагин:

$(document).ready(function(){

	$("#list tbody").pageinate({
		url: "server.php",
		pagelist_selector: "#list ul",
		start_page: 1,

		row:function(container, item, i){
			$("#list tbody tr:eq("+i+") td").each(function(i){
				if (!item)
					$(this).html('<span> </span>');
				else {
					switch (i){
						case 0:
							$(this).html('<span>'+item['title']+'</span>');
							break;
						case 1:
							$(this).html('<span>'+item['author']+'</span>');
							break;
						case 2:
							$(this).html('<span>'+item['date']+'</span>');
							break;
						case 3:
							$(this).html('<span>'+item['id']+'</span>');
							break;
					}
				}
			});
		},

		page:function(id, selected) {
			return $('<li class="'+(selected?"selected":"")+'">'+id+'</li>');
		}
	});

});

Вызывается он обычным для jQuery образом, указывая все перечисленные выше опции - url, pagelist_selector и т.п.:

$("#list tbody").pageinate({});

В качестве обработчиков row() и page() указываем функции, рисующие строку и пагинатор. Как видите, функции несложные, в особенности page(), где просто создается новый элемент li с номером страницы. Если страница текущая, то для созданного элемента указывается класс selected. Обработчик row() несколько сложнее - он целиком и полностью зависит от получаемых от сервера данных. В самом начале функция получает указатели на все ячейки строки (аргумент i указывает на строку таблицы), в которую нужно поместить значение:

$("#list tbody tr:eq("+i+") td").each(function(i){})

Затем, используя функцию each() поочередно добавляем нужные нам данные в соответствующие ячейки используя конструкцию switch. Если в функцию передан пустой аргумент item (пустая ячейка), то в содержимое ячейки очищается (визуально - span там нужен, чтобы пустая ячейка имела те же размеры что и заполненая):

if (!item)
	$(this).html('<span> </span>');

Конечно же, это не полнофункциональный пагинатор, как мы его привыкли видеть в обычных приложениях, но я думаю недостающие функции, как ссылки “Вперед” и “Назад”, несложно написать самостоятельно.

На сегодня это все.
До встречи!

Добавить в закладки:

Комментарии на “Постраничная навигация на jQuery”

  1. Жаль, что содержимое поисковиками никак не проиндексируется((

  2. Да, точно, это минус

  3. Думаю в скором времени будет индексироваться и AJAX ;)

  4. @Vovan
    Да скорей бы :)

  5. Если не ошибаюсь, то tfoot должен находиться до tbody, а не после как у вас в примере (по крайней мере в xhtml).

  6. @Vii
    Нет, а мне кажется что футер должен быть в самом низу, перед закрывающим </table>

  7. 2 admin:
    Понимаю, что статья не об этом, но всё же:

    “TFOOT must appear before TBODY within a TABLE definition so that user agents can render the foot before receiving all of the (potentially numerous) rows of data.” (http://www.w3.org/TR/html401/struct/tables.html#h-11.2.3)

  8. @Vii
    Ну значит, признаю свою ошибку :)

  9. Vii: Если не ошибаюсь, то tfoot должен находиться до tbody, а не после как у вас в примере (по крайней мере в xhtml).
    «tfoot» располагают в самом низу, чтобы выделение текста было правильным, иначе, если сделать правильно — расположить «tfoot», после «thead», то выделение будет происходить в таком же порядке. Тут уже надо выбирать, что важнее: юзабилити или валидность :-)

  10. а как насчёт если данных будет большое кол-во к примеру 5 тыс. записей, то как будет выглядеть постраничник, ведь не будеш все ссылки на страницы выводить на одной странице, они как то я понимаю должны смещаться при нахождении на определённой страницы

  11. @Слава
    Согласен, ссылки должны смещаться, а то если вывести все на одной странице, будет ужасно некрасиво. Но увы, этой возможности пока нет.

Оставить комментарий

JSToolbox создан на основе WordPress