Definindo o Layout

O layout a ser herdado é a definição do tile layout.tabbed, implementado em /layouts/tabbed-layout.jsp.
No momento da definição do seu mestre-detalhe em Tiles-definition.xml, a parte correspondente aos detalhes (abas) este deve estender de layout.tabbed, e ter alguns parâmetros setados, como demonstrado abaixo:

<!-- ############ Nota Fiscal ########### -->
<definition name="notafiscal.detalhe.tabulado" extends="layout.tabbed">
<put name="selectedIcon" value="tabItens"/>
<!-- Para alterar o layout das tabs para vertical -->
<!--put name="verticalTab" value="true"/-->
<putList name="tabList">
<item icon="tabItens" tooltip="notafiscal.items" value="/jsp/notafiscal/detalhe/detalheItens.jsp" link="/notafiscal/detalhe/changeTab.do"/>
<item icon="tabContatos" tooltip="notafiscal.contatos" value="/jsp/notafiscal/detalhe/detalheContatos.jsp" link="/notafiscal/detalhe/changeTab.do"/>
</putList>
</definition>

estes parâmetros definem quais abas o mestre possui e também qual aba é apresentada ativa por default (selectedIcon).
Na tag item, a propriedade icon é uma chave única para cada aba, enquanto tooltip indica a descrição e a propriedade value, descreve a jsp que implementa a referida aba.
Estas descrições (icon) serão apresentadas na área da tela reservada para o conjunto de abas, onde cada descrição é um link para o carregamento da jsp em questão dentro do próprio mestre.
É possível também definir se as abas aparecerão na vertical ou na horizontal através do parâmetro verticalTab. Quando suprimido ou com value=false seu valor é falso e o layout é considerado horizontal.
Depois de definida a parte das abas é necessário adicioná-la ao layout do mestre propriamente dito, indicando que o mestre pode possuir uma parte tabulada.

<definition name="notafiscal.detalhe.mestre" path="/jsp/notafiscal/detalhe/mestre.jsp">
<put name="detail" value="notafiscal.detalhe.tabulado"/>
</definition>

Escrevendo as Jsps

Para implementarmos um mestre-detalhe temos dois tipos de jsp:
  • jsp principal ou mestre que controlará as demais;
  • jsp's que implementam as abas;

Jsp Principal



Neste jsp configuramos os parâmetros necessários ao funcionamento das abas, onde:

<%-- aba selecionada --%>
<html:hidden property="selectedIcon"/>

Onde:
  • selectedIcon é um campo do formulário que contém a aba que está ativa no momento e que deve ser apresentada ativa após qualquer submit.
Vale ressaltar que este valor é armazenado em escopo de request e quando não encontrado é assumido o valor default setado no Tiles-definitions.xml.
Caso a aplicação esteja utilizando o redirect=true no momento do submit, faz-se necessário setar o valor desta variável novamente como um atributo no escopo de request, através da diretiva mostrada abaixo. Isto acontece porque, uma vez setado o redirect, este limpa todo o conteúdo do request e a variável selectedIcon é mantida somente dentro do formulário, não constando mais como um parâmetro de request. Logo, uma vez testado estará vazio, obrigando o engine de abas a considerar o valor default setado em Tiles-definitions.xml.

<c:set var="selectedIcon" scope="request" value="sessionScope.notaFiscalForm.selectedIcon"/>

Além dessas variáveis, é também necessária a importação do tile que contém as abas, no ponto exato em que se deseja que estas apareçam dentro do mestre :

<tiles:insert attribute="detail"/>

Jsp's – Abas



Cada aba possui seus próprios elementos e deve ser implementada em um jsp separado, como uma tela normal sem necessidade de indicarmos nada com relação às abas. Entretanto, devemos considerar ao defini-la:
  • possuirá limitações de layout, uma vez que esta ocupará uma área menor da tela, do que se fosse apresentada fora do mestre;
  • evitar a definição de formulário local a tal aba, uma vez que no momento do submit, somente este será enviado, podendo causar confusão com os dados do formulário pai que não sofrerá envio;
lembramos que os dados das abas já se encontram dentro do formulário do pai, e qualquer ação de submit na aba, irá submeter também os dados do pai que se encontram fora;
  • não deve apresentar tags html padrão como <html: form>, <html; html>, <html:header>, <html:title>, etc.

Configurando o Fluxo

O fluxo da utilização das abas de um mestre-detalhe é definido através do mapeamento de uma ação no arquivo struts-config.xml, como em uma action padrão. Uma FowardAction é definida para executar a troca de abas, como mostrado abaixo:

<action path="/notafiscal/detalhe/changeTab"
type="org.apache.struts.actions.ForwardAction"
scope="session"
name="notafiscalForm"
input="notafiscal.detalhe"
validate="false"
parameter="notafiscal.detalhe">
<!-- flag for indicating that resource security isn't required -->
<set-property property="checkPermission" value="false"/>
</action>

Definindo o Formulário

Lembramos que para o correto funcionamento do mestre detalhe, é necessária a inclusão das seguintes propriedades no momento da definição do formulário no arquivo Struts-config.xml:

<!-- Campo de seleção da aba atual (tile layout.tabbed) -->
<form-property name="selectedIcon" type="java.lang.String"/>

<!-- Objeto Mestre para edição com seus detalhes com escopo de sessão
(para forms complexos e que tenham que manter estado) -->
<form-property name="notafiscal" type="gov.tjpr.inteface.entity.NotaFiscal"/>

<!-- Objeto de paginação para formulário com escopo de sessão (para forms complexos e que tenham que manter estado) para este caso os parâmetros devem ser definidos na tag de paginação "pager" como campoObjetoPágina.pageNumber, .size, ... <form-property name="detalhe" type="gov.tjpr.entity.pagination.Page"/>-->

<!-- Campos da paginação por formulário para os itens -->
<form-property name="itemPageSize" type="java.lang.String" initial="10"/>
<form-property name="itemPageNumber" type="java.lang.String" initial="1"/>
<form-property name="itemSortColumn" type="java.lang.String"/>
<form-property name="itemSortOrder" type="java.lang.String"/>

<!-- Campos da paginação por formulário para os contatos -->
<form-property name="contatoPageSize" type="java.lang.String"/>
<form-property name="contatoPageNumber" type="java.lang.String" initial="1"/>
<form-property name="contatoSortColumn" type="java.lang.String"/>
<form-property name="contatoSortOrder" type="java.lang.String"/>