Strufts

Não sabemos o que é, mas nós temos.

Paginação (0)

Sábado, Fevereiro 13 por , em ,

Finalmente saí do zero com a tal paginação de resultados no projeto final da pós. Apesar de ter tentado o digg_pagination, endless_pagination e mais algumas soluções prontas, devido à dificuldade de integrar (será que é tão difícil escrever uma boa documentação das coisas que fazemos? Até mesmo o JQuery UI e o YUI pecam nisso nas páginas oficiais.) resolvi criar minha própria função para paginar a queryset.

Muito provável que tenha bugs, porque não foi testada exaustivamente, mas por enquanto está servindo.

utils.py


#--------------------------------------------------
# Constantes da paginação.
#--------------------------------------------------
PER_PAGE = 5
PAGE_RANGE = 10
NUM_PAGES_OUTSIDE_RANGE = 2
LEADING_PAGE_RANGE = 5



views.py


#coding:utf-8

from django.template.loader import render_to_string

from django.core.paginator import QuerySetPaginator

from models import *

from utils import *



def monta_paginacao(pagina, paginado):
'''
Monta a navegação entre a páginas como no site Digg.com
'''


# Se a página especificada ultrapassar o limite, redefine para a última
if pagina >= paginado.paginator.num_pages:
pagina = paginado.paginator.num_pages


if paginado.paginator.num_pages > PAGE_RANGE :
paginas_finais = range(paginado.paginator.num_pages - NUM_PAGES_OUTSIDE_RANGE + 1, paginado.paginator.num_pages + 1)


if pagina <= PAGE_RANGE - NUM_PAGES_OUTSIDE_RANGE:
paginas_visiveis = range(1, PAGE_RANGE + 1)
paginas_iniciais = ''

else:

paginas_visiveis = range(pagina - LEADING_PAGE_RANGE, (pagina + LEADING_PAGE_RANGE) % paginado.paginator.num_pages)
paginas_iniciais = range(1, NUM_PAGES_OUTSIDE_RANGE + 1)

mod_inicial = (1 + LEADING_PAGE_RANGE) % paginado.paginator.num_pages
mod_atual = (pagina + LEADING_PAGE_RANGE) % paginado.paginator.num_pages

if( mod_atual < mod_inicial or mod_atual == paginado.paginator.num_pages - 1):
paginas_finais = ''
paginas_visiveis = range(paginado.paginator.num_pages - mod_inicial, paginado.paginator.num_pages + 1)

else:
if (paginado.paginator.num_pages > 1):
paginas_visiveis = range(1, paginado.paginator.num_pages + 1)
else:
paginas_visiveis = ''
paginas_iniciais = paginas_finais = ''

return pagina, paginas_visiveis, paginas_iniciais, paginas_finais



def listagem_principal(request, ordenacao = 'envio', pagina = 1):

resultado = Arquivo.objects.order_by(ordenacao)

if ordenacao == 'envio' or ordenacao == 'downloads':
resultado = resultado.reverse()

try:
pagina = int(pagina)
except:
pagina = 1

paginado = QuerySetPaginator(resultado, PER_PAGE).page(pagina)

atual, paginas_visiveis, paginas_iniciais, paginas_finais = monta_paginacao(pagina, paginado)


contexto = {
'resultados': paginado,
'ordenacao': ordenacao,
'sequencia_visiveis': paginas_visiveis,
'paginas_iniciais': paginas_iniciais,
'paginas_finais': paginas_finais,
'atual': atual
}

template = render_to_string('listagem.html', contexto)

return HttpResponse(template)




O template da paginação foi criado em um arquivo separado para ser incluido no template da listagem, que utiliza JQuery para remover os estilos de acordo com certas condições.

paginacao.html


<div class="paginacao">
<ul id="pagination-flickr">


<li id="1st"><a href="javascript:listagem('{{ ordenacao }}', 1);">Primeira</a></li>
<li id="pxpag"><a href="javascript:listagem('{{ ordenacao }}', {{ atual|add:1 }});">Pr&oacute;xima &gt; &gt;</a></li>


{% for pagina in paginas_iniciais %}
<li><a href="javascript:listagem('{{ ordenacao }}', {{ pagina }});" >{{ pagina }}</a></li>
{% endfor %}

{% if paginas_iniciais %}
<li>...</li>
{% endif %}


{% for pagina in sequencia_visiveis %}

{% ifnotequal pagina atual %}
<li><a href="javascript:listagem('{{ ordenacao }}', {{ pagina }});" >{{ pagina }}</a></li>
{% else %}
<li class="active">{{ pagina }}</li>
{% endifnotequal %}

{% endfor %}

{% if paginas_finais %}
<li>...</li>
{% endif %}

{% for pagina in paginas_finais %}
<li><a href="javascript:listagem('{{ ordenacao }}', {{ pagina }});">{{ pagina }}</a></li>
{% endfor %}

<li id="antpag"><a href="javascript:listagem('{{ ordenacao }}', {{ atual|add:-1 }});">&lt; &lt; Anterior</a></li>
<li id="nth"><a href="javascript:listagem('{{ ordenacao }}', {{ resultados.paginator.num_pages }});">&Uacute;ltima</a></li>

</ul>
</div>



listagem.html


<script type="text/javascript">

function listagem(chave, pagina) {
$.post('/principal/listagem/' + chave + '/' + pagina + '/', {}, function(resposta) {
if(chave == 'envio')
$("#ui-tabs-8").html(resposta);
else if (chave == 'nome')
$("#ui-tabs-13").html(resposta);
else if (chave == 'downloads')
$("#ui-tabs-15").html(resposta);
});
}


function aplicarEstilos() {
var elemento = '';
var link = '';
var texto = '';

if ( {{ atual }} == '1' ) {
elemento = $("#1st");
link = elemento.find('a');
texto = elemento.text();

link.remove();
elemento.text(texto);
elemento.addClass('previous-off');

elemento = $("#antpag");
link = elemento.find('a');
texto = elemento.text();

link.remove();
elemento.text(texto);
elemento.addClass('previous-off');
} else if ( {{ atual }} == {{ resultados.paginator.num_pages }} ) {
elemento = $("#pxpag");
link = elemento.find('a');
texto = elemento.text();

link.remove();
elemento.text(texto);
elemento.addClass('next-off');

elemento = $("#nth");
link = elemento.find('a');
texto = elemento.text();

link.remove();
elemento.text(texto);
elemento.addClass('next-off');
}

}

$(document).ready(function() {

$('.link_pagina').click(function () {
var pagina_destino = $(this).attr('pag');
var chave = $(this).attr('chave');

listagem(chave, pagina_destino);
});

aplicarEstilos();
});
</script>

<!-- PAGINAÇÂO DOS RESULTADOS -->
{% include "paginacao.html" %}


<table border="0" cellspacing="30" id="listagem_principal">

{% for arquivo in resultados.object_list %}
<tr>
<td class="celula_listagem">
<table width="100%">
<tr>
<td valign="top" width="50%">
<p><strong>Nome:</strong> {{ arquivo.nome }}</p>
<p><strong>Tipo:</strong> {{ arquivo.tipo.tipo }}</p>
<p><strong>Autor:</strong> {{ arquivo.usuario.username }}</p>
<p><strong>Data:</strong> {{ arquivo.envio }}</p>
</td>
<td valign="top" width="50%">
<p><strong>Descri&ccedil;&atilde;o:</strong> {{ arquivo.descricao }}</p>
</td>
</tr>
</table>
</td>
</tr>
{% endfor %}

</table>


<!-- PAGINAÇÂO DOS RESULTADOS -->
{% include "paginacao.html" %}



O css utilizado foi o do Flickr, encontrado nesse site: http://woork.blogspot.com/2008/03/perfect-pagination-style-using-css.html



| edit post