6 Replies Latest reply on Aug 29, 2007 9:43 AM by fhagen

    a4j:repeater should refresh himself

    fhagen

      Hi,

      i'm very new to jsf and ajax4jsf and therefor i got some problems using the a4j:repeater.

      In my little testapp i'm using a repeater this way:

      <h:form id="form">
      <table>
       <tr>
       <th>Description</th>
       <th>2004</th>
       <th>2005</th>
       </tr>
       <a4j:repeat id="poslist" value="#{positionBean.positions}" var="pos">
       <tr>
       <td><h:outputText id="posdesc" value="#{pos.description}"/></td>
       <td><h:inputText id="posvalue04" value="#{pos.output[0]}">
       <a4j:support event="onclick" reRender="posvalue04"
       focus="posvalue04" action="#{pos.showFormula}"/>
       <a4j:support event="onchange" reRender="poslist"
       action="#{positionBean.calculateAction}"/>
       </h:inputText>
       </td>
       <td><h:inputText id="posvalue05" value="#{pos.output[1]}">
       <a4j:support event="onclick" reRender="posvalue05"
       action="#{pos.showFormula}"/>
       <a4j:support event="onchange" reRender="poslist"
       action="#{positionBean.calculateAction}"/>
       </h:inputText>
       </td>
       </tr>
       </a4j:repeat>
      </table>
      </h:form>
      


      The values from the bean are being displayed and the events "onclick" and "onchange" are being triggered. So everythings works fine so far.

      The "onchange" event should update the whole repeater but it doesn't.
      I read something about the "ajaxkeys" but don't know how to use them?

      Fabian

        • 1. Re: a4j:repeater should refresh himself
          ilya_shaikovsky

          You may not reRender a4j:repeat as it has no representation in DOM tree. PLease wrap it with outputPanel and update the panel.

          • 2. Re: a4j:repeater should refresh himself
            fhagen

            Ok,

            i putted the repeater between an outputpanel:

            <a4j:outputPanel id="output">
             <a4j:repeat id="poslist" value="#{positionBean.positions}"var="pos">
             <tr>
             <td><h:outputText id="posdesc" value="#{pos.description}"/></td>
             <td><h:inputText id="posvalue04" value="#{pos.output[0]}">
             <a4j:support event="onclick" reRender="posvalue04"
             focus="posvalue04" action="#{pos.showFormula}"/>
             <a4j:support event="onchange" reRender="output"
             action="#{positionBean.calculateAction}"/>
             </h:inputText>
             </td>
             <td><h:inputText id="posvalue05" value="#{pos.output[1]}">
             <a4j:support event="onclick" reRender="posvalue05"
             focus="posvalue05" action="#{pos.showFormula}"/>
             <a4j:support event="onchange" reRender="posvalue05"
             action="#{positionBean.calculateAction}"/>
             </h:inputText>
             </td>
            </tr>
            </a4j:repeat>
            </a4j:outputPanel>
            


            If a value is changed the repeater is displayed twice on the page.
            The original one and a new one.
            The new one includes the updated values but the original one doesn't.

            How to avoid the new repeater? The orig. one has to be updated.

            • 3. Re: a4j:repeater should refresh himself
              ilya_shaikovsky

              what a4j:log says about reRendering process?..

              • 4. Re: a4j:repeater should refresh himself
                fhagen

                Here is the log - part:

                debug[14:26:35,832]: Attempt to update part of page for Id: form:output
                debug[14:26:35,842]: call getElementById for id= form:output
                debug[14:26:35,842]: Replace content of node by replaceChild()
                debug[14:26:35,952]: search for elements by name 'script' in element span
                debug[14:26:35,972]: getElementsByTagName found 0
                debug[14:26:35,972]: Scripts in updated part count : 0
                debug[14:26:35,992]: Update part of page for Id: form:output successful
                debug[14:26:35,992]: call getElementById for id= ajax-update-ids
                debug[14:26:35,992]: Hidden JSF state fields: [object HTMLSpanElement]
                debug[14:26:35,992]: Namespace for hidden view-state input fields is undefined
                debug[14:26:35,992]: search for elements by name 'input' in element span
                debug[14:26:36,012]: getElementsByTagName found 1
                debug[14:26:36,012]: Replace value for inputs: 32 by new values: 1
                debug[14:26:36,012]: Input in response: javax.faces.ViewState
                debug[14:26:36,022]: Found same input on page with type: hidden
                debug[14:26:36,022]: Found same input on page with type: hidden
                debug[14:26:36,032]: search for elements by name 'INPUT' in element span
                debug[14:26:36,042]: getElementsByTagName found 0
                debug[14:26:36,042]: Replace value for inputs: 32 by new values: 0
                debug[14:26:36,042]: call getElementById for id= _A4J.AJAX.focus
                debug[14:26:36,052]: No focus information in response


                Do i have to update the outputPanel or something else?
                <a4j:support event="onchange" reRender="output" action="#{positionBean.calculateAction}"/>


                Should i change the reRender part to another id?

                • 5. Re: a4j:repeater should refresh himself
                  ilya_shaikovsky

                  hm.. could you please post your full sample anywhere or send to me..

                  • 6. Re: a4j:repeater should refresh himself
                    fhagen

                    Hi,

                    well I think i got a working solution for my testapp.

                    In this forum i found another post. There was a repeater with the ajaxKeys value set. He just putted some integer values into a HashSet and returned it to the repeater. So i did the same.

                    Here is my ajaxKeys HashSet:

                    Set<Integer> rowSet = new HashSet<Integer>();
                    // Getters and Setters are also available
                    
                    //this method is called within the constructor
                    private void writeRowSet() {
                     for(int i=0; i<positions.size();i++)
                     rowSet.add(i); //these are the indexes of the form elements
                    }
                    


                    And so i bound it to the repeater:
                    <a4j:repeat id="poslist" value="#{positionBean.positions}" var="pos" ajaxKeys="#{positionBean.rowSet}">
                     <tr>
                     <td><h:outputText id="posdesc" value="#{pos.description}"/></td>
                     <td><h:inputText id="posvalue04" value="#{pos.output[0]}">
                     <a4j:support event="onclick" reRender="posvalue04" focus="posvalue04" action="#{pos.showFormula}"/>
                     <a4j:support event="onchange" reRender="posvalue04" action="#{positionBean.calculateAction}"/>
                     </h:inputText>
                     </td>
                     <td><h:inputText id="posvalue05" value="#{pos.output[1]}">
                     <a4j:support event="onclick" reRender="posvalue05" focus="posvalue05" action="#{pos.showFormula}"/>
                     <a4j:support event="onchange" reRender="posvalue05" action="#{positionBean.calculateAction}"/>
                     </h:inputText>
                     </td>
                     </tr>
                    </a4j:repeat>


                    This is working pretty fine as long as i don't change a value and click another textfield. There seems to be a problem with the different ajax requests but that is another problem.