[Resolvido] Menu Dinâmico em JSF + Primefaces

Boa tarde meus caros,

Preciso criar um menu para meu soft em jsf + primefaces. A ideia é usar um p:megamenu em cima e uma p:tabView para exibir os módulos abaixo.

Pesquisei muito sobre como fazer isto, e encontrei 2 soluções, ambas com problemas até agora insolúveis, devido minha ignorância no assunto até o momento:

1 - Loop com ForEach: No entanto, parece existir um bug já bem conhecido pela comunidade que impede que eu faça um include dinamicamente assim.

2 - Registrar as tabs todas e controlar o Rendered através de atributo da Bean - Mas dai surge alguns incomodos:

Além do código ficar meio poluído (mas td bem), o problema eh que… se eu criar tab “X”, depois “Y”, depois “Z”, mas meu usuário chamar esses módulos em ordem diversa, por exemplo: primeiro ele chama a “Z”, depois a “Y”, depois a “X”, ele vai apresentar na ordem que está no código. Ou seja, corre o risco do meu usuário estar lá com inúmeras abas abertas, chamar mais uma… e esta aba aparecer lá no inicio… o que fica estranho, concordam?

Alguem tem alguma sugestão para resolver este problema? Ou mesmo alguma maneira totalmente diferente desta, outros componentes, enfim… Sou novo nesta tecnologia e ainda estou carecendo de padrões…

Um abraço a todos!

Não cheguei a ler todo o seu post, mas vou responder direto ao assunto. Você pode gerar o megamenu por um managedbean, inclusive o controle de usuário em questões de mostrar os itens, pode ser feito por lá. Dê uma olhada na documentação do componente, é bem simples de fazer e creio que não será dificil de implementar. Eu já fiz alguns a um bom tempo atrás, e bem provavel que agora seja bem mais facil fazê-lo.

Obrigado por responder André.

Feito está, mas com os inconvenientes que descrevi ao final do post. Existe uma maneira de faze-lo sem tais inconvenientes? Se sim, poderia me fornecer um exemplo?

Um abraço.

Obrigado André! Através da sua dica e a partir disso, minhas pesquisas, encontrei a solução…

Caso seja útil pra alguém:

Declaro a tabView da seguinte forma:

<p:tabView id="tabViewMenu" binding="#{bean.tabViewMenu}"> 

Desta maneira, seu conteúdo fica a cargo do componente tabViewMenu do bean.

No bean, declaro a tabView normalmente:

private TabView tabViewMenu;

e criei um método para adicionar as tabs dinamicamente:

[code] public void adicionaTab(String titulo, String url) {

	Tab aba = new Tab();

	aba.setTitle(titulo);
	aba.setClosable(true);
	
	FacesContext facesContext = FacesContext.getCurrentInstance();
	FaceletContext faceletContext = (FaceletContext) facesContext.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
	
	try {
		faceletContext.includeFacelet(aba, url);
	} catch (IOException e) {
		e.printStackTrace();
	}
	
	tabViewMenu.getChildren().add(aba);

}[/code]

depois, apenas chamo o método no xhtml:

<p:menuitem value="Cad. de Clientes" update=":tabViewMenu" actionListener="#{bean.adicionaTab('Cad. Clientes','cadClientes.xhtml')}"/>

Claro, poderia ser em um botão ou coisa do tipo…

é isso… Muito obrigado a todos que leram… um abraço!

Olá, primeiro muito obrigado para a entrada e desculpe pela tradução.

Eu tentei o exemplo, mas ele não funciona corretamente. Coloque o primeiro guia na página xhtml, mas trava os outros botões e não faz nada.

Esta é a parte do bean:

@Named
@RequestScoped
public class contenidoController implements Serializable {
	private static final long serialVersionUID = 1L;
	
	private TabView tabView = new TabView();
	private Menu subMenuSelected;
	private int tabRemove;	
	
	
	//Getters y Setters

	
	//Métodos
	public void doCrear(String nombre, String url) {
		Tab tab = new Tab();

		tab.setTitle(nombre);
		tab.setClosable(true);

		FacesContext facesContext = FacesContext.getCurrentInstance();  
	    FaceletContext faceletContext = (FaceletContext) facesContext.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);  
	      
	    try {
	    	faceletContext.includeFacelet(tab, url);  
	    } catch (IOException e) {
	        e.printStackTrace(); 
	    }
	    
		tabView.getChildren().add(tab);
	}
	
}

Este é o xhtml:

                <h:form id="formMenu">
		<p:commandButton value="Entidades" actionListener="#{contenidoController.doCrear('Entidades', '/banco_list.xhtml')}" update=":formMenu:tabContent" />
		<p:commandButton value="Usuarios" actionListener="#{contenidoController.doCrear('Usuarios', '/usuario_list.xhtml')}" update=":formMenu:tabContent" />
	
		<p:tabView id="tabContent" binding="#{contenidoController.tabView}">									
		</p:tabView>	
	</h:form>		

Gostaria muito de receber alguma ajuda. Foram necessários vários dias de leitura de documentação sobre isso, mas não pode fazê-lo funcionar correctametne.

Obrigado

[quote=tipet]Olá, primeiro muito obrigado para a entrada e desculpe pela tradução.

Eu tentei o exemplo, mas ele não funciona corretamente. Coloque o primeiro guia na página xhtml, mas trava os outros botões e não faz nada.

Esta é a parte do bean:

@Named
@RequestScoped
public class contenidoController implements Serializable {
	private static final long serialVersionUID = 1L;
	
	private TabView tabView = new TabView();
	private Menu subMenuSelected;
	private int tabRemove;	
	
	
	//Getters y Setters

	
	//Métodos
	public void doCrear(String nombre, String url) {
		Tab tab = new Tab();

		tab.setTitle(nombre);
		tab.setClosable(true);

		FacesContext facesContext = FacesContext.getCurrentInstance();  
	    FaceletContext faceletContext = (FaceletContext) facesContext.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);  
	      
	    try {
	    	faceletContext.includeFacelet(tab, url);  
	    } catch (IOException e) {
	        e.printStackTrace(); 
	    }
	    
		tabView.getChildren().add(tab);
	}
	
}

Este é o xhtml:

                <h:form id="formMenu">
		<p:commandButton value="Entidades" actionListener="#{contenidoController.doCrear('Entidades', '/banco_list.xhtml')}" update=":formMenu:tabContent" />
		<p:commandButton value="Usuarios" actionListener="#{contenidoController.doCrear('Usuarios', '/usuario_list.xhtml')}" update=":formMenu:tabContent" />
	
		<p:tabView id="tabContent" binding="#{contenidoController.tabView}">									
		</p:tabView>	
	</h:form>		

Gostaria muito de receber alguma ajuda. Foram necessários vários dias de leitura de documentação sobre isso, mas não pode fazê-lo funcionar correctametne.

Obrigado[/quote]

O log apresenta algum erro?

Os arquivos xhtml estão na mesma pasta?

O log não mostra Glassfish errro. Primefaces versão é de 3.4.
Os arquivos estão na mesma pasta localmente.

Um abraço.

[quote=tipet]O log não mostra Glassfish errro. Primefaces versão é de 3.4.
Os arquivos estão na mesma pasta localmente.

Um abraço.
[/quote]

Já tentou remover a barra do endereço?

Exemplo:

actionListener="#{contenidoController.doCrear(‘Usuarios’, ‘usuario_list.xhtml’)}"

Não consegui encontrar um defeito no seu código…

Eu tentei e não funciona.
A primeira guia é carregar bem e depois, quando ele trava e não reage a nenhum botão. Ao recarregar o trabalho dissipação página.

Poderia dar o exemplo completo que funciona?

obrigado

[quote=tipet]Eu tentei e não funciona.
A primeira guia é carregar bem e depois, quando ele trava e não reage a nenhum botão. Ao recarregar o trabalho dissipação página.

Poderia dar o exemplo completo que funciona?

obrigado[/quote]

Por acaso não se trata de ID’s repetidos?

Veja…

Ao trabalhar com abas… as páginas que você carregar nas abas ficam sendo parte de um mesmo documento html… por isso, você não pode usar a mesma ID para os componentes, mesmo em documentos a parte…

entendeu o possível problema?

Verifique se é isto, se for, eu tenho uma solução pra isto também…

Abraço

No ID para atribuir tabs, faz isso automaticamente.
Se o bean é @SessionScoped si falhar por ID repetido.

O código é o mesmo que o seu para criar a guia. Então eu perguntei se você pode postar mais código, para analisá-lo bem.

relação.

[quote=tipet]No ID para atribuir tabs, faz isso automaticamente.
Se o bean é @SessionScoped si falhar por ID repetido.

O código é o mesmo que o seu para criar a guia. Então eu perguntei se você pode postar mais código, para analisá-lo bem.

relação.[/quote]

Meu código é este mesmo…

Poderia postar o código do banco_list e usuario_list?

banco_list.xhtml e é o mesmo usuario_list.xhtml.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<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"
	xmlns:p="http://primefaces.org/ui">

<ui:composition>
	<h:form>
		<p:dataTable id="listBancos" value="#{bancoController.bancoList}" var="banco"
			selection="#{bancoController.bancoSel}" selectionMode="single" rowKey="#{banco.id}">				
			<p:column headerText="Id">
				<h:outputText value="#{banco.id}"/>
			</p:column>
			<p:column headerText="Banco">
				<h:outputText value="#{banco.nombre}"/>			
			</p:column>		
			<p:column headerText="Alias">				
				<h:outputText value="#{banco.alias}"/>			
			</p:column>	
			<p:column headerText="Código">				
				<h:outputText value="#{banco.codigo}"/>			
			</p:column>	
			<p:column headerText="País">				
				<h:outputText value="#{banco.pais.nombre}"/>			
			</p:column>				
		</p:dataTable>		
	</h:form>
</ui:composition>
</html>

me passe seu endereço de e-mail que eu mando um código completo pra você ver…

Olá, meu e-mail é tipetillo@gmail.com
Estou muito grato pelo seu apoio.

Oi Rodrigo, eu vou deixar este endereço um trabalho eu verificar com mais freqüência.

rbadenes@gsgestion.com

Uma saudação.

[quote=tipet]Oi Rodrigo, eu vou deixar este endereço um trabalho eu verificar com mais freqüência.

rbadenes@gsgestion.com

Uma saudação.[/quote]

Olá, eu não recebi nenhum e-mail tal. Você já teve algum problema com o e-mail?