1 2 Previous Next 15 Replies Latest reply on Oct 21, 2013 4:35 AM by liuliu

    Disabling rendering in case of empty data table does not work as expected

    tomhain

      I'm wondering why the attribute "rendered="#not empty..." does not work as expected.

       

      I have the following JSF Code:

       

      .....
      <!-- Following message gets always displayed (even if participations.size() > 0): -->
              
              <h:panelGroup rendered="#{empty participations}">
                  <em>No items available</em>
              </h:panelGroup>
      
      <!-- By adding 'rendered="#{not empty participations}"' in h:dataTable => Effect: even when table is not empty the wholetable is not displayed! -->
      
              <h:dataTable var="_participation" value="#{participations}"
                           styleClass="simpletablestyle"
                           id="participationTable">
      <!--                rendered="#{not empty participations}" -->
                  
                  <h:column>
                      <f:facet name="header">Datum</f:facet>
                          #{_participation.trainingItem.trainingDateAsString}
                  </h:column>
            
                  <h:column>
                      <f:facet name="header">Spieler</f:facet>
                      #{_participation.player.name}, #{_participation.player.firstname}
                  </h:column>        
              </h:dataTable>
      .....
      

       

      Two things I really do not understand:

      1) "No items available" gets always displayed, even when the size of the list "participations" is "0".

      2) When I add the attribute rendered in the dataTable with value "#{not empty participations} the table gets never displayed - even if the table has elements (participations.size() > 0

      In the above example the table gets displayed even if it is empty (showing just the Header). This should not happen. Instead: only if the "participations" list is empty the text "No items available" should be displayed. In the other case, the data table should be displayed

       

      I struggled already a long time with that and can't find the error myself. So, thanks for your help!

        • 1. Re: Disabling rendering in case of empty data table does not work as expected
          liuliu

          could you show your backing bean code?

          • 2. Re: Re: Disabling rendering in case of empty data table does not work as expected
            tomhain

            This is the relevant part of the Backing Bean:

             

            @RequestScoped
            @Named
            public class ParticipationListProducer {
            
                @Inject
                private ParticipationRepository participationRepository;
            
                @Inject
                private Logger log;
            
                private List<Participation> participations;
            
                private Date trainingDate = new Date();
                
                
                @Produces
                @Named
                public List<Participation> getParticipations() {
                    log.info("GetParticipations called " + participations.size() + " Elements");
                    return participations;
                }
                
                public void setTrainingDate(Date x) {
                    trainingDate = x;
                    retrieveAllParticipators();
                }
            
                public Date getTrainingDate() {
                    return trainingDate;
                }
            
                @PostConstruct
                public void retrieveAllParticipators() {
                    participations = participationRepository.getAllForSpecificDateOrderedByName(trainingDate);
                }
            ...
            
            • 3. Re: Disabling rendering in case of empty data table does not work as expected
              rhanus

              your code should work as you expect:

              tag with attribute rendered="#{empty participations}" is displayed when either participations is null or the collection is empty

              rendered="#{not empty participations}" has opposite meaning

               

              doublecheck your bean code or did you experience any re-rendering problems ?

              • 4. Re: Disabling rendering in case of empty data table does not work as expected
                liuliu

                I dont know how @produces works, probably  the FIRST time "participations" called for rendered, it is empty.

                • 5. Re: Disabling rendering in case of empty data table does not work as expected
                  tomhain

                  Well, I expected the described behaviour as well - but it is still not working. Honestly, I doublechecked my bean code several times. I can't see the issue. The bean deliveres the correct size of the collection to the jsf page. I don't think, the issue is because of my backing bean.

                   

                  The page itself gets displayed correctly (besides the empty data table). What do you mean by re-rendering problems? How can I recognize the same ? Is there a way to debug the client side code execution ?

                  • 6. Re: Disabling rendering in case of empty data table does not work as expected
                    liuliu

                    Could you try to replace participations with participationListProducer.participations?

                    • 7. Re: Disabling rendering in case of empty data table does not work as expected
                      rhanus

                      in your bean code the list of participants is produced only once at very beginning of bean lifecycle into the jsf page

                      when training date is updated the list is not updated anyway

                      liumin is propably right try to replace producer method with common getter

                      • 8. Re: Disabling rendering in case of empty data table does not work as expected
                        tomhain

                        I tried replacing participations by participationListProducer.participations and removed the @Produces annotiation. Same result :-(

                        • 9. Re: Disabling rendering in case of empty data table does not work as expected
                          liuliu

                          I did the same test, manuelly  creat the list  in retrieveAllParticipators. your code works with getter.

                          • 10. Re: Disabling rendering in case of empty data table does not work as expected
                            tomhain

                            Thanks for your time you spend on answering my question. However, it is still not working as expected. I really don't know why. I am currently reducing the code step by step to encapsulate the problem area...

                            • 11. Re: Re: Disabling rendering in case of empty data table does not work as expected
                              tomhain

                              Hi Radim,

                              Radim Hanus schrieb:

                               

                              in your bean code the list of participants is produced only once at very beginning of bean lifecycle into the jsf page

                              when training date is updated the list is not updated anyway

                              liumin is propably right try to replace producer method with common getter

                              I did not copy the whole JSF in the discussion - for purposes of clarity.

                               

                              Here is the relvant sourcecode , which updates the table:

                              <rich:calendar  id="trainingCalendar"
                                              mode="ajax" 
                                              popup="false"
                                              boundaryDatesMode="scroll" 
                                              locale="de/DE"
                                              buttonLabel="Heute"
                                              datePattern="dd.MM.yyyy"  
                                              dataModel="#{calendarModel}" 
                                              value="#{participationListProducer.trainingDate}">
                                  <a4j:ajax event="change" render="trainingDate_output participationTable participationAttributes_output popup" />
                              </rich:calendar>
                              

                               

                              This works, the table gets updated whenever the date is changed.

                              • 12. Re: Re: Re: Disabling rendering in case of empty data table does not work as expected
                                tomhain

                                This is the whole source code, now:

                                 

                                JSF:

                                <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                                <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                                                xmlns:ui="http://java.sun.com/jsf/facelets"
                                                xmlns:f="http://java.sun.com/jsf/core"
                                                xmlns:h="http://java.sun.com/jsf/html"
                                                template="/WEB-INF/templates/default.xhtml"
                                                xmlns:a4j="http://richfaces.org/a4j"
                                                xmlns:rich="http://richfaces.org/rich">
                                    <ui:define name="content">
                                        <h2>Trainingskalender:</h2>
                                        <h:outputStylesheet>
                                            .tdc {
                                            background-color: green;
                                            }
                                            .wdc {
                                            font-weight: bold;
                                            font-style: italic;
                                            }
                                        </h:outputStylesheet>
                                        <h:form>
                                            <rich:calendar id="trainingCal"
                                                           mode="ajax" 
                                                           popup="false"
                                                           boundaryDatesMode="scroll" 
                                                           locale="de/DE"
                                                           buttonLabel="Heute"
                                                           datePattern="dd.MM.yyyy"
                                                           dataModel="#{calendarModel}" 
                                                           value="#{participationListProducer.trainingDate}">
                                                <a4j:ajax event="change" render="output participationTable" />
                                            </rich:calendar>
                                        </h:form>
                                        <h2><h:outputText id="output" value="#{calendarModel.selectedDate}" /> </h2>
                                
                                        <h:panelGroup rendered="#{empty participationListProducer.participations}">  
                                            <em>No items available</em>  
                                        </h:panelGroup>  
                                  
                                        <h:dataTable var="_participation" value="#{participationListProducer.participations}"  
                                                     styleClass="simpletablestyle"  
                                                     rendered="#{not empty participationListProducer.participations}" 
                                                     id="participationTable">  
                                              
                                            <h:column>  
                                                <f:facet name="header">Datum</f:facet>  
                                                    #{_participation.trainingItem.trainingDateAsString}  
                                            </h:column>  
                                        
                                            <h:column>  
                                                <f:facet name="header">Spieler</f:facet>  
                                                #{_participation.player.name}, #{_participation.player.firstname}  
                                            </h:column>          
                                        </h:dataTable>  
                                    </ui:define>
                                </ui:composition>
                                
                                
                                

                                 

                                And this is code of the Backing Bean:

                                 

                                @RequestScoped
                                @Named
                                public class ParticipationListProducer {
                                
                                    @Inject
                                    private ParticipationRepository participationRepository;
                                
                                    @Inject
                                    private Logger log;
                                
                                    private List<Participation> participations;
                                
                                    private Date trainingDate = new Date();
                                    
                                    private int numberOfParticipators;
                                    
                                    private int numberOfDriversBack;
                                    
                                    private int numberOfDriversForth;
                                    
                                    private int numberOfSeatsForthAvailable;
                                    
                                    private int numberOfSeatsBackAvailable;
                                    
                                    private int numberOfSeatsBackRequired;
                                    
                                    private int numberOfSeatsForthRequired;
                                    
                                    public int getNumberOfParticipators() {
                                        return numberOfParticipators;
                                    }
                                    
                                    public int getNumberOfDriversBack() {
                                        return numberOfDriversBack;
                                    }
                                    
                                    public int getNumberOfDriversForth() {
                                        return numberOfDriversForth;
                                    }
                                    
                                    public int getNumberOfSeatsBackRequired() {
                                        log.info("return numberOfSeatsBackRequired" + numberOfSeatsBackRequired);
                                        return numberOfSeatsBackRequired;
                                    }
                                    
                                    public int getNumberOfSeatsForthRequired() {
                                        log.info("return numberOfSeatsForthRequired=" + numberOfSeatsForthRequired);
                                        return numberOfSeatsForthRequired;
                                    }
                                
                                    public int getNumberOfSeatsBackAvailable() {
                                        return numberOfSeatsBackRequired;
                                    }
                                    
                                    public int getNumberOfSeatsForthAvailable() {
                                        return numberOfSeatsForthRequired;
                                    }
                                
                                    public List<Participation> getParticipations() {
                                        log.info("GetParticipations called " + participations.size() + " Elements");
                                        return participations;
                                    }
                                    
                                    public void setTrainingDate(Date x) {
                                        trainingDate = x;
                                        retrieveAllParticipators();
                                    }
                                
                                    public Date getTrainingDate() {
                                        return trainingDate;
                                    }
                                
                                    public String getTrainingDateAsFormattedString() {
                                        return DateUtil.getSelectedDateAsFormattedString(trainingDate);
                                    }
                                
                                    
                                    @PostConstruct
                                    public void retrieveAllParticipators() {
                                        participations = participationRepository.getAllForSpecificDateOrderedByName(trainingDate);
                                        calculateParticipationAttributes();
                                    }
                                
                                    private void calculateParticipationAttributes() {
                                        numberOfParticipators = 0;
                                        for (Participation p : participations) {
                                            log.info(" Just read -> " + p.getId() + "; " + p.getTrainingItem().getCurrentDate());
                                            if (p.isParticipating())
                                                numberOfParticipators++;
                                            if (p.isDrivingBack())
                                                numberOfSeatsBackAvailable = numberOfDriversBack + p.getPlayer().getCarsize();
                                            if (p.isDrivingForth())
                                                numberOfSeatsForthAvailable = numberOfDriversForth + p.getPlayer().getCarsize();
                                        }
                                        numberOfSeatsBackRequired = numberOfParticipators - numberOfSeatsBackAvailable;
                                        numberOfSeatsForthRequired = numberOfParticipators - numberOfSeatsForthAvailable;
                                    }
                                }
                                

                                 

                                 

                                @Liumin: Do you see a diffference to your code ? Tx.

                                • 13. Re: Re: Re: Re: Disabling rendering in case of empty data table does not work as expected
                                  liuliu

                                  not big difference except you creat your list with database, i creat it myself. here is my code, very simple.

                                   

                                  @Named
                                  @RequestScoped
                                  public class TestBean implements Serializable{
                                  
                                      private static final long serialVersionUID = 4934630753831928437L;
                                      private static Log logger = LogFactory.getLog(TestBean.class);
                                      
                                      private List<String> header=new ArrayList<String>();
                                      
                                    @PostConstruct
                                      public void init(){
                                  //        this.header.add("header1");
                                  //        this.header.add("header2");
                                      }
                                      
                                      public List<String> getHeader() {
                                          return this.header;
                                      }
                                  }
                                  

                                   

                                  xhml

                                   

                                  <rich:dataTable rendered="#{not empty testBean.header}" value="#{testBean.header}" var="head">
                                  <rich:column >
                                        #{head}
                                  </rich:column>
                                  </rich:dataTable>
                                  

                                   

                                  BTW I use mojarra 2.1.25

                                  • 14. Re: Re: Re: Re: Disabling rendering in case of empty data table does not work as expected
                                    tomhain

                                    Your code works as expected in my container as well. This is strange, I can't see the big difference to my code and I really don't understand why the 'empty' keyword does not work in my code...

                                    I use jboss-jsf-api 2.1, spec. 2.0.9.

                                    1 2 Previous Next