5 Replies Latest reply on Feb 21, 2007 3:31 AM by Per Norman

    Null Value in s:link w/IceFaces

    Greg Zoller Newbie


      I'm using <ice:dataTable> to render some search results, like in the hotel booking example. Here's a bit of the code:

      <ice:dataTable id="departments" width="100%" cellspacing="1"
       value="#{year.list}" var="item"
       <!-- More rendering stuff here -->
       <s:link id="viewItem" value="#{item.name}" action="#{year.selectItem(item)}"/>

      The 'item' var is correctly assigned and the item.name value is correctly rendered. When I click on the link year.selectItem() is called, but... I get a null value passed in. For some reason the 'item' isn't being passed.

      I know item is non-null because it rendered the name property correctly.

      Why wouldn't it be passed to selectItem()?

      I see that in the hotel booking example the list used in the ice:dataTable has a @DataModel annotation where in my app its just a list of non-Seam objects.

      If I make the list a @DataModel will item then be passed?


        • 1. Re: Null Value in s:link w/IceFaces
          Greg Zoller Newbie

          Ok, I'm making progress solving the problem.

          It turns out that you definitely do need to annotate the list in the backing bean used to populate the <ice:dataTable> with @DataModel. If you don't, even though IceFaces rendering components will see your line-item variable correctly populated, the Seam <s:link> tag won't feed the value back into Seam.

          Now my next complication...

          Can you successfully nest <ice:dataTable>'s w/Seam?

          Here's what I have so far:

          Rendering xhtml:

          <ice:dataTable id="departments" width="100%" cellspacing="1"
           value="#{outer}" var="item"
           <s:link id="viewItem" value="#{item.name}" action="#{mgrBean.selectItem(item)}"/>
           <ice:dataTable width="100%" cellspacing="1"
           value="#{inner}" var="bucket"
           <s:link id="viewBucket" value="#{bucket.name}" action="#{mgrBean.selectBucket(bucket)}"/>

          public class ManagerBean {
           private List<Foo> list;
           public void init() {
           // populate list
           public String selectItem(Foo foo) {...}
           public String selectBucket(Bar bar) {...}

          public class Foo {
           private List<Bar> buckets;

          So it might render something like this:


          Here's what happens: The outer table is rendered and clicking on the s:link elements for ONE, TWO, or THREE correctly passes the corresponding (non-null) objects to the backing bean (calling selectItem()).

          But clicking on A-E is still passing null to selectBucket() on the backing bean (ManagerBean).

          Has anyone nested these before? How about nesting non-IceFaces dataTables?

          • 2. Re: Null Value in s:link w/IceFaces
            Greg Zoller Newbie

            Further research... the original question in the post has been answered but nesting dataTables remains. Trying non-IceFaces DataTables yields the same result so I'm going to open a new post without the clutter of IceFaces.

            • 3. Re: Null Value in s:link w/IceFaces
              Per Norman Newbie

              I have the same problem. I've been trying several different repeater and datatable components from both Tomahawk, Trinidad and Facelets with the same result. The standard h:commandLink works fine, but an identical s:link always send null as parameter value.

              Whats wrong?

              I m using Seam 1.1.6,
              Myfaces 1.1.4,
              Facelets 1.1.12,
              Ajax4JSF 1.0.6,
              Trinidad incubator-m1-SNAPSHOT

              • 4. Re: Null Value in s:link w/IceFaces
                Greg Zoller Newbie


                Here's the scoop... for Seam to pass these components correctly in s:link Gavin said they need to be derived from DataModel (JSF class). Using the @DataModel annotation works on the outer table's data but not the inner tables', so you need to try to create them w/new() as DataModel instances. Remember that Seam juiced EL to allow parameter passing to methods, such as in s:link, which JSF doesn't currently support, and it appears from the code that non-DataModel objects are not passed (null is passed instead).

                So far I haven't fixed this particular problem, but I did find a work-around. In my <s:link> elements I can include a <f:param> element that passes an id I can use to find the object I wanted to pass in the first place. If your experience is like mine your can render/access everything you need in the xhtml but you just can't pass values to your backing objects in s:link, right?

                Won't win awards for sexiness but it works fine. In my project the code generated by seam-gen produced data tables that used this <s:link>/<f:param> partnership.

                ps. Here's another really cleaver/ugly hack to get around the parameter-passing limitations: use a "bastard" Map implementation. Standard EL lets you access #{myNamedObj.map[foo]} where foo is your object you want passed. Supposedly the map does a simple retrieval, but your bastard Map can override the get() method and do any blessed thing it wants. The magic is that your actual object got passed in! Of course you're trampling all over the semantics of what the Map class is supposed to do. I didn't say it was a good idea...but it works just fine.


                • 5. Re: Null Value in s:link w/IceFaces
                  Per Norman Newbie


                  It's good to know why it didn't work. The workaround solved it.