Galera estou iniciando os estudos com JSF2 + Primefaces, e estou com uma duvida na hora de manipular a visibilizade de componentes de uma tela, por exemplo tenho um h:selectOneMenu e ao escolher determinado indice eu tenho de esconder componentes de um p:dialog e tambem redistribuir os componentes no painel, mas estou completamente confuso em como fazer isso.
Controle componentes visiveis JSF2 + Primefaces
12 Respostas
Para controlar a visualização dos componentes, use o atributo rendered=(boolean) dos componentes.
Eu crio um atributo boolean no managed bean e altero seu valor de acordo com as ações ocorridas na tela.
Ex: O usuário selecionou um valor no selectOneMenu.
O valor é submetido pra um método que verifica qual valor foi selecionado.
Se esse valor for X, eu seto a visualização do componente Y pra false.
Entao no meu managedBean eu tenho todos os componentes?
por exemplo um botoes inputtext etc, e no ManagedBean manipular esses componentes?
Não.
Funciona assim:
No managed bean vc declara um boolean para controlar a exibição do painel X
private boolean exibePainelX = Boolean.TRUE; // get/set
Na página vc utiliza o rendered apontando para o boolean do managed bean.
<h:panel id="painelX" rendered="#{seuMB.exibePainelX}">
E de acordo com as interações do usuário, vc altera o valor da variavel exibePainelX e controla a visualização dos componentes na tela. Por exemplo: ao clicar num botão é chamado o método #seuMB.atualizar(). Dentro desse método vc altera o valor do atributo exibePainelX e pode esconder algum botão, campo de texto, painel, etc… Todos esses componentes tem o atributo rendered.
entendi e na açaõ do comboBox eu chamo o update atualizo o painel e na acao eu altero o atributo boolean
Isso. Segue um exemplo “real”:
Tenho uma página de cadastro de usuários. Se o usuário for do tipo “cliente”, ele deve estar vinculado à um cliente já cadastrado.
O componente “comboCliente” não é exibido quando a página é carregada, pois meu atributo exibirComboCliente tem o valor default false.
No método selecionarTipoUsuario, acionado pelo evento onchange do combo, verifico o tipo escolhido e altero o valor de exibirComboCliente, refletindo na renderização do componente “comboCliente”.
<h:outputLabel value="#{msg.usuario_tipo}" />
<h:selectOneMenu value="#{usuarioMB.usuario.tipoUsuario}" id="comboTipoUsuario" style="width:200px;">
<f:selectItems value="#{usuarioMB.tipos}" />
<p:ajax event="change" action="#{usuarioMB.selecionarTipoUsuario}" update="painelCadastrarUsuario" />
</h:selectOneMenu>
<h:outputLabel value="#{msg.usuario_cliente}" id="clienteLabel" rendered="#{usuarioMB.exibirComboCliente}" />
<h:selectOneMenu value="#{usuarioMB.usuario.cliente}" id="comboCliente" rendered="#{usuarioMB.exibirComboCliente}" style="width:200px;">
<f:selectItems value="#{usuarioMB.clientes}" id="clienteItens" />
<f:converter converterId="clienteConverter"/>
</h:selectOneMenu>
/**
* Se tipo selecionado for Cliente, exibe o combo de clientes
*/
public void selecionarTipoUsuario() {
if(TipoUsuario.CLIENTE.toString().equals(usuario.getTipoUsuario())) {
setExibirComboCliente(Boolean.TRUE);
} else {
setExibirComboCliente(Boolean.FALSE);
}
}
ok mas a minha duvida é a seguinte, no seu caso voce faz a verificação em cima dos atributos do objeto cliente, agora no meu caso eu tenho um selectOnItem fixo statico
<h:selectOneMenu id="cbEnvioEmail">
<f:selectItem itemLabel="E-mail Cadastrado" itemValue="1"/>
<f:selectItem itemLabel="Inserir E-mail" itemValue="2"/>
</h:selectOneMenu>
Entao ao chamar o evento do combo preciso passar o valor dele no caso o itemValue, para verificar qual a opção esta selecionada para dae manipular os componentes.
<p:ajax event="change" action="#{nFeController.selecionarTipoEmail}" update="pnlEmail" />
mas como eu faria para passar o valor do combo selecionado?
e o estranho quando coloco este p:ajax ele me da erro “O atributo action nao esta definido na interface do componente”
faça a compração dentro de rendered, exemplo:
<p:selectOneMenu value="#{meuBean.meuInt}">
<f:selectItem itemLabel="E-mail Cadastrado" itemValue="1"/>
<f:selectItem itemLabel="Inserir E-mail" itemValue="2"/>
<p:ajax event="change" update="output" process="@this"/>
</p:selectOneMenu>
<p:outputpanel id="output">
<p:panel rendered="#{meuBean.meuInt = 1}">
</p:panel>
<p:panel rendered="#{meuBean.meuInt = 2}">
</p:panel>
</p:outputpanel>
aqui vc ta jogando o valor pro seu int e depois buscando e mostrando a tela que o cliente solicitou !
Polverini blz agora funcionou, só tira algumas duvidas pra mim, por exemplo se eu nao coloco o outputPanel, o componente nao atualiza, entao eu tenho de fazer sempre com esse componente para que funcione?
o que seria esse process="@this" pois se eu tiro tambem funciona.
Obrigado.
como vc esta usando o rendered uma vez que o valor seja = false o componente não é desenhado, então ele não existe, desse modo não tem como atualiza-lo, assim vc tem que deixa-lo dentro de um outro componente e atualizar este componente acima, como por exemplo <h:form>.
Quando vc usa o @this vc envia o valor somente do select ou do componente que usa ele, caso nao use vc vai enviar o form inteiro, sendo assim se existir algum item componente required=“true” o select não vai funcionar, você pode usar o id no process tbm
veja mais aqui: http://www.primefaces.org/showcase-labs/ui/pprPartialTree.jsf
No caso por exemplo quero que ao disparar o evento change do combo eu chame um metodo no meu ManagedBean para montar uma lista, e passar para um dataList, vi os exemplos no showLab do primefaces, e vi a opção com o listener, entao fiz o seguinte...
<p:ajax event="change" update="pnlTipoEmail"
listener="#{nFeController.selecionarTipoEmail()}" process="@this" />
no meu ManagedBean
public void selecionarTipoEmail() {
switch (tipoEmail) {
case 1:
emailList = new ArrayList<String>();
emailList.add("[email removido]");
emailList.add("[email removido]");
emailList.add("[email removido]");
break;
}
}
e na minha pagina
<p:dataList value="#{nFeController.emailList}" var="email">
#{email}
</p:dataList>
mas ao executar esta disparando um exception
javax.servlet.ServletException: /pages/listaNFe.xhtml @177,101 listener="#{nFeController.selecionarTipoEmail()}" Error Parsing: #{nFeController.selecionarTipoEmail()}
javax.faces.webapp.FacesServlet.service(FacesServlet.java:422)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:113)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
está sobrando () no seu #{nFeController.selecionarTipoEmail()}, o certo seria #{nFeController.selecionarTipoEmail}
noss que erro besta, entao por exemplo quando chamo um metodo do meu ManagedBean nao consigo passar nenhum parametro certo?
eu apenas chamo o nome do metodo, qual seria a diferenca por exemplo de action para um actionListener, pois no action Listener é possivel passar parametro para o metodo do MB?