-
1. Re: Seam - iterator tag?
bfo81 Jul 13, 2006 8:35 AM (in response to elenh)Iteration over JSF tags isn't possible. You know, every JSF page has a static component tree, and the number of contained components cannot vary.
To put it in a nutshell: There's no JSF iteration tag, and you even NEVER shouldn't do something like that:
<JSTL loop>
</JTSL loop>
The only possibilty to iterate over something in JSF is the dataTable-Tag. -
2. Re: Seam - iterator tag?
bfo81 Jul 13, 2006 8:36 AM (in response to elenh)For some reason the forum has corrupted my Post. So here it is again: What you shouldn't do
Start of JTSL Loop
A JSF Tag
End of JSTL Loop -
3. Re: Seam - iterator tag?
elenh Jul 13, 2006 9:17 AM (in response to elenh)Ok thanx for the reply?
But where can I find the documendation of the seam tag library? I have only come up with the s:link, s:conversationId and s:validateAll tag?
Thanx,
Elenh -
4. Re: Seam - iterator tag?
pmuir Jul 13, 2006 11:04 AM (in response to elenh)I'm trying to find out if seam provides any tag for iteration, like jstl's c:foreach?
If you use facelets you can use <ui:repeat> -
5. Re: Seam - iterator tag?
cptnkirk Jul 13, 2006 11:17 AM (in response to elenh)I think if you use JSF 1.2 you can use c:foreach again. Although iterators like dataTable and ui:repeat are supposed to be much more efficient than JSTL looping.
-
6. Re: Seam - iterator tag?
gavin.king Jul 13, 2006 12:52 PM (in response to elenh)Personally I am very happy with ui:repeat in facelets. I'm not convinced that h:dataTable isn't a little over-engineered for what it does ;-)
-
7. Re: Seam - iterator tag?
gavin.king Jul 13, 2006 1:01 PM (in response to elenh)I'll work on documenting the Seam taglib today.
-
8. Re: Seam - iterator tag?
max522over Jul 14, 2006 2:25 PM (in response to elenh)If you want info about myfaces try:
http://wiki.apache.org/myfaces/FrontPage
or
http://myfaces.apache.org/
if you want information about JSF you can go:
http://www.jcp.org/en/jsr/detail?id=127
or
http://java.sun.com/javaee/javaserverfaces/
But as far as Seam's JSF tags. I think Seam was designed to work with JSF and therefore all the JSF tag libraries that are compliant with spec should work with Seam. I could be wrong but that is the way I understand it.
Mark -
9. Re: Seam - iterator tag?
gavin.king Jul 14, 2006 2:38 PM (in response to elenh)But as far as Seam's JSF tags. I think Seam was designed to work with JSF and therefore all the JSF tag libraries that are compliant with spec should work with Seam. I could be wrong but that is the way I understand it.
Correct. -
10. Re: Seam - iterator tag?
dbatcn Jul 24, 2006 8:26 PM (in response to elenh)Does <ui:repeat> support @DataModel, @DataModelSelection, etc.? I couldn't find any evidence of it in the reference and I tried looking at the code but got lost... ;-)
-
11. Re: Seam - iterator tag?
basel Jul 25, 2006 12:03 AM (in response to elenh)The <ui:repeat> needs a list of objects to iterate over, this has nothing to do with support. You can find an example is the dvd-store sample application bundled with Seam.
-
12. Re: Seam - iterator tag?
pmuir Jul 25, 2006 7:30 AM (in response to elenh)AFAIK you can iterate using ui:repeat over a DataModel but @DataModelSelection definitely won't work (but probably better to just iterate over an outjected list?)
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=81781#3939903 -
13. Re: Seam - iterator tag?
dbatcn Jul 26, 2006 8:25 PM (in response to elenh)I looked at the link that Pete pointed out and the way I read Gavin's comment in there I didn't see why @DataModelSelection shouldn't work. If true, enlightenment appreciated.
Anyway, what I'm trying to do is have a page that uses nested iteration to let a user operate on both sides of a many-to-many relationship. I'm inclined to agree with Gavin that "I'm not convinced that h:dataTable isn't a little over-engineered for what it does ;-)". In particular for my application, I don't want the HTML table from <h:dataTable>.
I've created an abstracted little Seam app that gets at what I'm trying to do: iterate over an iteration and be able to do an operation over either the inner or outer iteration. When pressing the "rename" buttons, the value that I expect to be injected is not there (the log.error() calls below are triggered). I believe that this is a self-contained, compilable, runnable, and suitable small abstraction for a test case or bug report, if that's helpful. Code goes into a package called com.orgmob.play .
Is this a bug or can anybody say how to do this?
As always, pointing out bugs of mine and/or pointers to existing explanation humbly and gratefully appreciated.
Foo.java:package com.orgmob.play; import java.io.Serializable; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; import javax.persistence.Transient; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.datamodel.DataModel; @Entity @Name("foo") @Table(name="FOOS") public class Foo implements Serializable { private long id; private String name; private Set<Bar> bars = new HashSet<Bar>(); @Id @Column(name="FOO_ID") @GeneratedValue public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Column(name="NAME") public String getName() { return name; } public void setName(String groupname) { this.name = groupname; } @ManyToMany(cascade=CascadeType.PERSIST) @JoinTable(name="FOO_BAR", joinColumns={@JoinColumn(name="FOO_ID")}, inverseJoinColumns={@JoinColumn(name="BAR_ID")}) public Set<Bar> getBars() { return bars; } public void setBars( Set<Bar> bars ) { this.bars = bars; } @Transient @DataModel(value="barList") public List<Bar> getBarList() { return new ArrayList<Bar>( bars ); } @Override public String toString() { return "Foo[" + name + "]"; } }
Bar.java:package com.orgmob.play; import java.io.Serializable; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; import org.jboss.seam.annotations.Name; @Entity @Name("bar") @Table(name="BARS") public class Bar implements Serializable { private long id; private String name; private Set<Foo> foos = new HashSet<Foo>(); @Id @Column(name="BAR_ID") @GeneratedValue public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Column(name="NAME") public String getName() { return name; } public void setName(String groupname) { this.name = groupname; } @ManyToMany(cascade=CascadeType.PERSIST,mappedBy="bars") public Set<Foo> getFoos() { return foos; } public void setFoos( Set<Foo> foos ) { this.foos = foos; } @Override public String toString() { return "Bar[" + name + "]"; } }
FubarManager.java:package com.orgmob.play; import javax.ejb.Local; @Local public interface FubarManager { public void find(); public void stop(); public void createFoo(); public void commitFoo(); public void commitBar(); public void destroy(); public void delete(); }
FubarManagerBean.java:package com.orgmob.play; import java.io.Serializable; import java.util.HashSet; import java.util.List; import javax.ejb.Remove; import javax.ejb.Stateful; import javax.persistence.EntityManager; import org.jboss.seam.annotations.Begin; import org.jboss.seam.annotations.Destroy; import org.jboss.seam.annotations.End; import org.jboss.seam.annotations.Factory; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.datamodel.DataModel; import org.jboss.seam.annotations.datamodel.DataModelSelection; import org.jboss.seam.log.Log; @Stateful @Name("fubarManager") public class FubarManagerBean implements FubarManager, Serializable { @Logger private Log log; @DataModel(value="fooList") private List<Foo> fooList; @DataModelSelection(value="fooList") @Out(required=false) private Foo foo; @DataModelSelection(value="barList") @Out(required=false) private Bar bar; @In(create=true) private EntityManager orgmobDatabase; @Begin(join=true) @Factory("fooList") public void find() { log.debug("looking for foo objects..."); fooList = (List<Foo>)orgmobDatabase.createQuery( "from Foo foo order by foo.id asc").getResultList(); log.debug("found "+fooList.size()+" foos in fooList: " + fooList ); } @End public void stop() { } private String newFooname() { // find a group name not currently seen by user; HashSet<String> foonameS = new HashSet<String>(); for ( Foo foo : fooList ) { foonameS.add( foo.getName() ); } String foonamePrefix = "foo"; String fooname; int attempt = 1; do { fooname = foonamePrefix + (attempt++); } while ( foonameS.contains( fooname ) ); return fooname; } public void createFoo() { foo = new Foo(); foo.setName( newFooname() ); orgmobDatabase.persist( foo ); // always use the Bar with the lowest id. List<Bar> allBars = (List<Bar>)orgmobDatabase.createQuery( "from Bar bar order by bar.id asc").getResultList(); Bar bar = null; if ( allBars.size() > 0 ) { bar = allBars.get( 0 ); // Foo owns the bidirectional many-to-many relationship with Bar. foo.getBars().add( bar ); } orgmobDatabase.merge( foo ); orgmobDatabase.flush(); if ( null != bar ) { orgmobDatabase.refresh( bar ); } log.debug( "for bar "+bar+" created foo: "+foo); log.debug( "foo "+foo+" has "+foo.getBars().size()+" bars"); log.debug( "bar "+bar+" has "+bar.getFoos().size()+" foos"); for ( Bar b : foo.getBars() ) { log.debug( "a bar for foo "+foo+": "+b); } if ( null != bar ) { for ( Foo f : bar.getFoos() ) { log.debug( "a foo for bar"+bar+": "+f); } } find(); // update fooList } public void commitFoo() { if ( null == foo ) { log.error("FubarManagerBean.commitFoo() called but foo is null!"); } else { orgmobDatabase.merge( foo ); } } public void commitBar() { if ( null == bar ) { log.error("FubarManagerBean.commitBar() called but bar is null!"); } else { orgmobDatabase.merge( bar ); } } public void delete() { foo.getBars().remove(bar); orgmobDatabase.remove(bar); bar=null; } @Destroy @Remove public void destroy() { } }
fubar.xhtml:<!DOCTYPE composition 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:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:ui="http://java.sun.com/jsf/facelets" > <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Fubar Manager</title> </head> <body> <h:form> <h:outputText value="you have no foos" rendered="#{empty fooList or fooList.rowCount == 0}" /> <ui:repeat var="foo" value="#{fooList}" rendered="#{not empty fooList and fooList.rowCount > 0}"> <hr/> <h:outputText value="#{1+fooList.rowIndex}"/>. <s:link linkStyle="button" value="rename foo" action="#{fubarManager.commitFoo}" /> <h:inputText value="#{foo.name}" /> <br/> <ui:repeat var="bar" value="#{foo.barList}"> <br/> <s:link linkStyle="button" value="rename bar" action="#{fubarManager.commitBar}" /> <h:inputText value="#{bar.name}" /> </ui:repeat> </ui:repeat> <hr/> <hr/> <s:link value="New Foo" action="#{fubarManager.createFoo}" linkStyle="button" /> </h:form> </body> </html>
components.xml:<components> <component name="org.jboss.seam.core.init"> <property name="myFacesLifecycleBug">true</property> <property name="jndiPattern">member/#{ejbName}/local</property> </component> <component class="org.jboss.seam.core.Ejb" installed="false"/> <!-- Configuring a managed persistence context --> <component name="orgmobDatabase" class="org.jboss.seam.core.ManagedPersistenceContext"> <property name="persistenceUnitJndiName">java:/EntityManagerFactories/orgmobData</property> </component> </components>
import.sql:insert into FOOS(FOO_ID,NAME) values (1,'foo1') insert into FOOS(FOO_ID,NAME) values (2,'foo2') insert into FOOS(FOO_ID,NAME) values (3,'foo3') insert into FOOS(FOO_ID,NAME) values (4,'foo4') insert into FOOS(FOO_ID,NAME) values (5,'foo5') insert into BARS(BAR_ID,NAME) values(1,'bar1') insert into BARS(BAR_ID,NAME) values(2,'bar2') insert into BARS(BAR_ID,NAME) values(3,'bar3') insert into BARS(BAR_ID,NAME) values(4,'bar4') insert into BARS(BAR_ID,NAME) values(5,'bar5') insert into FOO_BAR(FOO_ID,BAR_ID) values(1,1) insert into FOO_BAR(FOO_ID,BAR_ID) values(2,2) insert into FOO_BAR(FOO_ID,BAR_ID) values(1,2) insert into FOO_BAR(FOO_ID,BAR_ID) values(3,3) insert into FOO_BAR(FOO_ID,BAR_ID) values(1,3) insert into FOO_BAR(FOO_ID,BAR_ID) values(4,4) insert into FOO_BAR(FOO_ID,BAR_ID) values(1,4) insert into FOO_BAR(FOO_ID,BAR_ID) values(5,5) insert into FOO_BAR(FOO_ID,BAR_ID) values(1,5)
-
14. Re: Seam - iterator tag?
pmuir Jul 27, 2006 7:34 AM (in response to elenh)"dbatcn" wrote:
I looked at the link that Pete pointed out and the way I read Gavin's comment in there I didn't see why @DataModelSelection shouldn't work. If true, enlightenment appreciated.