quinta-feira, 21 de março de 2013

Layout Ajax com JSF

Esta informação está contida em outros blogs mas decidi escrevê-la aqui também porque sempre achei informações incompletas, sendo um pouco num blog e outro pouco noutro.

A ideia é criar um layout de website com área de cabeçalho, menu à esquerda e centro com conteúdo. Até aí é fácil e o Netbeans dá uma mão para a gente (na versão 7.3, crie um facelet e você verá). Neste layout, a intenção é permitir que o usuário clique no menu posicionado à esquerda e o conteúdo da página (no centro) seja atualizado sem que toda a página seja recarregada.

Primeiro, é necessário criar um controlador (bean) para manter a página corrente a ser carregada. Veja, no código abaixo, a declaração bem simples do IndexController;  perceba que o atributo currentPage é inicializado com o nome da página com o conteúdo inicial do site.

@ManagedBean
public class IndexController {

    private String currentPage = "home.xhtml"; // página com conteúdo inicial

    public String getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(String currentPage) {
        this.currentPage = currentPage;
    }
}

Supondo que a página inicial seja index.xhtml, com o layout do site devidamente estruturado (junto com CSS), insira o código abaixo na área reservada para a descrição do menu. Aqui, o menu está bastante simples e é basicamente composto por dois links onde cada um deve abrir as páginas inserir.xhtml e listar.xhtml.

<h:form>
   <f:ajax render=":contentForm:reload">
      <h:commandlink action="#{indexController.setCurrentPage('inserir.xhtml')}" value="Inserir"/>
      <h:commandlink action="#{indexController.setCurrentPage('listar.xhtml')}" value="Listar"/>
   </f:ajax>
</h:form>

Ainda no mesmo arquivo index.xhtml, agora na área reservada para o conteúdo do website propriamente dito, insira o código abaixo.

<h:form id="contentForm">
    <h:panelGroup id="reload">
        <ui:include src="#{indexController.currentPage}"/>
    </h:panelGroup>
</h:form> 

Os códigos demonstrados acima fazem referência à 3 arquivos: home.xhtml, inserir.xhtml e listar.xhtml. Estes arquivos precisam ser criados com o conteúdo específico. Abaixo está o exemplo de como tais arquivos devem ser criados:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets">
    <ui:composition>
         Coloque aqui o conteúdo a ser exibido no website! 
    </ui:composition>
</html>

Com esta abordagem, a URL do website não modifca toda vez que o usuário clica no menu!

Agora suponha que o conteúdo exibido no website tenha um botão ou um link que leve à outra página. Naturalmente a ideia aqui é atualizar comente a área de conteúdo. O código abaixo mostra um exemplo de como seria isto:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <ui:composition>
        <f:ajax render=":contentForm:reload">
            <h:commandLink value="Atualizar" action="#{indexController.setCurrentPage('/ui/alterar.xhtml')}"/>               
        </f:ajax>
    </ui:composition>
</html>

Veja que no código acima não está declarado a tag <h:form> para permitir a declaração do <h:commandLink>. Aqui, o form com o identificador 'contentForm' já fora delcarado em index.html e recebe toda a atualização da página e por isso não precisa ser declarado novamente.

Referências: