9 Replies Latest reply on Oct 24, 2013 10:27 PM by Brian Leathem

    setPropertyActionListener not invoked

    Tom Hain Newbie

      Hi,

       

      My JSF Page shows a dataTable and I'd like to open popup a window whenever the user clicks on a "Change" Button which is part of each row. The popup should show the details of the selected row.

      I used the showCase Example http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=dataTable&sample=dataTableEdit&skin=blueSky of RichFaces as a basis.

      However, something seems to be wrong, because the pop up does not show the details of the row. Somehow, the Backing Bean does not get initialized corretly (setter method not called) and the data is not propagated from the parent data table to the pop up window. From my understanding, this is the job of the setPropertyActionListener Method.

       

      I think these are the relevant parts:

       

      JSF:

      <h:form>
                  <rich:dataTable var="_participation" value="#{participations}"
                               styleClass="simpletablestyle"
                               iterationStatusVar="it"
                               id="participationTable">
      
                      <rich:column>
                          <f:facet name="header">Player</f:facet>
                          #{_participation.player.name}, #{_participation.player.firstname}
                      </rich:column> 
                      <rich:column>
                          <f:facet name="header">Drives Back</f:facet>
                          <h:selectBooleanCheckbox value="#{_participation.drivingBack}" readonly="true"/>
                      </rich:column>
      <!-- The command link to open the pop up with details -->
                      <rich:column>
                          <a4j:commandLink styleClass="no-decor" render="editGrid" execute="@this"
                               onclick="#{rich:component('editPane')}.show()">
                               <h:graphicImage value="/resources/icons/edit.gif" alt="edit" />
                               <a4j:param value="#{it.index}" assignTo="#{participationController.currentParticipationIndex}" />
                               <f:setPropertyActionListener target="#{participationController.editedParticipation}" value="#{_participation}" />
                           </a4j:commandLink>
                      </rich:column>
                  </rich:dataTable>
      
      <!-- The Pop Up -->            
              <rich:popupPanel header="Edit" id="editPane" domElementAttachment="parent" width="400" height="170">
                  <h:panelGrid columns="3" id="editGrid">
                      <h:outputText value="Id" />
                      <h:outputText value="#{participationController.currentParticipationIndex}" />
                      <h:panelGroup />
                      <h:outputText value="Teilnahme" />
                      <h:outputText value="#{participationController.editedParticipation.participating}" />
                      <h:panelGroup />
                      <h:outputText value="Spieler" />
                      <h:outputText value="#{participationController.editedParticipation.player.firstname}" />
                  </h:panelGrid>
      
                  <a4j:commandButton value="Store" action="#{participationController.update}" render="table" execute="editPane"
                      oncomplete="if (#{facesContext.maximumSeverity==null}) {#{rich:component('editPane')}.hide();}" />
                  <a4j:commandButton value="Cancel" onclick="#{rich:component('editPane')}.hide(); return false;" />
              </rich:popupPanel>
      
              </h:form>
      

       

      This is my ManagedBean:

       

      @ManagedBean(name = "participationController")
      @ViewScoped
      public class ParticipationController implements Serializable {
      
          @Inject
          private Logger log;
         
      
          private Participation editedParticipation;
          
      
          /**
           * @return the editedParticipation
           */
          public Participation getEditedParticipation() {
              return editedParticipation;
          }
      
          /**
           * @param editedParticipation the editedParticipation to set
           */
          public void setEditedParticipation(Participation changedParticipation) {
              log.info("setEditedParticipation " + changedParticipation); // never written to log file!
              this.editedParticipation = changedParticipation;
          }
      
      }
      

       

      I Hope somebody can see the isse and give me a hint. Thanks!

        • 1. Re: setPropertyActionListener not invoked
          Brian Leathem Master

          Is this related to validation failures, as in the known issue?

          https://issues.jboss.org/browse/RF-11413

          • 2. Re: setPropertyActionListener not invoked
            Tom Hain Newbie

            Thanks, but I don't think so. I do not use any validation and the value is even not displayed in the pop up window for the very first time. The target of  'setPropertyActionListener' is not called. This is the reason, but I do not know why the propertyActionListener is not invoked.

             

            I changed in the meanwhile from "onclick" to "oncomplete" (this is the only difference to the showcase example) but the popup will even not be opened :-(

             

            1. <a4j:commandLink styleClass="no-decor" render="editGrid" execute="@this" 
            2. onclick="#{rich:component('editPane')}.show()">

            to

            1. <a4j:commandLink styleClass="no-decor" render="editGrid" execute="@this" 
            2.                          oncomplete="#{rich:component('editPane')}.show()">
            • 3. Re: setPropertyActionListener not invoked
              Brian Leathem Master

              Can you try setting domElementAttachment to form?

              • 4. Re: setPropertyActionListener not invoked
                Tom Hain Newbie

                I tried the same. No change: same result.

                 

                I am wondering why participationController.setEditedParticipation() is not called with value of _participation (which is the current item of the dataTable). Should this not be the case with the following statement:

                <f:setPropertyActionListener target="#{participationController.editedParticipation}" value="#{_participation}" />

                • 5. Re: setPropertyActionListener not invoked
                  Brian Leathem Master

                  Given that it works in the showcase, I'd try starting with the showcase code as-it-is (or as close as is possible) and make small changes from there to your current impl, seeing at what point it breaks along the way.

                   

                  Also, please share what container you are running in, as well as the implementation and version of JSF you are using.

                  • 6. Re: Re: setPropertyActionListener not invoked
                    Tom Hain Newbie

                    Hi Brian,

                     

                    I use JBoss AS 7.1.1 and the JBoss JSF Implementation 2.0.9.

                    Honestly, I don't think it is because of different containers we are using. It is more a bug I produced myself..

                     

                    Well, I have a suspicion..:

                    I posted only the relevant parts of my source code (what I thought are the relevant parts) , because I didn't want to confuse everybody with to much source code ;-). Now, I'd like to share the whole source code with you because there must be somewehere else a bug I cannot find. I guess something else causes the effect I am now asking for an idea. Actually, I guess some ui components gets rendered which should not be rendered.

                     

                    The following xhtml page shows a calendar component and a data table initially. Whenever the user selects a date, a JPA query gets executed with the date as filter criteria. The datatable gets updated and rendered again. So far so good. This works as expected.

                     

                    Now, I observed that the datatable gets rendered again when the user clicks on the command link to edit the selected row. And this should not be the case. Because this event loads the data again, but not for the selected date. It loads the data for the current date which is wrong! This jpa query, returns no result! So, I guess the empty data gets propagated via setpropertyActionListener and that is the reason for displaying no data in the popup panel. However, I can't explain why the log message of participationController.setEditedParticipation() will not be logged.

                     

                    Any ideas on that ?

                     

                    Here is the whole source code:

                     

                    xhtml:

                     

                    <?xml version="1.0" encoding="UTF-8"?>
                    
                    <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>Calendar:</h2>
                            <h:outputStylesheet>
                                .tdc {
                                background-color: green;
                                }
                                .wdc {
                                font-weight: bold;
                                font-style: italic;
                                }
                                .even-row {
                                background-color: #FCFFFE;
                                }
                                .odd-row {
                                background-color: #ECF3FE;
                                }
                                .active-row {
                                background-color: #FFEBDA !important;
                                cursor: pointer;
                                }
                            </h:outputStylesheet>
                    
                            <h:form id="calendar_form">
                                <rich:calendar id="trainingCalendar"
                                              mode="ajax"
                                              popup="false"
                                              boundaryDatesMode="scroll"
                                              locale="de/DE"
                                              buttonLabel="Heute"
                                              datePattern="dd.MM.yyyy" 
                                              dataModel="#{calendarModel}"
                                              value="#{participationListProducer.trainingDate}"
                                              valueChangeListener="#{participationListProducer.trainingDateChanged}">
                                    <a4j:ajax event="change" render="trainingDate_output participation_table participationAttributes_output" />
                                </rich:calendar>
                            </h:form>   
                            <h:outputText id="trainingDate_output" value="Training on #{participationListProducer.trainingDateAsFormattedString}:" />
                    
                            <h:form id="table_form">
                                <rich:dataTable var="_participation" value="#{participationListProducer.participations}"
                                                iterationStatusVar="it"
                                                id="participation_table"
                                                rowClasses="odd-row, even-row"
                                                styleClass="stable">
                                    <rich:column>
                                        <f:facet name="header">Player</f:facet>
                                        #{_participation.player.name}, #{_participation.player.firstname}
                                    </rich:column>
                                    <rich:column>
                                        <f:facet name="header">Participates</f:facet>
                                        <h:selectBooleanCheckbox value="#{_participation.participating}" readonly="true"/>
                                    </rich:column>
                                    <rich:column>
                                        <f:facet name="header">Drives Forth</f:facet>
                                        <h:selectBooleanCheckbox value="#{_participation.drivingForth}"  readonly="true"/>
                                    </rich:column>
                                    <rich:column>
                                        <f:facet name="header">Drives Back</f:facet>
                                        <h:selectBooleanCheckbox value="#{_participation.drivingBack}" readonly="true"/>
                                    </rich:column>
                                    <rich:column>
                                        <a4j:commandLink styleClass="no-decor" render="editGrid" execute="@this"
                                                        onclick="#{rich:component('editPane')}.show()">
                    
                                            <h:graphicImage value="/resources/icons/edit.gif" alt="edit" />
                                            <a4j:param value="#{it.index}" assignTo="#{participationController.currentParticipationIndex}" />
                                            <f:setPropertyActionListener target="#{participationController.editedParticipation}" value="#{_participation}" />
                                        </a4j:commandLink>
                                    </rich:column>
                                </rich:dataTable>
                    
                                <rich:popupPanel header="Edit Participation" id="editPane" domElementAttachment="parent" width="400" height="170">
                                    <h:panelGrid columns="3" id="editGrid">
                                        <h:outputText value="Id" />
                                        <h:outputText value="#{participationController.currentParticipationIndex}" />
                                        <h:panelGroup />
                                        <h:outputText value="Teilnahme" />
                                        <h:outputText value="#{participationController.editedParticipation.participating}" />
                                        <h:panelGroup />
                                        <h:outputText value="Spieler" />
                                        <h:outputText value="#{participationController.editedParticipation.player.firstname}" />
                                    </h:panelGrid>
                    
                                    <a4j:commandButton value="Store" action="#{participationController.updateParticipation()}" render="participation_table" execute="editPane"
                                                      oncomplete="if (#{facesContext.maximumSeverity==null}) {#{rich:component('editPane')}.hide();}" />
                                    <a4j:commandButton value="Cancel" onclick="#{rich:component('editPane')}.hide();
                                                                return false;" />
                                </rich:popupPanel>
                    
                            </h:form>
                            <rich:jQuery selector=".stable tr:odd" query="addClass('odd-row')" />
                            <rich:jQuery selector=".stable tr:even" query="addClass('even-row')" />
                            <rich:jQuery selector=".stable tr" event="mouseover" query="jQuery(this).addClass('active-row')" />
                            <rich:jQuery selector=".stable tr" event="mouseout" query="jQuery(this).removeClass('active-row')" />
                    
                            <h:panelGrid id="participationAttributes_output" >
                                <h:outputText value="#{participationListProducer.numberOfSeatsForthRequired} Seats required Forth!"
                                              rendered="#{participationListProducer.numberOfSeatsForthRequired > 0}"/>
                    
                                <h:outputText value="#{participationListProducer.numberOfSeatsBackRequired} Seats required back!"
                                              rendered="#{participationListProducer.numberOfSeatsBackRequired > 0}"/>
                                <h:outputText value="#{participationListProducer.numberOfParticipators} Participations of training"/>
                            </h:panelGrid>
                    
                        </ui:define>
                    
                    </ui:composition>
                    

                     

                    Bean Code:

                     

                    @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) {
                            log.info("setTrainingDate called " + x.toString());
                            trainingDate = x;
                        }
                    
                        public void trainingDateChanged(ValueChangeEvent event) {
                            log.info("trainingDateChanged called !");
                            if (event.getNewValue() != null) {
                                log.info("New TrainingDate = " + event.getNewValue());
                                trainingDate = (Date) event.getNewValue();
                                retrieveAllParticipators();
                                calculateParticipationAttributes();
                            }
                        }
                    
                        public Date getTrainingDate() {
                            return trainingDate;
                        }
                    
                        public String getTrainingDateAsFormattedString() {
                            return DateUtil.getSelectedDateAsFormattedString(trainingDate);
                        }
                    
                        
                        @PostConstruct
                        public void retrieveAllParticipators() {
                            log.info("retrieveAllParticipators for " + trainingDate.toString());
                            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;
                    
                            log.info("Calculated NumberOfSeatsBackRequired = " + numberOfSeatsBackRequired);
                            log.info("Calculated NumberOfSeatsForthRequired = " + numberOfSeatsForthRequired);
                            log.info("Calculated NumberOfParticipators = " + numberOfParticipators);
                    
                        }
                    }
                    
                    • 7. Re: Re: Re: setPropertyActionListener not invoked
                      Tom Hain Newbie

                      The participationListProducer (code-snippet above) is just for filling the datatable. The source code of the relevant Bean (ParticipationController) is in the initial post. This information is just for the completness. Does anybody has an idea why the setPropertyActionListener is not invoked ? (Find below the important piece of code)



                      <f:setPropertyActionListener target="#{participationController.editedParticipation}" value="#{_participation}" />  
                      

                       

                       

                      @ManagedBean(name = "participationController")
                      @ViewScoped
                      public class ParticipationController implements Serializable {
                      
                      // snipp (getter, setter..)
                      
                      
                      public void setEditedParticipation(Participation changedParticipation)
                           log.info("setEditedParticipation " + changedParticipation);
                           this.editedParticipation = changedParticipation;
                      }
                      

                       

                      Many thanks in advance!!

                      • 8. Re: Re: Re: Re: setPropertyActionListener not invoked
                        Tom Hain Newbie

                        Even the paramValue is not assigned to the bean property , because my entry in the logfile is not written

                         

                        1.                 <a4j:commandLink styleClass="no-decor" render="editGrid" execute="@this" 
                        2.                                     onclick="#{rich:component('editPane')}.show()"> 
                        3.                         <h:graphicImage value="/resources/icons/edit.gif" alt="edit" /> 
                        4.                         <a4j:param value="#{it.index}" assignTo="#{participationController.currentParticipationIndex}" /> 
                        5.                         <f:setPropertyActionListener target="#{participationController.editedParticipation}" value="#{_participation}" /> 
                        6.                     </a4j:commandLink> 
                        7.    

                         

                        It should just call the corresponding setter - but it does not work..

                        @ManagedBean(name = "participationController")
                        @ViewScoped
                        public class ParticipationController implements Serializable {
                        
                        //...
                            private int currentParticipationIndex;
                        
                            public void setCurrentParticipationIndex(int currentParticipationIndex) {
                                log.info("setCurrentParticipationIndex called with " + currentParticipationIndex);
                                this.currentParticipationIndex = currentParticipationIndex;
                            }
                        //...
                        }
                        

                         

                        I have really no idea anymore and would be glad if somebody could help me on that...Thanks in advance!

                        • 9. Re: setPropertyActionListener not invoked
                          Brian Leathem Master

                          At this point, I'd suggest you file a jira issue with a http://sscce.org/http://sscce.org/ reproducer and we can take a closer look at what is going on.