9 Replies Latest reply on Mar 5, 2009 9:53 AM by alan79

    Problem AJAX Rerendering Date selected from rich:calendar

    alan79

      I have problems with a date selected from rich:calendar when ajax rerendering.

      Here is the example code:

      <a4j:outputPanel id="filterOptions" layout="block">
      
       <rich:calendar value="#{timerepHandler.selectedDateStart}"
       rendered="#{timerepHandler.filterOption =='1'}" locale="en"
       popup="true" datePattern="dd.MM.yyyy" showApplyButton="false"
       cellWidth="24px" cellHeight="22px" style="width:200px" />
       <rich:calendar immediate="true" ajaxSingle="false" value="#{timerepHandler.selectedDateEnd}"
       rendered="#{timerepHandler.filterOption =='1'}" locale="en"
       popup="true" datePattern="dd.MM.yyyy" showApplyButton="false"
       cellWidth="24px" cellHeight="22px" style="width:200px" />
      
       <h:inputText value="#{timerepHandler.selectedDateStart}" />
       <h:inputText value="#{timerepHandler.selectedDateEnd}" />
      
       <a4j:commandButton value="Refresh List" reRender="test123"
       action="#{timerepHandler.getReportList}" />
      
       <h:panelGrid id="test123">
       <h:outputText value="#{timerepHandler.selectedDateStart}" />
       <h:outputText value="#{timerepHandler.selectedDateEnd}" />
       </h:panelGrid>
       </a4j:outputPanel>
      


      1. In the outputPanel "filterOptions" I select a start and a end date.
      Option A: select the date from rich:calendar
      Option B: Enter the date manually in h:inputText

      2. When clicking the a4j:commandButton "RefreshList" the panelGrid "test123" is reRendered.
      3. In the panelGrid "test123" the dates are displayed

      For some reason Option A (rich:calendar) is not working. Option B (inputText) is working perfectly.

      Has anyone a clue why this is not working? Maybe a bug?
      Thank you very much for your help!
      Regards
      Alan

        • 1. Re: Problem AJAX Rerendering Date selected from rich:calenda
          alan79

          I forgot to post the environment info:
          myfaces 1.2.6
          richfaces: 3.3.0
          facelets: 1.1.14

          • 2. Re: Problem AJAX Rerendering Date selected from rich:calenda
            alan79

            I'm still debugging on this issue. I'm now trying to get this to work without rich:calender using normal h:inputText. Now I found out, that rootcause of the issue is about the rendered attribute:
            rendered="#{timerepHandler.filterOption=='1' }"

            This code is not working:

            <h:form>
             <h:panelGrid class="vertical-menu-cell" columnClasses="optionList"
             columns="1" cellspacing="0" cellpadding="0">
             <h:outputText value="Select Filter Option" />
             <h:selectOneRadio value="#{timerepHandler.filterOption }"
             layout="pageDirection">
             <a4j:support event="onclick" reRender="filterOptions" />
             <f:selectItem itemLabel="All open" itemValue="0" />
             <f:selectItem itemLabel="Date Selection" itemValue="1" />
             <f:selectItem itemLabel="Current Month" itemValue="2" />
             <f:selectItem itemLabel="By Project" itemValue="3" />
             </h:selectOneRadio>
             <h:panelGrid id="filterOptions" layout="block">
             <h:panelGrid rendered="#{timerepHandler.filterOption=='1' }">
             <h:inputText value="#{timerepHandler.selectedDateStart}">
             <f:convertDateTime pattern="#{cont.datePattern }" />
             </h:inputText>
             <h:inputText value="#{timerepHandler.selectedDateEnd}">
             <f:convertDateTime pattern="#{cont.datePattern }" />
             </h:inputText>
             </h:panelGrid>
            
             <a4j:commandButton value="Refresh List" reRender="reports"
             action="#{timerepHandler.getReportList}" />
             </h:panelGrid>
             </h:panelGrid>
            
            
            
            
             <h:outputText value="#{timerepHandler.noRecords }" />
            
             <h:panelGrid id="reports">
             <rich:dataTable cellpadding="0" cellspacing="0" width="640"
             border="0" binding="#{timerepHandler.dataTable}" var="record"
             value="#{timerepHandler.reportList}" sortable="true"
             headerClass="richTableColumnHeader">
             <a4j:support event="onRowClick" onsubmit="changeColor(this)"
             ajaxSingle="true">
             <f:param name="currentRow" value="#{record.reportId}" />
             </a4j:support>
             <f:facet name="header">
             <rich:columnGroup>
             <rich:column rowspan="1" colspan="1" rendered="false">
             <h:outputText value="#{cont.lblReportId}" />
             </rich:column>
             <rich:column rowspan="1" colspan="1">
             <h:outputText value="" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportStart}" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportEnd}" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportCustomer}" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportProject}" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportHours}" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportStatus}" />
             </rich:column>
             </rich:columnGroup>
             </f:facet>
             <rich:column colspan="1" rendered="false">
             <h:outputText value="#{record.projectId}" />
             </rich:column>
             <rich:column colspan="1">
             <h:commandLink id="editProjectPic" styleClass="linkPic"
             action="#{timerepHandler.editReportRecord }">
             <h:graphicImage styleClass="linkPic" title="edit" alt="edit"
             url="#{facesContext.externalContext.requestContextPath}/../images/record_edit.png" />
             </h:commandLink>
            
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value="#{record.start}">
             <f:convertDateTime pattern="#{cont.dateTimePattern }" />
             </h:outputText>
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value="#{record.end}">
             <f:convertDateTime pattern="#{cont.dateTimePattern }" />
             </h:outputText>
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value="#{record.projects.company.name}" />
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value="#{record.projects.projectName}" />
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value=" #{record.totalHours}" />
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value="#{record.status}" />
             </rich:column>
             </rich:dataTable>
             </h:panelGrid>
            
             </h:form>
            
            


            This code is working:
            <h:form>
             <h:panelGrid class="vertical-menu-cell" columnClasses="optionList"
             columns="1" cellspacing="0" cellpadding="0">
             <h:outputText value="Select Filter Option" />
             <h:selectOneRadio value="#{timerepHandler.filterOption }"
             layout="pageDirection">
             <a4j:support event="onclick" reRender="filterOptions" />
             <f:selectItem itemLabel="All open" itemValue="0" />
             <f:selectItem itemLabel="Date Selection" itemValue="1" />
             <f:selectItem itemLabel="Current Month" itemValue="2" />
             <f:selectItem itemLabel="By Project" itemValue="3" />
             </h:selectOneRadio>
             <h:panelGrid id="filterOptions" layout="block">
             <h:panelGrid>
             <h:inputText value="#{timerepHandler.selectedDateStart}">
             <f:convertDateTime pattern="#{cont.datePattern }" />
             </h:inputText>
             <h:inputText value="#{timerepHandler.selectedDateEnd}">
             <f:convertDateTime pattern="#{cont.datePattern }" />
             </h:inputText>
             </h:panelGrid>
            
             <a4j:commandButton value="Refresh List" reRender="reports"
             action="#{timerepHandler.getReportList}" />
             </h:panelGrid>
             </h:panelGrid>
            
            
            
            
             <h:outputText value="#{timerepHandler.noRecords }" />
            
             <h:panelGrid id="reports">
             <rich:dataTable cellpadding="0" cellspacing="0" width="640"
             border="0" binding="#{timerepHandler.dataTable}" var="record"
             value="#{timerepHandler.reportList}" sortable="true"
             headerClass="richTableColumnHeader">
             <a4j:support event="onRowClick" onsubmit="changeColor(this)"
             ajaxSingle="true">
             <f:param name="currentRow" value="#{record.reportId}" />
             </a4j:support>
             <f:facet name="header">
             <rich:columnGroup>
             <rich:column rowspan="1" colspan="1" rendered="false">
             <h:outputText value="#{cont.lblReportId}" />
             </rich:column>
             <rich:column rowspan="1" colspan="1">
             <h:outputText value="" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportStart}" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportEnd}" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportCustomer}" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportProject}" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportHours}" />
             </rich:column>
             <rich:column rowspan="2" colspan="2">
             <h:outputText value="#{cont.lblReportStatus}" />
             </rich:column>
             </rich:columnGroup>
             </f:facet>
             <rich:column colspan="1" rendered="false">
             <h:outputText value="#{record.projectId}" />
             </rich:column>
             <rich:column colspan="1">
             <h:commandLink id="editProjectPic" styleClass="linkPic"
             action="#{timerepHandler.editReportRecord }">
             <h:graphicImage styleClass="linkPic" title="edit" alt="edit"
             url="#{facesContext.externalContext.requestContextPath}/../images/record_edit.png" />
             </h:commandLink>
            
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value="#{record.start}">
             <f:convertDateTime pattern="#{cont.dateTimePattern }" />
             </h:outputText>
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value="#{record.end}">
             <f:convertDateTime pattern="#{cont.dateTimePattern }" />
             </h:outputText>
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value="#{record.projects.company.name}" />
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value="#{record.projects.projectName}" />
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value=" #{record.totalHours}" />
             </rich:column>
             <rich:column colspan="2">
             <h:outputText value="#{record.status}" />
             </rich:column>
             </rich:dataTable>
             </h:panelGrid>
            
             </h:form>
            


            The only difference is the rendered attribute on this line:
            <h:panelGrid rendered="#{timerepHandler.filterOption=='1' }">
             <h:inputText value="#{timerepHandler.selectedDateStart}">
             <f:convertDateTime pattern="#{cont.datePattern }" />
             </h:inputText>
             <h:inputText value="#{timerepHandler.selectedDateEnd}">
             <f:convertDateTime pattern="#{cont.datePattern }" />
             </h:inputText>
             </h:panelGrid>
            


            Please any help is appreciated. I would love to make use of AJAX intensively, but to me it seems to work very buggy at the moment? Or do you just use it the wrong way. Thank you for your support!
            Regards
            Alan

            • 3. Re: Problem AJAX Rerendering Date selected from rich:calenda
              alan79

              I would like to clearify one thing:

              The problem is that the value of
              - #{timerepHandler.selectedDateStart}
              - #{timerepHandler.selectedDateEnd}
              is always the default value.

              Field changes are not processed correctly on ajax rerendering. As soon as the mentioned "rendered" attribute is removed everything works perfectly!

              • 4. Re: Problem AJAX Rerendering Date selected from rich:calenda
                nbelaevski

                Is timerepHandler bean request-scoped?

                • 5. Re: Problem AJAX Rerendering Date selected from rich:calenda
                  alan79

                   

                  "nbelaevski" wrote:
                  Is timerepHandler bean request-scoped?

                  Yes. timerepHandler bean is request scoped.

                  • 6. Re: Problem AJAX Rerendering Date selected from rich:calenda
                    alan79

                     

                    "nbelaevski" wrote:
                    Is timerepHandler bean request-scoped?

                    Hi Nick.
                    I found the case RF-3154 (https://jira.jboss.org/jira/browse/RF-3154?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel) that seems to describe this behaviour. I changed now the scope of the bean to "session" and it is working now.

                    So do I understand it correctly? The main issue is that jsf is not binding components to the backing bean that aren't rendered. This means that every page containing ajax hide/display functionality needs to be managed by a session-scoped bean.

                    What is the impact for the whole application? I mean is it a good idea to have many session-scope beans?

                    Thank you very much for your hint. At least is is working now!
                    Rgds
                    Alan

                    • 7. Re: Problem AJAX Rerendering Date selected from rich:calenda
                      nbelaevski

                      Hi Alan,

                      JSF stops request processing for the components that are not rendered. And it doesn't store value for #{...} attribute, but an expression; so on the sequential submit the expression is re-evaluated again and now it's false. It's very common issue.

                      Solutions:

                      1. Use session-scoped beans
                      2. Seam conversation
                      3. a4j:keepAlive
                      4. State Manager API: http://livedemo.exadel.com/richfaces-demo/richfaces/stateAPI.jsf?c=stateAPI&tab=usage

                      • 8. Re: Problem AJAX Rerendering Date selected from rich:calenda
                        alan79

                        Hi Nick
                        Thank you very much for your answer.

                        "nbelaevski" wrote:

                        1. Use session-scoped beans
                        2. Seam conversation
                        3. a4j:keepAlive
                        4. State Manager API: http://livedemo.exadel.com/richfaces-demo/richfaces/stateAPI.jsf?c=stateAPI&tab=usage


                        I wish I would have integrated Seam at the beginning. It seems to be a lot of work afterwords..!?
                        I tried to use a4j:keepAlive but I got a lot of serialization exceptions. State Manager seems to be pretty complicated to me. Therefore I try to continue with the session beans.

                        Regards
                        Alan

                        • 9. Re: Problem AJAX Rerendering Date selected from rich:calenda
                          alan79

                          <t:saveState value="#{timerepHandler.selectedDateStart} "/>
                          <t:saveState value="#{timerepHandler.selectedDateEnd} "/>
                          did the trick!!! No session beans necessary anymore!