2 Replies Latest reply on May 12, 2009 2:57 AM by Ross Johnson

    Problem testing component for null in rendered attribute

    Ross Johnson Newbie

      Hello,


      I have a page which shows a list of entities (@DataModel) and the details of the user selected entity. Until a row is selected, the details should not be displayed.


      I have been trying to control the details display with the rendered attribute like


      <h:outputText value="testEntity not null" rendered="#{testEntity!=null}" />
      



      where testEntity is an entity bean/seam component.


      The problem is that I can never make this test return false. I have tried adding @In(create=false, required=false) and @Out(required=false) in my SFSB. There is no @AutoCreate on the entity. I have even tried using a different component whos only reference in the whole application is in the afore mentioned test.


      Is this correct behavior? My main concern here is that I don't understand the rules that govern when seam instantiates a component.


      /Ross.

        • 1. Re: Problem testing component for null in rendered attribute
          Arbi Sookazian Master

          The entities that are looped thru in a h:dataTable component are typically not null.


          For example, if your outjected ListDataModel instance is based on a JPAQL query like:


          @DataModel
          List<Customer> customerList;
          
          public foo() {
              customerList = entitymanager.createQuery("select c from Customer c").getResultList();
          }



          Then typically all x Customer entities in this outjected ListDataModel are not null.


          What you need to do is add an action method so when the user clicks on a button/link for a particular row in the dataTable, a context variable (property) is set to true in your SFSB and then reRender the lower UI component to display it.


          This addresses your concern (from SiA book):


          When the tip context variable is referenced by a value expression in the JSF template (#{tip.*}), Seam
          instantiates the GolfTip class and stores the instance in the Seam container under the variable name tip.



          Here is the code sample associated with the above:


          <h:form>
          <h3>Do you have golf wisdom to add?</h3>
          <div class="field">
          <h:outputLabel for="author">Author:</h:outputLabel>
          <h:inputText value="#{tip.author}"/>
          </div>
          <div class="field">
          <h:outputLabel for="category">Category:</h:outputLabel>
          <h:selectOneMenu value="#{tip.category}">
          <f:selectItem itemValue="The Swing"/>
          <f:selectItem itemValue="Putting"/>
          <f:selectItem itemValue="Attitude"/>
          </h:selectOneMenu>
          </div>
          <div class="field">
          <h:outputLabel for="content">Advice:</h:outputLabel>
          <h:inputTextarea value="#{tip.content}"/>
          </div>
          <div class="actions">
          <h:commandButton action="#{tipAction.add(tip)}"
          value="Submit Tip"/>
          </div>
          </h:form>




          • 2. Re: Problem testing component for null in rendered attribute
            Ross Johnson Newbie

            Thanks Arbi for your response. The approach of using a boolean in the SFSB was how I managed to make it work, I just don't understand why it is necessary. What use is @Out(required=false) if Seam creates the component regardless.


            For example, this line is the only reference to a rangeProfile entity. (Forget about the DataModel stuff, it's not really relevant).



            <h:outputText value="RP EXISTS" rendered="#{rangeProfile!=null}" />
            



            The following was taken from the server log after the page was requested. The first line is a logging statement I added to the constructor of the RangeProfile entity.


            2009-05-12 10:32:26,043 DEBUG [RangeProfile] (http-localhost%2F127.0.0.1-8080-3) RANGE PROFILE CREATED: RangeProfile<0,>
            2009-05-12 10:32:26,043 DEBUG [org.jboss.seam.contexts.Contexts] (http-localhost%2F127.0.0.1-8080-3) found in conversation context: rangeProfile
            2009-05-12 10:32:26,043 DEBUG [org.jboss.seam.contexts.Contexts] (http-localhost%2F127.0.0.1-8080-3) found in conversation context: rangeProfile
            2009-05-12 10:32:26,043 DEBUG [org.jboss.seam.contexts.Contexts] (http-localhost%2F127.0.0.1-8080-3) found in conversation context: rangeProfile
            2009-05-12 10:32:26,043 DEBUG [org.jboss.seam.contexts.Contexts] (http-localhost%2F127.0.0.1-8080-3) found in conversation context: rangeProfile
            



            All I'm doing is testing for the existence of the component. But the component is being instantiated as a result of the test. I understand that Seam would create the component if I use any of its' methods. This behavior even happens when I use 'not empty rangeProfile' which is designed to test for null (as well as empty collections etc.). Why?