2 Replies Latest reply on Nov 4, 2005 8:01 AM by alextemnokhod

    accessing DataModel

    wildepete

      I am having trouble reconciling the way Seam examples use a data model vis a vis other JSF examples, books, etc.

      In the booking example the data model is outjected using @DataModel annotation on a field, and it is available only after an action method find has been called. This action method is called from as a result of a link on another page, then the navigation rules tell it to display the page with the data.

      @DataModel
       private List<Hotel> hotels;
       @DataModelSelectionIndex
       private int hotelIndex;


      It would appear to me that I have to make sure this action method is called whenever I want to navigate to this page.

      @Begin
       public String find()
       {
       hotel = null;
       String searchPattern = searchString==null ? "%" : '%' + searchString.toLowerCase().replace('*', '%') + '%';
       hotels = em.createQuery("from Hotel where lower(name) like :search or lower(city) like :search or lower(zip) like :search or lower(address) like :search")
       .setParameter("search", searchPattern)
       .setMaxResults(50)
       .getResultList();
      
       log.info(hotels.size() + " hotels found");
      
       return "main";
       }


      But what if I want to have a bookmarkable page (so no action method would have been called), or navigate from several other pages (and don't want to have to make sure that this action method is always called)?

      A lot of non-Seam examples have the value binding for dataTable coming from a property of a backing bean rather than directly from a context variable. The get method is called when the page is rendered and the bean can then fetch the data.

      <t:dataTable id="data"
       styleClass="scrollerTable"
       headerClass="standardTable_Header"
       footerClass="standardTable_Header"
       rowClasses="standardTable_Row1,standardTable_Row2"
       columnClasses="standardTable_Column,standardTable_ColumnCentered,standardTable_Column"
       var="car"
       value="#{pagedSort.cars}"
       preserveDataModel="true"
       rows="10"
       rowId="#{car.type}"
       rowOnClick="alert('rowId: ' + this.id)"
       sortColumn="#{pagedSort.sort}"
       sortAscending="#{pagedSort.ascending}"
       preserveSort="true">


      Is this approach compatible with Seam? E.g., can @DataModel annotate a getter method and still function properly?

      or put another way

      What is the best / recommended way to fetch values without calling an action method? Put another way I want a data model to exist upon initial render.

      In the booking example the user has to first input a search string before the data is fetched, so it makes sense. However in my application I want to have my "main" page be the List of all existing items AND have it be pageable (use Tomahawk enhanced dataTable).


        • 1. Re: accessing DataModel
          alextemnokhod

          It's interesting problem. My current simple solution (booking example):

          public class HotelBookingAction implements HotelBooking, Serializable {
          ...
           public List<Hotel> getHotels() { // add this getter
           if (hotels == null) {
           searchString = null;
           find();
           }
           return hotels;
           }
          ...
          }
          
          public interface HotelBooking {
          ...
           public java.util.List<Hotel> getHotels();
          ...
          }
          
          // in main.xhtml
           <h:outputText value="No Hotels Found" rendered="#{hotelBooking.hotels != null and empty hotelBooking.hotels}"/>
           <h:dataTable value="#{hotelBooking.hotels}" var="hot" rendered="#{not empty hotelBooking.hotels}">
          
          


          So you can access http://localhost:8080/seam-booking/main.jsf via GET requests, without Find button. Notice that there is no conversation now:
          INFO [HotelBooking] 10 hotels found
          INFO [HotelBooking] destroyed
          


          • 2. Re: accessing DataModel
            alextemnokhod

            Also don't forget to add @Begin to selection method (to allow hotel selection):

             @Begin
             public String selectHotel()