1 2 Previous Next 19 Replies Latest reply on Jan 31, 2007 5:12 AM by pmuir

    Seam - iterator tag?

    elenh

      Hi,

      Can anybody inform me about where I can find the documentation about seam's tag library (s:)?

      I'm trying to find out if seam provides any tag for iteration, like jstl's c:foreach? Or I have to use jstl?

      Thanx,
      Elenh

        • 1. Re: Seam - iterator tag?
          bfo81

          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

            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

              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

                 

                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?

                  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

                    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

                      I'll work on documenting the Seam taglib today.

                      • 8. Re: Seam - iterator tag?
                        max522over

                        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

                           

                          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?

                            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

                              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

                                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?

                                  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

                                     

                                    "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.


                                    1 2 Previous Next