8 Replies Latest reply on Apr 9, 2007 7:32 AM by dpaterson

    problem with t:commandLink in rerendered datatable

    dpaterson

      I'm trying to create a simple "suggest" like feature based on a inputText box and a Ajax supported dataTable. I am able to update the dataTable no problem but for some reason my commandLinks within the table don't work.

      These same links function properly, making the appropriate backing bean calls, in a non-ajax scenario. I've tried a bunch of variants using a4j command links instead of t:commandLink but that has't helped. Here's the snippet of the JSF and backing bean. Basically when I click a link I should call a backing bean method that will load the details for the record and take me to a detail page based on the string populate() returns. Not sure what I'm missing.

      JSF

      <t:inputText forceId="true" value="#{serviceBeanAllView.a4jTest}" id="test11">
       <a4j:support event="onkeyup" requestDelay="180" immediate="false" reRender="id_data_table_pop"/>
      </t:inputText>
      <t:dataTable
       id="id_data_table_pop"
       rowOnMouseOver="this.style.backgroundColor='#D6DDE2'"
       rowOnMouseOut="this.style.backgroundColor=''"
       forceId="true"
       styleClass="class_table_view_all class_table_view_pop"
       rowClasses="even_class, odd_class"
       columnClasses="name_column"
       cellpadding="0"
       cellspacing="0"
       align="center"
       var="service"
       value="#{serviceBeanAllView.sortListFiltered}"
       sortColumn="#{serviceBeanAllView.sort}"
       renderedIfEmpty="true">
       <%-- Name column. --%>
       <h:column>
       <t:commandLink styleClass="name_link" action="#{serviceBeanSingle.populate}">
       <t:updateActionListener property="#{serviceBeanSingle.zoneId}" value="#{service.zoneId}" />
       <t:updateActionListener property="#{serviceBeanSingle.id}" value="#{service.id}" />
       <t:updateActionListener property="#{serviceBeanSingle.task}" value="#{serviceBeanSingle.editTask}" />
       <h:outputText value="#{service.name}" />
       </t:commandLink>
       </h:column>
       </t:dataTable>


      ServiceBeanSingle.populate()

      public String populate() {
       logger.info("populate() "+PreferencesBean.START_STR);
       setReadOnly(true);
      
       ServiceServiceBean service = ServiceServiceBean.getService();
       try {
       ServiceObject object = service.getById(getZoneId(), getId());
       setName(object.getName());
       setDescription(object.getDescription());
       setApplicationId(object.getApplicationId());
       setNetworkDestinationId(object.getNetworkDestinationId());
       setSubscriberRoleName(object.getSubscriberRoleName());
       setNoFurtherClassification(object.isNoFurtherClassification());
       setZoneId(object.getZoneId());
       setId(object.getId());
      
       applicationMap = ServiceServiceBean.getAllApplications();
       networkDestinationMap = ServiceServiceBean.getAllNetworkDestinations();
      
       return PAGE_SERVICE_EDIT;
       } catch (Throwable t) {
       UiErrorHandlerBean.getHandler().handle(null, t);
       return PAGE_SERVICE_VIEW_ALL;
       } finally {
       logger.debug("populate() "+PreferencesBean.FINISH_STR);
       }
       }

      My Environment is: MyFaces 1.1.4, Tomahawk 1.1.3, Tomcat 5.5.28, JDK 1.5.x. We are also using tiles support with MyFaces. Any help would be greatly appreciated.

        • 1. Re: problem with t:commandLink in rerendered datatable
          ilya_shaikovsky

          Try please to use a4j:form and a4j:htmlCommandLink - its the same for the tomahawk ones except some encoding improvements for links

          • 2. Re: problem with t:commandLink in rerendered datatable
            dpaterson

            I've tried the a4j:commandLink to no avail and the problem I have with using a a4j:form is I'm already inside another form so I can't nest them. I'll see if I can move things around a bit. Thanks for the swift assistance.

            • 3. Re: problem with t:commandLink in rerendered datatable
              dpaterson

              So here's what I've got now:
              In my layout template I have:

              <a4j:form id="main">
              <%-- Content. --%>
              <t:div id="body_div" forceId="true">
               <f:subview id="content_view">
               <tiles:insert attribute="body" flush="false"/>
               </f:subview>
              </t:div>
              </a4j:form>


              And in the body inserted by tiles I have:

              <t:inputText onfocus="this.autocomplete=false" forceId="true" value="#{serviceBeanAllView.a4jTest}" id="test11">
               <a4j:support event="onkeyup" requestDelay="180" immediate="false" reRender="id_data_table_pop"/>
              </t:inputText>
              <a4j:commandButton action="#{serviceBeanAllView.search}"
               onmouseover="this.className='command_button command_button_over'"
               onmouseout="this.className='command_button'"
               onmousedown="this.className='command_button command_button_click'"
               styleClass="command_button" value="Search">
              </a4j:commandButton>
              
              <a4j:outputPanel ajaxRendered="true" layout="block" >
              <t:dataTable
               id="id_data_table_pop"
               rowOnMouseOver="this.style.backgroundColor='#D6DDE2'"
               rowOnMouseOut="this.style.backgroundColor=''"
               forceId="true"
               styleClass="class_table_view_all class_table_view_pop"
               rowClasses="even_class, odd_class"
               columnClasses="name_column"
               cellpadding="0"
               cellspacing="0"
               align="center"
               preserveDataModel="false"
               var="service"
               rows="6"
               value="#{serviceBeanAllView.sortListFiltered}"
               sortColumn="#{serviceBeanAllView.sort}"
               renderedIfEmpty="true">
               <%-- Name column. --%>
               <h:column>
               <a4j:commandLink ajaxSingle="false" styleClass="name_link" action="#{serviceBeanSingle.populate}">
               <t:updateActionListener property="#{serviceBeanSingle.zoneId}" value="#{service.zoneId}" />
               <t:updateActionListener property="#{serviceBeanSingle.id}" value="#{service.id}" />
               <t:updateActionListener property="#{serviceBeanSingle.task}" value="#{serviceBeanSingle.editTask}" />
               <h:outputText value="#{service.name}" />
               </a4j:commandLink>
               </h:column>
               </t:dataTable>
               </a4j:outputPanel>


              Still doesn't work, the links never call the backing bean.

              • 4. Re: problem with t:commandLink in rerendered datatable
                ilya_shaikovsky

                Try to use

                <a4j:outputPanel ajaxRendered="true">
                 <h:messages/>
                </a4j:outputPanel>
                

                To prevent possible validation/conversion errors

                Use
                <a4j:log>
                to look to the client side debugger.

                And why you didn't tries reRender anything? You need simple navigation - then use
                <a4j:htmlCommandLink/>


                • 5. Re: problem with t:commandLink in rerendered datatable

                  yep. a4j:commandLink and a4j:htmlCommandLink are not the same. You have to use a4j:htmlCommandLink as a substitute for non-ajax command link.

                  • 6. Re: problem with t:commandLink in rerendered datatable
                    dpaterson

                    Oops, didn't realize there was commandLink and htmlCommandLink, my mistake. Still can't get it working though. I've simplyfied it somewhat and the links still don't call my backing bean method.

                    This snippet is inside a <a4j:form> in the layout template:

                    <t:inputText onfocus="this.autocomplete=false" forceId="true" value="#{serviceBeanAllView.a4jTest}" id="test11">
                     <a4j:support event="onkeyup" requestDelay="180" immediate="false" reRender="main:content_view:body_content_view:service_list" />
                    </t:inputText>
                    <t:commandButton action="#{serviceBeanAllView.search}"
                     onmouseover="this.className='command_button command_button_over'"
                     onmouseout="this.className='command_button'"
                     onmousedown="this.className='command_button command_button_click'"
                     styleClass="command_button" value="Search">
                    </t:commandButton>
                    
                    <a4j:outputPanel ajaxRendered="true" id="service_list" layout="block" >
                    <t:dataList style="font-size:8px;" forceId="true" value="#{serviceBeanAllView.sortListFiltered}" var="service">
                     <a4j:htmlCommandLink action="#{serviceBeanSingle.populate}">
                     <t:updateActionListener property="#{serviceBeanSingle.zoneId}" value="#{service.zoneId}" />
                     <t:updateActionListener property="#{serviceBeanSingle.id}" value="#{service.id}" />
                     <t:updateActionListener property="#{serviceBeanSingle.task}" value="#{serviceBeanSingle.editTask}" />
                     <h:outputText value="#{service.name}" />
                     </a4j:htmlCommandLink >
                     </t:dataList>
                    </a4j:outputPanel>


                    Here is the rendered html for a link:
                    <a onclick="return _JSFFormSubmit('main:content_view:body_content_view:_idJsp63:0:_idJsp64','main',null,{})"
                     href="#" id="main:content_view:body_content_view:_idJsp63:0:_idJsp64">AgentX</a>


                    I debuged the _JSFFormSubmit script in firebug as well and that seemed to execute and correctly submit the form.

                    Lastly here's the output from my log when the link is clicked, not much really.

                    15:47:07,078 [DEBUG] [TraceResourcePhaseListener] View Root :/page-service-setup-services-view-all.jsp
                    15:47:07,078 [DEBUG] [UpdateModelValuesPhaseListener] Before Update Model
                    15:47:07,078 [INFO ] [ServiceBeanAllView] setA4jTest called input is: agen
                    15:47:07,078 [INFO ] [ServiceBeanAllView] filterSortList called
                    15:47:07,078 [INFO ] [ServiceBeanAllView] filterSortList called
                    15:47:07,078 [DEBUG] [UpdateModelValuesPhaseListener] After Update Model
                    15:47:07,265 [DEBUG] [AbstractConcurrentReadCache] get called (key=org.ajax4jsf.framework.ajax.AjaxScript)
                    15:47:07,296 [DEBUG] [AbstractConcurrentReadCache] get called (key=org/ajax4jsf/renderers/ajax/scripts/form.js)


                    Anything I should turn up so I can get a bit more info? I don't get anything in
                    <log/>
                    or
                    <messages/>
                    after I click the link.

                    • 7. Re: problem with t:commandLink in rerendered datatable
                      dpaterson

                      I think I've gotten somewhere, the links will function when outside a t:dataList or t:dataTable rendered after the keyup event in my text box with ajax support.

                      If I referenence one of my collection by index outside the dataList tag the link functions

                      <a4j:outputPanel ajaxRendered="true" id="service_list" layout="block" >
                      
                       <a4j:htmlCommandLink action="#{serviceBeanSingle.populate}">
                       <t:updateActionListener property="#{serviceBeanSingle.zoneId}" value="#{serviceBeanAllView.sortListFiltered[0].zoneId}" />
                       <t:updateActionListener property="#{serviceBeanSingle.id}" value="#{serviceBeanAllView.sortListFiltered[0].id}" />
                       <t:updateActionListener property="#{serviceBeanSingle.task}" value="UPDATE" />
                       <h:outputText value="#{serviceBeanAllView.sortListFiltered[0].name}" />
                       </a4j:htmlCommandLink >
                      </a4j:outputPanel>


                      Likewise if I reference a item I know exists in the collection and output that link in the list, the link does not function.

                      <a4j:outputPanel ajaxRendered="true" id="service_list" layout="block" >
                      <t:dataList forceId="true" value="#{serviceBeanAllView.sortListFiltered}" var="service">
                       <a4j:htmlCommandLink value="Dummy Link" action="#{serviceBeanSingle.populate}">
                       <t:updateActionListener property="#{serviceBeanSingle.zoneId}" value="2158" />
                       <t:updateActionListener property="#{serviceBeanSingle.id}" value="2228" />
                       <t:updateActionListener property="#{serviceBeanSingle.task}" value="UPDATE" />
                       </a4j:htmlCommandLink>
                       </t:dataList>
                      </a4j:outputPanel>


                      The only difference I see is that the link id's a slightly different.

                      The one that works:
                      <a id="main:content_view:body_content_view:_idJsp66" onclick="return _JSFFormSubmit('main:content_view:body_content_view:_idJsp66','main',null,{})" href="#" >AgentX</a>


                      The one that works, NOT:
                      <a id="main:content_view:body_content_view:_idJsp63:0:_idJsp64" onclick="return _JSFFormSubmit('main:content_view:body_content_view:_idJsp63:0:_idJsp64','main',null,{})" href="#" >Dummy Link</a>



                      • 8. Re: problem with t:commandLink in rerendered datatable
                        dpaterson

                        Still banging my head over this one, anyone have any ideas why a4j:htmlCommandLink works on it's own but doesn't work when it's inside a nested t:datalist component?