Início > Programação > Como Esconder e Reexibir Componentes JSF em Runtime sem Causar Problemas de Renderização

Como Esconder e Reexibir Componentes JSF em Runtime sem Causar Problemas de Renderização

Precisava criar um formulário dinâmico cuja exibição de um componente depedendia do estado de um managed bean e a mudança desse estado assim como a re-renderização forçada daquele componente seria feita via ajax à partir de um commandLink do Primefaces. Ao utilizar o atributo “rendered” setado para “false” em componentes do Primefaces vi um dos efeitos colaterais indesejáveis dos componentes ricos: eles param de funcionar ou apresentam comportamento incorreto.

A análise feita aqui afirma que o problema deve-se a tentativa de renderização de um componente que não estava presente na página naquele momento, pois como o atributo “rendered” era “false”, ele não foi integrado ao HTML gerado. Sendo assim, quando uma requisição ajax é recebida no lado cliente, a engine do ajax não é capaz de fazer o refresh, pois o componente não é encontrado.

A solução proposta pelo desenvolvedor que fez essa análise é colocar um componente panelGroup um nível acima do componente que deve ser exibido ou não. A execução do ajax incidirá sobre um componente que sempre estará integrado ao HTML e forçará aquele meu outro componente a atualizar seu estado interno consultando o managed bean.

Essa solução funciona para uma implementação mais simples do JSF, como o Mojarra, mas não funciona para componentes do Primefaces. Esses componentes mais ricos têm muito JavaScript agregado e um ciclo de renderização bem complexo. Além disso, eles têm potencial para maximizar o problema do Partial State Saving.

A análise daquele desenvolvedor e esse post me inspiraram a implementar a minha solução. Agora, uso o estado interno do managed bean para determinar que estilo utilizarei no painel acima do meu componente Primefaces: o que usa “display: none” ou o que usa “display: block”. Assim, os componentes sempre serão renderizados, mas nem sempre apresentados na página.

1. Managed Bean

@ViewScoped
@ManagedBean(name = "bean")
public class Bean {

   // (...) demais propriedades

   private boolean opcoesAvancadas;

   public boolean isOpcoesAvancadas(){
      return opcoesAvancadas;
   }
	
   public void exibirOpcoesAvancadas(){
      opcoesAvancadas = !opcoesAvancadas;
   }
}

2. Configuração do CSS

.show {
    display: block;
}

.hide {
    display: none;
}

3. Página XHTML

<div>
   <div>
      <label>Nome</label>
      <p:inputText value="#{bean.pessoa.nome}"></p:inputText>
   </div>
   <h:panelGroup styleClass="#{bean.opcoesAvancadas ? 
      'show' : 'hide'}" id="painel">
      <label>Dependentes</label>
      <p:selectOneMenu value="#{bean.depedenteSelecionado}" >  
         <f:selectItem noSelectionOption="true" itemLabel= "Selecione..." />
         <f:selectItems value="#{bean.pessoa.dependentes}" var="dependente" 
            itemValue="#{dependente}" itemLabel="#{dependente.nome}" />
      </p:selectOneMenu>
   </h:panelGroup>
   <p:commandLink  value="Opções avançadas" 
      action="#{bean.exibirOpcoesAvancadas()}" update="painel" />
</div> 
Anúncios
  1. Nenhum comentário ainda.
  1. No trackbacks yet.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: