670
 

Постраничная навигация на 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>');

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

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

Добавить в закладки:
Maklay.com - Большой каталог товаров для спорта и активного отдыха

Комментарии на “Постраничная навигация на 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. @Слава
    Согласен, ссылки должны смещаться, а то если вывести все на одной странице, будет ужасно некрасиво. Но увы, этой возможности пока нет.

  12. а не мог бы кто-то выложить оригинальные демки “решения”?
    ссылка, что вначале статьи, уже померла((

    меня в первую очередь интересуют PHP скрипты серверной части.

  13. @Vetal
    Я использовал исходные PHP скрипты без изменения. Выложил здесь:
    http://www.jstoolbox.com/demo/jquery-pagination/server.txt
    http://www.jstoolbox.com/demo/jquery-pagination/posts.txt

  14. @admin
    Спасибо большое!

  15. никак не могу сообразить как реализовать подгрузку данных из бд, неподскажите хороший форум по ajax?

  16. Николай 1 июня 2009 в 15:42

    Подскажите, пожалуйста, возможно ли использовать такую пагинацию на обычном html-сайте. Проблема – есть два десятка html-страничек по общему шаблону но с разным содержанием – возможно ли создать такую пагинацию для навигации между этими страницами? или все же нужно использовать php?
    Заранее благодарен!!!

  17. Думаю, этот скрипт для такой цели не подойдет. Он сделан именно под табличные данные и к тому же, здесь URL устанавливается при инициализации, а затем к нему добавляется параметр – номер страницы, вам же нужно, чтобы каждый раз URL менялся на новый.

  18. Николай 1 июня 2009 в 21:34

    Скажите, это как-то можно реализовать или есть готовые java скрипты?

  19. Увы, готовых не могу посоветовать.

  20. Все работает замечательно. Но почему-то не выводится русский текст((. Может кто подскажет как лечить?

  21. А у меня данные таблицы получаются из бд…а в некоторых столбцах вообще используются ссылки, кнопки и другие объекты….
    Можно ли как-то переделать функцию для прорисовки строк таблицы, чтобы она получала данные не в формате json а в виде html со значениями взятыми и бд…

  22. @Inga
    Это можно, но скрипт собственно заточен под JSON.

  23. Выложи плз архивом эту работу, пожалуйста. Мне очень надо.

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

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