Добрый день! Недавно писал пагинацию для Backbone.js, вот хотел бы поделиться с Вами, может кому-то пригодится.
Пускай нам надо сделать пагинацию вида:
1… 3 4 5 6 7… 12
Для реализации понадобится вид PaginationView и шаблон pagination-view.
Вид — PaginationView
window.PaginationView = Backbone.View.extend({
template: _.template($("#pagination-view").html()), // шаблон
link: "", // ссылка
page_count: null, // кол-во страниц
page_active: null, // активная страница
page_show: 5, // кол-во страниц в блоке видимости
attributes: { // атрибуты элемента
"class": "pagination"
},
initialize: function(params) { // конструктор
this.link = params.link;
this.page_count = params.page_count;
if (this.page_count <= this.page_show) {
this.page_show = this.page_count;
}
this.page_active = params.page_active;
},
render: function(eventName) { // выдача
...
}
});
Имеем такое описание вида. В конструкторе принимаем параметры, params — объект параметров.
Теперь рассмотрим логику выдачи. Для выдачи пагинации, а точнее блока, видимых страниц, нам надо найти индекс начала и конца этих страниц. Ищем кол-во элементов до активного и после. То есть делим пополам.
var range = Math.floor(this.page_show / 2);
var nav_begin = this.page_active - range;
var nav_end = this.page_active + range;
Дальше нам нужно узнать или надо нам выдавать "..." с каждой из сторон. Заводим две переменные, которые покажут, нужны ли:
var left_dots = true;
var right_dots = true;
И так, когда нам нужны "...", когда начало больше 2 (слева) и когда меньше конца — 1 (справа). Для этого пишем две проверки, в которых разберем еще один частный случай. Он состоит в том, что если у нас активный второй, то блок выдачи имеет на один больше элемент.
1 2 3 4 5 6… 12
И так же в конце.
1… 7 8 9 10 11 12
if (nav_begin <= 2) {
nav_end = this.page_show;
if (nav_begin == 2) {
nav_end++;
}
nav_begin = 1;
left_dots = false;
}
if (nav_end >= this.page_count - 1 ) {
nav_begin = this.page_count - this.page_show + 1;
if (nav_end == this.page_count - 1) {
nav_begin--;
}
nav_end = this.page_count;
right_dots = false;
}
И в конце концов отправляем шаблону:
$(this.el).html( this.template({
link: this.link,
page_count: this.page_count,
page_active: this.page_active,
nav_begin: nav_begin,
nav_end: nav_end,
left_dots: left_dots,
right_dots: right_dots
}) );
Шаблон pagination-view
Шаблон написан с использованием Twitter Bootstrap. Тривиальная выдача.
<ul>
<% if (page_active > 1) { %>
<li><a href="<%= link %><%= page_active-1 %>">«</a></li>
<% } %>
<% if (left_dots == true) {%>
<li><a href="<%= link %>1">1</a></li>
<li class="disabled"><a href="#">...</a></li>
<% } %>
<% for (var i = nav_begin; i <= nav_end; i++) { %>
<li <% if (page_active == i) print('class="active"') %> ><a href="<%= link %><%= i %>"><%= i %></a></li>
<% } %>
<% if (right_dots == true) {%>
<li class="disabled"><a href="#">...</a></li>
<li><a href="<%= link %><%= page_count %>"><%= page_count %></a></li>
<% } %>
<% if (page_active < page_count) { %>
<li><a href="<%= link %><%= page_active+1 %>">»</a></li>
<% } %>
</ul>
P.S. Все очень просто, берите и пользуйтесь :).
P.S.S. Если кол-во страниц блока парное число, то переменную range нужно искать по-другому, но в пагинациях используют зачастую непарное число.
Автор: ozzycv