5 Replies Latest reply on Jul 27, 2007 4:24 AM by damianharvey

    commandLink not working if rendered dynamically

    damianharvey

      I have a problem where the Ajax4JSF commandLink and commandButton don't work if they are rendered via an Ajax call. I'm using ajax4jsf-1.1.2-20070718.000117-113.jar and Seam 1.3.0ALPHA.

      I have created a simple test to prove this. My TestBean:

      package com.locuslive.odyssey.session;
      
      import org.jboss.seam.annotations.Logger;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.log.Log;
      
      @Name("testBean")
      public class TestBean {
       @Logger Log log;
       private boolean toggle = false;
      
       public void sayHello() {
       log.info("*** Hello ****");
       }
       public boolean isToggle() {
       return toggle;
       }
       public void setToggle(boolean toggle) {
       this.toggle = toggle;
       }
      }

      My test.xhtml page:
      <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
       xmlns:s="http://jboss.com/products/seam/taglib"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:a="https://ajax4jsf.dev.java.net/ajax"
       xmlns:rich="http://richfaces.ajax4jsf.org/rich"
       template="/layout/template.xhtml">
      
      <ui:define name="body">
      <h:form>
      <a:log/>
       <a:commandLink id="sayHelloLink_1" action="#{testBean.sayHello}" value="Say Hello!" reRender="testDiv"/><br/>
       <a:commandLink id="toggleLink_1" action="#{testBean.setToggle(true)}" value="Turn on toggle" reRender="testDiv"/>
       <s:div id="testDiv">
       <s:div id="renderedDiv" rendered="#{testBean.toggle}">
       <a:commandLink id="sayHelloLink_2" action="#{testBean.sayHello}" value="Say Hello!" reRender="testDiv"/><br/>
       <a:commandLink id="toggleLink_2" action="#{testBean.setToggle(false)}" value="Turn off toggle" reRender="testDiv"/>
       </s:div>
       </s:div>
      </h:form>
      </ui:define>
      </ui:composition>
      


      If I click on the first SayHello link, the method in the TestBean is hit and the message prints out in the logs. If I click the "Turn on Toggle" link, my div displays. If I then click on any of the links that have been newly rendered they do not work.

      I have cranked up the log4j settings on my server and the big difference is that on the lines that work these entries appear:
      10:16:26,892 DEBUG [Contexts] found in event context: testBean
      10:16:26,892 DEBUG [RootInterceptor] intercepted: testBean.sayHello
      

      whereas they are not there when a rendered link is clicked. Does anyone know what might cause this? Is anyone else having problems with rendered links?

      Thanks,

      Damian.

        • 1. Re: commandLink not working if rendered dynamically
          damianharvey

          And there is no noticeable difference between the HTML for the links rendered via normal HTTP Request and those rendered via AJAX. I can only think that it is something to do with the state of the component on the server??

          • 2. Re: commandLink not working if rendered dynamically

            I have the same problem!

            a:commandLink is not working, whereas a:commandButton does!

            POST request is sent, but not processed.

            commandLink is broken even if placed inside of rich:tabPanel =(

            • 3. Re: commandLink not working if rendered dynamically

              if rendered is false at the beginning of the second JSF phase, the content will not be rendered. JSF works like that. You need to be careful with command stuff inside the 'rendered' component.
              Damian, read this http://tinyurl.com/2z2ckq

              P.S. a4j:keepAlive allows to keep the value of the been between the ajax requests

              • 4. Re: commandLink not working if rendered dynamically

                Thanks, Sergey!

                Removing 'rendered' attribute have fixed my problem!

                • 5. Re: commandLink not working if rendered dynamically
                  damianharvey

                  Many thanks Sergey.

                  keepAlive fixed the problem. This is ideal for me, but it is worth noting that the Bean must be serializable for keepAlive to work.

                  The working code looks like this:

                  <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                  <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                   xmlns:s="http://jboss.com/products/seam/taglib"
                   xmlns:ui="http://java.sun.com/jsf/facelets"
                   xmlns:f="http://java.sun.com/jsf/core"
                   xmlns:h="http://java.sun.com/jsf/html"
                   xmlns:a="https://ajax4jsf.dev.java.net/ajax"
                   xmlns:rich="http://richfaces.ajax4jsf.org/rich"
                   template="/layout/template.xhtml">
                  
                  <ui:define name="body">
                  <h:form>
                  <a:log/>
                   <a:commandLink id="sayHelloLink_1" action="#{testBean.sayHello}" value="Say Hello!" reRender="testDiv"/><br/>
                   <a:commandLink id="toggleLink_1" action="#{testBean.setToggle(true)}" value="Turn on toggle" reRender="testDiv"/>
                   <s:div id="testDiv">
                   <a:keepAlive beanName="testBean"/>
                   <s:div id="renderedDiv" rendered="#{testBean.toggle}">
                   <a:commandLink id="sayHelloLink_2" action="#{testBean.sayHello}" value="Say Hello!" reRender="testDiv"/><br/>
                   <a:commandLink id="toggleLink_2" action="#{testBean.setToggle(false)}" value="Turn off toggle" reRender="testDiv"/>
                   </s:div>
                   </s:div>
                  </h:form>
                  </ui:define>
                  </ui:composition>