08 maio 2007

Wicket: AJAXiando a Paginação

No penúltimo post, mostrei como implementar paginação de listas com o framework Wicket. Agora, visando maior produtividade e usabilidade na interface, apresento-lhes o que é preciso para implementar a mesma paginação ajaxiada.

O processo é o mesmo, já que o framework é component-based. As alterações no HTML são mínimas e mesmo em Java, o que será preciso modificar é qual componente instanciar para tratar a ListView. Mas por se tratar de uma implementação Ajax, algumas considerações e explicações devem ser feitas antes.
  • Ao implementar algo em Ajax, as vezes é preciso de uma área (div) para ser atualizada pelas requisições assíncronas com novo código HTML produzido dinâmicamente no servidor.
  • No caso da ListView, é importante que a tabela fique dentro de uma área como esta.
  • Em Wicket, é possível referenciar uma área qualquer div através do componente WebMarkupContainer.
Uma das enormes vantagens de utilizar o framework Wicket, é poder desenvolver diversas funcionalidades sem escrever uma linha de Javascript qualquer. Seu suporte a Ajax está muito estável para funcionalidades básicas, e ainda existe o projeto Wicket Extensions que provê muitos outros componentes 100% plugáveis a qualquer aplicação Wicket. Cada componente expõe no HTML de alguma forma, o Javascript necessário para que o mesmo funcione, como os de Ajax por exemplo. Em outro post, mostrarei como implementar componentes reutilizáveis (e aí sim, teremos que escrever Javascript se for o caso).

Seguindo o assunto do post, vamos ao que interessa: ajaxiar uma paginação. Abaixo, está o código da tela utilizada na explicação anterior:

Pessoas.html
<table>
<tr>
<td>nome</td>
<td>idade</td>
</tr>
<tr wicket:id="lista">
<td><span wicket:id="nome">foo</span></td>
<td><span wicket:id="idade">12</span></td>
</tr>
<tr>
<td colspan="2">
<span wicket:id="navegacao">Aqui vai a barra de navegacao</span>
</td>
</tr>
</table>

A única alteração que devemos fazer, é colocar esta tabela dentro de uma área atualizável por requisição Ajax: um div. Ou seja, ficará assim:

<div wicket:id="ajaxTable">
<table>
<tr>
...
</tr>
</table>
</div>


Feito isto, é preciso que o componente ajaxTable seja reconhecido pelo Wicket na classe Pessoas. E é agora que utilizaremos a classe WebMarkupContainer:

Pessoas.java
public class Pessoas extends WebPage {
public Pessoas() {
List listaPessoas; /* obtem de algum lugar (Spring talvez) */
PageableListView view = new PageableListView("lista", listaPessoas) {
protected void populateItem(ListItem item) {
Pessoa p = (Pessoa) item.getModelObject();
item.add(new Label("nome", p.getNome());
item.add(new Label("idade", p.getIdade());
}
};

WebMarkupContainer ajaxTable = new WebMarkupContainer("ajaxTable");
ajaxTable.setOutputMarkupId(true); // obrigatorio pq nao tem o
// atributo id com mesmo
// nome no html
add(ajaxTable);

// O componente PageableListView está dentro do

// entao deve ser adicionado ao WebMarkupContainer, não à página.
ajaxTable.add(view);

// O componente-chave para paginação-ajax, está aqui:
ajaxTable.add(new AjaxPagingNavigator("navegacao", view));
}
}
Pronto! Paginação ajax habilitada com sucesso! :)
Desta forma, ao navegar na lista somente a tabela com os dados será atualizada, através de requisições Ajax. Esta funcionalidade é muito útil quando se tem telas pesadas com diversos componentes, e não queremos atualizar a página inteira, ou quando simplesmente queremos dizer que a aplicação é Web 2.0 compliant.

Explicando um pouco o que foi feito:
  • Não foi preciso alterar qualquer trecho de código na table html, mas é necessário que a mesma esteja numa área atualizável div.
  • Não existe um AjaxPageableListView. O mesmo que utilizamos no primeiro exemplo foi utilizado aqui.
  • Como existe um div para ser atualizado assíncronamente, este precisa ser referenciado por um WebMarkupContainer, que conterá o novo código HTML após a requisição Ajax e substituirá o código anterior.
  • Qualquer componente que esteja dentro do div, deve ser adicionado no MarkupContainer, respeitando a árvore de componentes.
  • Configurei a propriedade
    outputMarkupId
    porque no HTML, nao coloquei o atributo id manualmente. Este método faz apenas isto. Utiliza o nome do componente para o atributo id.
  • Tanto a ListView como o Navigator, são adicionados no MarkupContainer.
  • Para a paginação efetivamente funcionar, deve-se utilizar o componente
    AjaxPagingNavigator
  • Pronto!
Até a próxima!

2 comentários:

Paulo Silveira disse...

Apesar de ter uma abordagem orietada a componentes, em vez de action based, prefiro muito mais o estilo do wicket e do tapestry que o inferno do JSF :).

parabens pelo post

Anônimo disse...

Como utilizar este exemplo ???

Contato

Email:bruno.borges(at)gmail.com

LinkedIn: www.linkedin.com/in/brunocborges
Twitter: www.twitter.com/brunoborges
Comprei e Não Vou
Rio de Janeiro, RJ Brasil
Oracle
São Paulo, SP Brasil