8 Replies Latest reply on Sep 7, 2007 10:29 AM by Jim Dummy

    rich:dataTable ajaxKeys="" method not called.

    Jim Dummy Newbie

      Hello!

      I'm trying to implement a asynchronously populated table.

      The idea is to have a Bean with List<> of rows and Set as a keys for rows to be updated (inserted). the pool will update the table every second until the table is completely populated.

      No luck so far :-(
      Even the dataTable contains ajaxKeys="" the bean method is not called.

      I have a button.
      By pressing the button I show a modal panel with "please wait" and start a long process. Then I close a modal panel, but keep pooling until the table is populated (enabled="#{SearchForm.running}")
      I don't want to repaint the whole table, so I suppose i can specify ajaxKeys as a set of newly populated rows (?).


      here is the example:

      ...
       <a4j:outputPanel id="search_button">
       Search:
       <h:inputText value="#{SearchForm.searchString}"/>
       <a4j:commandButton
       id="search"
       actionListener="#{SearchForm.search}"
       onclick="javascript:Richfaces.showModalPanel('search_mp', {left:'auto', top:'auto'})"
       oncomplete="Richfaces.hideModalPanel('search_mp');"
       value="search"
       reRender="search_list, search_timer">
       </a4j:commandButton>
       <a4j:poll
       id="search_timer"
       reRender="search_list"
       interval="1000"
       ajaxSingle="true"
       enabled="#{SearchForm.running}"/>
       <rich:modalPanel
       id="search_mp"
       moveable="false"
       resizeable="false"
       width="220"
       height="40"
       zindex="2000">
       <h:graphicImage value="/img/wait.gif" alt="please wait..."/>
       </rich:modalPanel>
       </a4j:outputPanel>
      
       <rich:tabPanel switchType="ajax">
       <rich:tab label="Query Result">
       <rich:dataTable
       id="search_list"
       value="#{SearchForm.results}"
       ajaxKeys="#{SearchForm.rowKeys}"
       var="result"
       style="width: 100%;">
      
       <rich:column style="width: 100%; border: 0px none transparent">
       <rich:simpleTogglePanel label="#{result.description}"
       switchType="ajax"
       ajaxSingle="true"
       opened="false">
       <rich:dataTable value="#{result.resultList}" rendered="#{not empty result.resultList}" var="r" style="width: 100%">
       <rich:column>
       <a4j:outputPanel style="width: 100%; height: 150px; overflow: auto; padding:2px;" layout="block">
       <h:outputText value="#{result.htmlMap[r]}" style="width: 100%; height: 100%; text-align: left" escape="false"/>
      
       </a4j:outputPanel>
       </rich:column>
       </rich:dataTable>
       </rich:simpleTogglePanel>
       </rich:column>
       </rich:dataTable>
       </rich:tab>
      
      ...
      


      full code :
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
      
      <%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
      <%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
      
      <%@ taglib uri="https://ajax4jsf.dev.java.net/ajax" prefix="a4j"%>
      <%@ taglib uri="http://richfaces.ajax4jsf.org/rich" prefix="rich"%>
      
      <f:subview id="search_page">
       <a4j:outputPanel id="search_button">
       Search:
       <h:inputText value="#{SearchForm.searchString}"/>
       <a4j:commandButton
       id="search"
       actionListener="#{SearchForm.search}"
       onclick="javascript:Richfaces.showModalPanel('search_mp', {left:'auto', top:'auto'})"
       oncomplete="Richfaces.hideModalPanel('search_mp');"
       value="search"
       reRender="search_list, search_timer">
       </a4j:commandButton>
       <a4j:poll
       id="search_timer"
       reRender="search_list"
       interval="1000"
       ajaxSingle="true"
       enabled="#{SearchForm.running}"/>
       <rich:modalPanel
       id="search_mp"
       moveable="false"
       resizeable="false"
       width="220"
       height="40"
       zindex="2000">
       <h:graphicImage value="/img/wait.gif" alt="please wait..."/>
       </rich:modalPanel>
       </a4j:outputPanel>
      
       <rich:tabPanel switchType="ajax">
       <rich:tab label="Query Result">
       <rich:dataTable
       id="search_list"
       value="#{SearchForm.results}"
       ajaxKeys="#{SearchForm.rowKeys}"
       var="result"
       style="width: 100%;">
      
       <rich:column style="width: 100%; border: 0px none transparent">
       <rich:simpleTogglePanel label="#{result.description}"
       switchType="ajax"
       ajaxSingle="true"
       opened="false">
       <rich:dataTable value="#{result.resultList}" rendered="#{not empty result.resultList}" var="r" style="width: 100%">
       <rich:column>
       <a4j:outputPanel style="width: 100%; height: 150px; overflow: auto; padding:2px;" layout="block">
       <h:outputText value="#{result.htmlMap[r]}" style="width: 100%; height: 100%; text-align: left" escape="false"/>
      
       </a4j:outputPanel>
       </rich:column>
       </rich:dataTable>
       </rich:simpleTogglePanel>
       </rich:column>
       </rich:dataTable>
       </rich:tab>
      
       <rich:tab label="Log">
       <rich:dataTable
       id="result_list"
       value="#{SearchResultList.list}"
       var="result"
       style="width: 100%;">
      
       <rich:column style="border: 0px none transparent">
       <h:selectBooleanCheckbox value="#{result.checked}">
       <a4j:support event="onchange" reRender="logic"/>
       </h:selectBooleanCheckbox>
       </rich:column>
       <rich:column style="border: 0px none transparent">
       <a4j:outputPanel id="logic">
       <h:selectOneRadio value="#{result.logic}" required="false" style="text-align: center" rendered="#{result.checked}">
       <f:selectItem itemLabel="OR" itemValue="OR" />
       <f:selectItem itemLabel="AND" itemValue="AND" />
       <f:selectItem itemLabel="NOT" itemValue="NOT" />
       </h:selectOneRadio>
       </a4j:outputPanel>
       </rich:column>
       <rich:column style="width: 100%; border: 0px none transparent">
       <rich:simpleTogglePanel label="#{result.description}"
       switchType="ajax"
       ajaxSingle="true"
       opened="false"
       style="background-color: #{result.checked ? 'CC33FF' : '#66CCFF'}">
       <h:dataTable value="#{result.resultList}" rendered="#{not empty result.resultList}" var="r" >
       <h:column>
       <a4j:outputPanel style="padding:2px;" layout="block">
       <h:outputText value="#{result.htmlMap[r]}" style="width: 100%; height: 100%; text-align: left" escape="false"/>
      
       </a4j:outputPanel>
       </h:column>
       </h:dataTable>
       </rich:simpleTogglePanel>
       </rich:column>
       </rich:dataTable>
       </rich:tab>
       </rich:tabPanel>
      </f:subview>
      


        • 1. Re: rich:dataTable ajaxKeys=
          Jim Dummy Newbie

          I just have no idea how it supposed to work...

          I changed dataTable to a4j:repeat and the method is called only once.
          Then the reload happens and it reloads all the data again...

          Shouldn't it ask for the new rowSet every time I reload the table/repeater?
          Could ajaxKeys be dynamic?

          Thank you.

          <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
          <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
          
          <%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
          <%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
          
          <%@ taglib uri="https://ajax4jsf.dev.java.net/ajax" prefix="a4j"%>
          <%@ taglib uri="http://richfaces.ajax4jsf.org/rich" prefix="rich"%>
          
          <f:subview id="search_page">
           <a4j:outputPanel id="search_button">
           Search:
           <h:inputText value="#{SearchForm.searchString}"/>
           <a4j:commandButton
           id="search"
           actionListener="#{SearchForm.search}"
           onclick="javascript:Richfaces.showModalPanel('search_mp', {left:'auto', top:'auto'})"
           oncomplete="Richfaces.hideModalPanel('search_mp');"
           value="search"
           reRender="search_list, search_timer">
           </a4j:commandButton>
           <a4j:poll
           id="search_timer"
           reRender="my_test"
           interval="1000"
           enabled="#{SearchForm.running}"/>
           <rich:modalPanel
           id="search_mp"
           moveable="false"
           resizeable="false"
           width="220"
           height="40"
           zindex="2000">
           <h:graphicImage value="/img/wait.gif" alt="please wait..."/>
           </rich:modalPanel>
           </a4j:outputPanel>
          
           <a4j:outputPanel id="my_test">
           <a4j:repeat
           value="#{SearchForm.results}"
           ajaxKeys="#{SearchForm.rowKeys}"
           var="result">
           <rich:simpleTogglePanel label="#{result.description}"
           switchType="client"
           ajaxSingle="true"
           opened="false">
           <rich:dataTable value="#{result.resultList}" rendered="#{not empty result.resultList}" var="r" style="width: 100%">
           <rich:column>
           <a4j:outputPanel style="width: 100%; height: 150px; overflow: auto; padding:2px;" layout="block">
           <h:outputText value="#{result.htmlMap[r]}" style="width: 100%; height: 100%; text-align: left" escape="false"/>
          
           </a4j:outputPanel>
           </rich:column>
           </rich:dataTable>
           </rich:simpleTogglePanel>
           </a4j:repeat>
           </a4j:outputPanel>
          </f:subview>
          


          • 2. Re: rich:dataTable ajaxKeys=
            Jim Dummy Newbie

            Hello again,
            It looks like I am talking to myself... :-(

            I found an example:

            <a4j:poll intervall="1000" action="#{repeater.action}" reRender="list">
            ...
            <table>
             <tbody>
             <a4j:repeat value="#{bean.props}" var="detail" binding="#{repeater.myRepeat}"
             id="list" ajaxKeys="#{repeater.ajaxedRowsSet}">
             </tr>
             <td>
             <h:outputText value="detail.someProperty">
             </td>
             </tr>
             </a4j:repeat>
             <tbody>
            <table>
            


            and that is what I am failed to do...

            I have a List of beans which is growing say it's 10 elements now
            every second I am polling the repeater and it asks for elements and for a rows to be updated (inserted).
            let's say we have 5 rows more, so the list will be 15 and set (ajaxKeys) is [11 .. 15]
            I think this way ajax response should have only last 5 rows?
            I checked the log and it always returns all the rows.
            It asks for the set only the first time (when the list is empty) (!?!) and then never returns to ask for it, but load whole the data all the time.

            Any idea?
            Thank you in advance.

            P.S. I'm testing 3.1RC5

            • 3. Re: rich:dataTable ajaxKeys=
              Ilya Shaikovsky Master

              You shouldn't reRender a4j:repeat if you need partial update of the table. reRender the outputText directly.

              You may look to the example from richfaces-demo in SVN,

              • 4. Re: rich:dataTable ajaxKeys=
                Jim Dummy Newbie

                Hello Ilia,

                Thank you for reply, but I still can't make it work... :-(

                When I reRender a component inside repeater I got my ajaxKeys method called properly, but WITHOUT refreshing, so I have an empty list.
                If I try to rerender repeater outer component (panel) I have whole list reloaded every time and no ajaxKeys calls

                here is the code again:

                <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
                <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
                
                <%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
                <%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
                
                <%@ taglib uri="https://ajax4jsf.dev.java.net/ajax" prefix="a4j"%>
                <%@ taglib uri="http://richfaces.ajax4jsf.org/rich" prefix="rich"%>
                
                <f:subview id="search_page">
                 <a4j:outputPanel>
                 Search:
                 <h:inputText value="#{SearchForm.searchString}"/>
                 <a4j:commandButton
                 id="search_button"
                 actionListener="#{SearchForm.search}"
                 onclick="this.disabled = true; javascript:Richfaces.showModalPanel('search_mp', {left:'auto', top:'auto'})"
                 oncomplete="Richfaces.hideModalPanel('search_mp');"
                 value="search"
                 disabled="#{SearchForm.running}"
                 reRender="search_timer, item">
                 </a4j:commandButton>
                 <a4j:poll
                 id="search_timer"
                 reRender="search_button, item"
                 interval="1000"
                 enabled="#{SearchForm.running}"/>
                 <rich:modalPanel
                 id="search_mp"
                 moveable="false"
                 resizeable="false"
                 width="220"
                 height="40"
                 zindex="2000">
                 <h:graphicImage value="/img/wait.gif" alt="please wait..."/>
                 </rich:modalPanel>
                 </a4j:outputPanel>
                
                 <a4j:outputPanel id="my_test">
                 <a4j:repeat
                 id="repeat_table"
                 value="#{SearchForm.results}"
                 ajaxKeys="#{SearchForm.rowKeys}"
                 var="result">
                 <a4j:outputPanel id="item">
                 Blah...
                 </a4j:outputPanel>
                 </a4j:repeat>
                 </a4j:outputPanel>
                </f:subview>
                


                // I just changed the actual data with "Blah..."

                Could you please provide me the link to the demo.
                I found http://livedemo.exadel.com/a4j-repeat/ but it forwards nowhere...

                Spasibo.

                • 6. Re: rich:dataTable ajaxKeys=
                  Jim Dummy Newbie

                  Hello,

                  Thank you for the example. it works.

                  Unfortunately I'm still fighting with mine.

                  The problem as I understand is that the data itself is changing (the list is growing), so even I'm returning the keys correctly on every iteration the repeater doesn't refresh it. I even made a binding instead of passing my List<> to the repeater - no luck.
                  By the way the <a4j:log> shows that data is sent back to the browser correctly, just not updated... :-(

                  Thank u very much

                  • 7. Re: rich:dataTable ajaxKeys=
                    Ilya Shaikovsky Master

                    The main ajax limitation - you can't add something to DOM tree.. just update. So seems you need to refresh the whole table.

                    • 8. Re: rich:dataTable ajaxKeys=
                      Jim Dummy Newbie

                      Hello Ilia,
                      thank you I think that has nothing to see with ajax (ajax is only a fancy way to pass data to javascript), but with an implementation (would you say that I can not add a DOM element from javascript?). Nevermind, My solution is to hide (rendered="#{...}") the rows and "update" them when data arrives. so the same effect as "inserting".

                      The proble I have is that rows itself are rich:simpleTogglePanel and I have some issues too... :-(

                      I close this topic to start a new one.

                      Thank you!