pessoal tenho uma tela q possui um frame e uma Tree fora dele, eu quero q os nós da minha Tree atualizem meu frame, estou usando primeFaces mas nao sei como vou fzr isso!!!
Como colocar link no <p:Tree> (primeFaces)?
55 Respostas
dentro do teu <p:column> você faz isso direto não?
nao eu nem uso table, ele é construido assim:
<p:tree value="#{indexBean.root}" var="node">
<p:treeNode>
<h:outputText value="#{node}"/>
</p:treeNode>
</p:tree>
Isso não funciona?
<h:form>
<p:tree value="#{indexBean.root}" var="node">
<p:treeNode>
<h:commandLink value="#{node}" action="#{indexBean.doSth}" />
</p:treeNode>
</p:tree>
</h:form>
nao eu nem uso table, ele é construido assim:
<p:tree value="#{indexBean.root}" var="node"> <p:treeNode> <h:outputText value="#{node}"/> </p:treeNode> </p:tree>
Eu tinha entendido que era treeTable,
mas o código do dev.rafael deve funcionar corretamente
eu ate pensei no commandLink, mas minha duvida estava nesse ponto imagenine a estrutura:
+no.1
–+no1.1
–+no1.2
+no.2
–+no2.1
–+no2.2
ai se eu colocar o action, ele vai para todos, o q quero é q setar para o meu frame somente os nos filhos, no caso o no1.1,no1.2,no2.1,no2.2 e tb como vou colocar o target para o meu frame?
<h:form>
<p:tree value="#{indexBean.root}" var="node">
<p:treeNode>
<h:commandLink value="#{node}" action="#{indexBean.doSth(node)}" />
</p:treeNode>
</p:tree>
</h:form>
Ai no servidor vc atualiza o form com os nós filho de node.
eu entendi, mas nao sei como fazer isso no metodo doSth(node), como eu vou alterar o form no servidor, colocando a acao e “setando” o target ?
Os campos do seu form não estão vinculados à atributos de algum ManagedBean? Então é o método doSth(node) usar o objeto recebito p/ alterar os atributos. Quando a página for atualizada os campos do form vão conter as informações q vc colocou nesse atributos.
sim, o objeto que vou receber é um TreeNode, mas ele nao da opcao para eu mandar a url e nem target
Não o objeto q vc vai receber é do tipo declarado em “var” no seu p:tree. Ou seja, o tipo dos items armazenados em “#{indexBean.root}”.
entao esse root é um TreeNode !
@ManagedBean
public class IndexBean {
private TreeNode root;
public IndexBean() {
root = new DefaultTreeNode("Root", null);
TreeNode node0 = new DefaultTreeNode("Node 0", root);
TreeNode node1 = new DefaultTreeNode("Node 1", root);
TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);
TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);
TreeNode node010 = new DefaultTreeNode("Node 1.0", node1);
TreeNode node011 = new DefaultTreeNode("Node 1.1", node1);
}
public TreeNode getRoot() {
return root;
}
public void doSth(TreeNode node) {
Object data = node.getData();
// .. ai é só fazer a "mágica".
}
dev.Rafael me desculpa, mas realmente eu nao sei como eu vou setar a url e o target tem como vc colocar um exemplo ai para eu ver !
Faz o seguinte, posta o código q vc está usando ai
ManagedBean
import javax.faces.bean.ManagedBean;
import org.primefaces.model.TreeNode;
import org.primefaces.model.DefaultTreeNode;
@ManagedBean
public class IndexBean {
private TreeNode root;
public IndexBean() {
root = new DefaultTreeNode("Root", null);
TreeNode node0 = new DefaultTreeNode("Node 0", root);
TreeNode node1 = new DefaultTreeNode("Node 1", root);
TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);
TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);
TreeNode node010 = new DefaultTreeNode("Node 1.0", node1);
TreeNode node011 = new DefaultTreeNode("Node 1.1", node1);
TreeNode node000 = new DefaultTreeNode("Node 0.0.0", node00);
TreeNode node001 = new DefaultTreeNode("Node 0.0.1", node00);
TreeNode node0010 = new DefaultTreeNode("Node 0.1.0", node01);
}
public TreeNode getRoot() {
return root;
}
}
xhtml
<h:body>
<h:form>
<div id="divArvoredos">
<p:tree value="#{indexBean.root}" var="node">
<p:treeNode>
<h:link value="#{node}">
</p:treeNode>
</p:tree>
</div>
<iframe src="" name="miolo" class="coisa" width="730" marginwidth="0" height="518" marginheight="0" align="top" scrolling="no" frameborder="0">
</iframe>
</h:form>
</h:body>
<h:body>
<h:form>
<div id="divArvoredos">
<p:tree value="#{indexBean.root}" var="node">
<p:treeNode>
<h:link value="#{node}" target="miolo" outcome="/a_pagina_q_vai_no_frame?id=#{node.data}">
</p:treeNode>
</p:tree>
</div>
<iframe src="" name="miolo" class="coisa" width="730" marginwidth="0" height="518" marginheight="0" align="top" scrolling="no" frameborder="0">
</iframe>
</h:form>
</h:body>
A página q vai no frame fica mais ou menos assim:
<h:body>
<f:metadata>
<f:viewParam name="id" value="#{bean.id}" />
</f:metadata>
<!-- Aqui ficam os componentes q vão mostrar os dados -->
</h:body>
Ai vc só precisa de um bean p/ expor essas informações.
@Named
@RequestScoped
public class Bean {
private Pessoa pessoaSelecionada;
public Pessoa getPessoaSelecionada() {
return pessoaSelecionada;
}
public String getId() {
return pessoaSelecionada.getId();
}
public void setId(String id) {
pessoaSelecionada = em.find(Pessoa.class, id);
}
}
po obrigado eu consegui setar para o frame, mas ainda nao consegui pegar quem esta mandando a requisicao, nao entendi muito esse passo como eu posso fazer isso e a anotacao @Named q vc colocou é de que pacote e para q server, pq eu nao achei nas minhas bibliotecas ?
Essa anotação @Named tem a mesma função de @ManagedBean, mas vc deve usar @Named se estiver usando CDI. Eu, particularmente, não me vejo mais desenvolvendo em JSF sem CDI. A anotação @Named estará presente em qualquer servidor JEE6 (como Glassfish). Se vc não estiver usando um servidor JEE6 vc ainda pode adicionar CDI adicionando as bibliotecas do WELD ao seu projeto.
O q é isso de “quem está mandando a requisição”? Vc quer saber o usuário q o está fazendo ou a página de origem?
blz agora acho q entendi, vou simplificar ainda estou aprendendo jsf, e injecao de dependencia aina nao vi, mas dei uma olhada rapida aqui e aprendi um pouco, tive que importar a bilbioteca weld-servlet, configurar o listener no meu web.xml, para poder coloca a anotacao @named, ai blz so q quando eu vou ver minha aplicacao ela da
javax.servlet.ServletException: Servlet execution threw an exception
com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:542)
com.sun.faces.application.view.JspViewHandlingStrategy.executePageToBuildView(JspViewHandlingStrategy.java:355)
com.sun.faces.application.view.JspViewHandlingStrategy.buildView(JspViewHandlingStrategy.java:130)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)
root cause
java.lang.StackOverflowError
javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
Que server vc está usando?
tomcat 6.0.20
so nao entendi o META-INF/context.xml in the web root, é para o <Context>
<Resource name="BeanManager"
auth="Container"
type="javax.enterprise.inject.spi.BeanManager"
factory="org.jboss.weld.resources.ManagerObjectFactory"/>
</Context>
aonde ?
Q IDE vc está utilizando?
eclipse
então deve haver algo como:
+ MyApp
- + WebContent
- - + META-INF
- - - + context.xml
- - + WEB-INF
tb achei, fiz o passo a passo eu ainda nao rolou mesmo erro !
so dar para fzr isso com injecao ?
NP, vc vaz de qualquer jeito.
NP ? nao entendi ?
O CDI é apenas mais um framework q vai te ajudar. Mas ele não é obrigatório. Vc pode desenvolver JSF2 sem o CDI sem problemas.
sim mas ai voltamos para aquele problema como eu vou pegar o objeto selecionada dentro do frame ?
Problema nenhum. Basta substituir o @Named por @ManagedBean e está tudo resolvido.
tentei ja fazer com isso, mas nao sei o q esta havendo com request nao esta pegando o objeto !
q versão do JSF vc está usando?
2.0
no seu método public void doSth(TreeNode nt) o q está chegando p/ parametro?
eu nao criei esse metodo eu seto a pagina no outcome=“teste.xhtml?id=#{node}”
Nesse caso, vc está passando parâmetros através de uma requisição get. Esses parametros não podem ser de outro tipo q não String (até podem mais ai vc iria precisar de um Converter p/ lidar com isso). Vc vai fazer outcome=“teste?id=#{node.data}”. A extensão .xhtml não é necessária, o próprio JSF pode resolver isso p/ vc. Além disso
a página q será apresentada deve ter uma sessão f:metadata onde vc vai declarar os f:viewParams e associa-los à atributos de algum bean gerenciado. Exatamente como no ultimo código q postei.
entao eu criei uma pagina de teste e ficou assim
teste.xhtml // pagina dentro do frame<h:body>
<f:metadata>
<f:viewParam id="id" value="#{testeBean.id}" />
</f:metadata>
<h:form>
<h:outputText value="#{testeBean.id}"/>
<br/>
<h:outputText value="to aki"/>
</h:form>
</h:body>
@RequestScoped
@ManagedBean
public class TesteBean {
@ManagedProperty(name="id",value="#{requestScope.id}")
private TreeNode id;
public TreeNode getId(){
return id;
}
public void setId(TreeNode id){
this.id = id;
}
eu ate coloquei o ManagedProperty para ver ser pega o parametro id mas da "java.lang.NullPointerException: Erro de argumento: O parâmetro key é nulo"
kra, é uma requisição GET. Vc não está recebendo um TreeNode vc está recebendo uma String. Se vc quer receber um TreeNode vai precisar criar um custom Converter p/ converter a string q vc está recebendo em um TreeNode.
como eu posso fazer para ele me mandar via post ?
Não pode!
entendi, mas por mas q seja uma string, nem ela eu estou recebendo se nao o erro seria ClassCastException e nao NullPotinterException, se eu quizer pegar a string como faco ? com o custom Converter ?
Cara, substitui o:
<h:link value="Editar" target="miolo" outcome="teste.xhtml?id=#{node}" />
por:
<h:commandLink value="Editar" action="#{testeBean.edit(node)}" />
e no ManagedBean:
@ManagedBean
@RequestScoped
public class TesteBean {
private TreeNode node;
public TreeNode getNode() {
return node;
}
public String editNode(TreeNode node) {
this.node = node;
return "/teste";
}
}
Cara, substitui o:
view plaincopy to clipboardprint?
<h:link value=“Editar” target=“miolo” outcome=“teste.xhtml?id=#{node}” />
<h:link value=“Editar” target=“miolo” outcome=“teste.xhtml?id=#{node}” />por:
view plaincopy to clipboardprint?
<h:commandLink value=“Editar” action="#{testeBean.edit(node)}" />
nao posso o MangedBean responsavel por essa tela é o IndexBean, se eu colocar outro bean associado ele da pau, esse “testeBean.edit(node)}” teria que ser indexBean e ainda caio no mesmo ponto como faco para poder pegar do outro lado ?
Não existe isso de bean responsável pela tela. Em JSF n ManagedBeans podem ser associados aos diferentes componentes da sua view. Esse código funciona perfeitamente, eu garanto.
<p:tree value="#{indexBean.root}" var="node">
<p:treeNode>
<h:commandLink value="#{node}" target="miolo" action="#{testeBean.editar(node)}"/>
</p:treeNode>
</p:tree>
javax.servlet.ServletException: /index.xhtml @18,96 action="#{testeBean.editar(node)}" Error Parsing: #{testeBean.editar(node)}
javax.faces.webapp.FacesServlet.service(FacesServlet.java:325)
br.com.jsync.myjob.util.EntityManagerFiltro.doFilter(EntityManagerFiltro.java:45)
root cause
javax.faces.view.facelets.TagAttributeException: /index.xhtml @18,96 action="#{testeBean.editar(node)}" Error Parsing: #{testeBean.editar(node)}
com.sun.faces.facelets.tag.TagAttributeImpl.getMethodExpression(TagAttributeImpl.java:225)
com.sun.faces.facelets.tag.jsf.ActionSourceRule$ActionMapper2.applyMetadata(ActionSourceRul
Kra eu estou no final do meu expediente. Amanhã eu vejo isso p/ vc.
blz tb estou amanha se fala ate mais e obrigadao !!!
Ta ai kra.
A view:
<?xml version='1.0' encoding='UTF-8' ?>
<!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:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<title>Prime Tree</title>
</h:head>
<h:body>
<h:form>
<p:tree value="#{treeBean.root}" var="node"
nodeSelectListener="#{treeBean.nodeSelected}"
selectionMode="single"
update="detail">
<p:treeNode>
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
<h:panelGroup id="detail">
<iframe src="faces/detail.xhtml"></iframe>
</h:panelGroup>
</h:form>
</h:body>
</html>
A view q aparece no iframe:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.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">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>PrimeTree - Detail</title>
</h:head>
<h:body>
<h:outputText value="Hello #{treeBean.selected.data}!" />
</h:body>
</html>
E o ManagedBean:
@ManagedBean
public class TreeBean implements Serializable {
private TreeNode root;
private TreeNode selected;
public TreeBean() {
root = new DefaultTreeNode("Root", null);
TreeNode node0 = new DefaultTreeNode("Node 0", root);
TreeNode node1 = new DefaultTreeNode("Node 1", root);
TreeNode node2 = new DefaultTreeNode("Node 2", root);
TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);
TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);
TreeNode node10 = new DefaultTreeNode("Node 1.0", node1);
TreeNode node11 = new DefaultTreeNode("Node 1.1", node1);
TreeNode node000 = new DefaultTreeNode("Node 0.0.0", node00);
TreeNode node001 = new DefaultTreeNode("Node 0.0.1", node00);
TreeNode node010 = new DefaultTreeNode("Node 0.1.0", node01);
TreeNode node100 = new DefaultTreeNode("Node 1.0.0", node10);
}
public TreeNode getRoot() {
return root;
}
public void nodeSelected(NodeSelectEvent e) {
System.out.println("nodeSelected");
selected = e.getTreeNode();
}
public TreeNode[] getSelection() {
return new TreeNode[0];
}
public void setSelection(TreeNode[] selection) {
System.out.println("setSelection");
}
public TreeNode getSelected() {
return selected;
}
}
Vc pode fazer a mesma coisa sem iframe só com o h:panelGroup!
Rafael,
você pode dar uma olhada neste meu post aqui http://www.guj.com.br/posts/list/220025.java
não sei o que estou fazendo de errado, a tree não esta aparecendo.
Grato,
Filipe D.
po eu vi sua mensagem, mas nem cheguei a testar ainda, porque estava fissurado tentando fazer, acabei conseguindo e fiz aquilo que vc tinha dito usando o converter, mas vou fazer desse jeito que vc postou acho mais elegante, mas o meu ficou assim
index.xhtml
<h:form>
<div id="divArvoredos">
<p:tree value="#{indexBean.root}" var="node">
<p:treeNode>
<h:link outcome="teste" target="miolo">
<h:outputText value="#{node}" />
<f:param name="no" value="#{node}"/>
</h:link>
</p:treeNode>
</p:tree>
</div>
<iframe src="" name="miolo" class="coisa" width="730" marginwidth="0" height="518" marginheight="0" align="top" scrolling="no" frameborder="0">
</iframe>
</h:form>
teste.xhtml
<f:view contentType="text/html">
<f:metadata>
<f:viewParam name="no" value="#{testeBean.node}" />
</f:metadata>
<h:head>
<title>Ver Pessoa</title>
</h:head>
<h:body>
<h:form>
<h:outputText value="#{testeBean.node}"/>
</h:form>
</h:body>
</f:view>
IndexBean
@ManagedBean
public class IndexBean {
private TreeNode root;
private TreeNode nodeEmUso;
public IndexBean() {
root = new DefaultTreeNode("Root", null);
TreeNode node0 = new DefaultTreeNode("Node 0", root);
TreeNode node1 = new DefaultTreeNode("Node 1", root);
TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);
TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);
TreeNode node010 = new DefaultTreeNode("Node 1.0", node1);
TreeNode node011 = new DefaultTreeNode("Node 1.1", node1);
TreeNode node000 = new DefaultTreeNode("Node 0.0.0", node00);
TreeNode node001 = new DefaultTreeNode("Node 0.0.1", node00);
TreeNode node0010 = new DefaultTreeNode("Node 0.1.0", node01);
}
public TreeNode getRoot() {
return root;
}
TesteBean
@RequestScoped
@ManagedBean
public class TesteBean {
private TreeNode node;
public TreeNode getNode() {
return node;
}
public void setNode(TreeNode node) {
this.node = node;
}
}
TreeNodeConverter
@FacesConverter(forClass=TreeNode.class)
public class TreeNodeConverter implements Converter{
@Override
public Object getAsObject(FacesContext ctx, UIComponent ui, String str) {
TreeNode node = new DefaultTreeNode(str,null);
return node;
}
@Override
public String getAsString(FacesContext ctx, UIComponent ui, Object obj) {
return ((TreeNode)obj).getData().toString();
}
}
entendi a ideia, mas vc chegiu a testar ´? pq estou vendo aqui por algum motivo o valor nao esta aparecendo no frame !
Sim, esse código foi testado e funciona. Contudo eu tive alguns problemas quando usando o p:tree q acabaram por se resolver “sozinhos” de modo q eu não sei dizer se são bugs.