5 Replies Latest reply on Aug 5, 2008 7:34 PM by sjmenden

    Passing method calls to Facelets tag

    rhythmicdevil

      Hello,
      I am trying to create a JSF confirmation box that replaces the Javascript confirm() function. I am using Seam and Rich Faces 3.2.1. The confirm box is a facelet tag that pops up a modal box with 'cancel' and a 'continue' buttons. Everything is working correctly except for one crucial piece; passing the method call for the continue button.


      Here is the set up for the facelets tag in the main xhtml page:


      <at:confirm
          id="confirm"
          title="Confirm"
          message="Do you want to continue"
          buttonText="Continue"
          backingBean="#{confirmAction}"
          method="testMethodTwo"
      />



      Here is the code for the button inside the facelets tag:


      <a4j:commandLink
          styleClass="rdSplGr1"
          href="#"
          action="#{backingBean[method]}">
          <s:span>#{buttonText}</s:span>
      </a4j:commandLink>




      The method simply does nothing when the user clicks the button. I am assuming this is due to the lack of () however there does not seem to be a way to get those in there. I have tried the following:


      1) placing the parens like this: method="testMethodTwo()"



      2) placing the parens like this: action="#{backingBean[method]()}"


      The first does nothing, the second causes an EL exception.


      I know that it has nothing to do with the modal as I have also placed a button like this into the modal:



      <a4j:commandLink
          styleClass="rdSplGr1"
          href="#"
          action="#{confirmAction.testMethodOne()}">
           <s:span>MethodOne</s:span>
      </a4j:commandLink>




      That button, as you can see has what I am trying to create dynamically and it works like a charm.


      So how do I pass a method call correctly? Or if that is impossible how do I solve the problem of having a the continue button having a different method assigned to it?


      Thanks for any insight into this.

        • 1. Re: Passing method calls to Facelets tag
          sjmenden
          No, this should work, it does in the example I've worked with.  Do you have your a4j:commandLink wrapped in a <h:form> ?
          • 2. Re: Passing method calls to Facelets tag
            rhythmicdevil
            Hi Samuel,
            thanks for reading my post. One thing that was explained to me by another developer I work with about the [] operators is that they only work for values and so cant be used for calling a method. Even though in reality you are calling a getter or setter.

            I should have an update for this problem sometime tomorrow.
            • 3. Re: Passing method calls to Facelets tag
              sjmenden
              []  can be resolved to both a ValueExpression or MethodExpression, actually even [][] can be used, something like #{backingBean[fieldName][nestedFieldName]}  Which would be appropriate if you were trying to access the field of an Object in an Object. 

              But back to the topic at hand:
              ex.

              <a:commandButton id="update"
                value="Update"
                action="#{backingBean[update]}"
                rendered="#{backingBean[managed]}" />

              works where #{backingBean[update]} is a MethodExpression and #{backingBean[managed]} is an ActionExpression.

              So, I think the problem is, why is that method not getting called, can you verify there is a form surrounding the a4j:commandLink?
              • 4. Re: Passing method calls to Facelets tag
                rhythmicdevil

                I am sure that the code with the button is in the form. See underneath I have posted each of the files in their entirety. The XHTML page has the form element and so I assume when the Facelet is included into the page it too is inside the form element. I have looked at the rendered source and verified that that is true. I have verified in the output log that the methods get called from the two test buttons in the XHTML page. I have verified that the method does not called from the button in the modal(Facelet). I really appreciate you taking the time to look at this. My colleague has given me a technique using a delegate to execute the method. I am going to give that a try now but I look forward to hearing what you have to say.


                This the XHTML page


                <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
                                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                <html
                    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:rich="http://richfaces.org/rich"
                    xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
                    xmlns:at="http://www.autotrader.com/jsf"
                >
                
                <body>
                <ui:composition template="layout/template_base.xhtml">
                    <ui:define name="body">
                    <h:form>
                    
                            <s:div
                                styleClass="buttonwrapper"
                                style="display:inline;"
                            >
                                <a4j:commandLink
                                    styleClass="rdSplGr1"
                                    href="#"
                                    action="#{confirmAction.testMethodOne()}"
                                >
                                    <s:span>MethodOne</s:span>
                                </a4j:commandLink>
                            </s:div>
                            <s:div
                                styleClass="buttonwrapper"
                                style="display:inline;"
                            >
                                <a4j:commandLink
                                    styleClass="rdSplGr1"
                                    href="#"
                                    action="#{confirmAction.testMethodTwo()}"
                                >
                                    <s:span>MethodTwo</s:span>
                                </a4j:commandLink>
                            </s:div>
                    
                    
                        <div onclick="Richfaces.showModalPanel('confirm')">Click</div>
                
                        <at:confirm
                            id="confirm"
                            title="Confirm"
                            message="Do you want to continue"
                            buttonText="Continue"
                            backingBean="#{confirmAction}"
                            method="testMethodTwo"
                         />
                       </h:form>
                    </ui:define>
                </ui:composition>
                
                </body>
                
                </html>
                



                This is the Facelet



                <ui:composition
                    xmlns="http://www.w3.org/1999/xhtml"
                    xmlns:h="http://java.sun.com/jsf/html"
                    xmlns:f="http://java.sun.com/jsf/core"
                    xmlns:ui="http://java.sun.com/jsf/facelets"
                    xmlns:rich="http://richfaces.org/rich"
                    xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
                    xmlns:s="http://jboss.com/products/seam/taglib"
                >
                    <a4j:outputPanel
                        id="notificationCont"
                        ajaxRendered="true"
                    >
                        <rich:modalPanel
                            id="#{id}"
                            rendered="true"
                            showWhenRendered="false"
                            zindex="10000"
                            height="100"
                            width="200"
                        >
                            <f:facet name="header">
                                <h:panelGroup>
                                    <h:outputText value="#{title}" />
                                </h:panelGroup>
                            </f:facet>
                
                            <h:outputText value="#{message}"></h:outputText>
                
                            <h:panelGrid
                                style="margin:10px auto 0 auto;"
                                columns="2"
                                columnClasses="paddingRight, paddingLeft"
                            >
                                <h:column>
                                    <s:div
                                        styleClass="buttonwrapper"
                                        style="display:inline;"
                                    >
                                        <div
                                            onclick="Richfaces.hideModalPanel('#{id}');"
                                            class="rdClGr1"
                                        ><s:span>Cancel</s:span></div>
                                    </s:div>
                                </h:column>
                                <h:column>
                                    <s:div
                                        styleClass="buttonwrapper"
                                        style="display:inline;"
                                    >
                                        <a4j:commandLink
                                            styleClass="rdSplGr1"
                                            href="#"
                                            action="#{backingBean[method]}"
                                        >
                                            <s:span>#{buttonText}</s:span>
                                        </a4j:commandLink>
                                    </s:div>
                                </h:column>
                            </h:panelGrid>
                            
                        </rich:modalPanel>
                    </a4j:outputPanel>
                </ui:composition>



                This is the backing class



                package actionClasses;
                
                import org.jboss.seam.annotations.Name;
                
                @Name("confirmAction")
                public class ConfirmAction
                {
                     public String testMethodOne()
                     {
                          System.out.println("testMethodOne fired");
                          return "true";
                     }
                     
                     public boolean testMethodTwo()
                     {
                          System.out.println("testMethodTwo fired");
                          return true;
                     }
                     
                }
                



                • 5. Re: Passing method calls to Facelets tag
                  sjmenden

                  I'd venture a guess this has something to do with the additional Richfaces tags you have surrounding the link, modalPanel, outputPanel, ect...


                  I put together a simplified example based on what you have and it does work, so one of the few possibilities left is some Richfaces interference, or versioning.  I'm testing with Seam 2.0.3.CR1, but that shouldn't make a difference.


                  confirm.xhtml


                  <ui:composition
                      xmlns="http://www.w3.org/1999/xhtml"
                      xmlns:h="http://java.sun.com/jsf/html"
                      xmlns:f="http://java.sun.com/jsf/core"
                      xmlns:ui="http://java.sun.com/jsf/facelets"
                      xmlns:rich="http://richfaces.org/rich"
                      xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
                      xmlns:s="http://jboss.com/products/seam/taglib">
                  
                       <a4j:commandLink
                           styleClass="rdSplGr1"
                           value="Click Me"
                           action="#{backingBean[method]}" />
                   
                  </ui:composition>



                  testCompositeButton.xhtml


                  <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:rich="http://richfaces.org/rich"
                                  xmlns:crud="http://enhancements.seam/jsf"
                                  template="layout/template.xhtml">
                  
                       <ui:define name="body">
                            <h:form>
                                 <crud:confirm backingBean="#{TestBackingBean}" method="submit" />
                            </h:form>
                       </ui:define>
                  </ui:composition>



                  TestBackingBean.java


                  @Name("TestBackingBean")
                  public class TestBackingBean {
                  
                       @Logger 
                       private Log log;
                       
                       public void submit() {
                            log.info("TestBackingBean:submit()");
                       }
                  }




                  After clicking the link:



                  12:29:58,774 INFO  [TestBackingBean] TestBackingBean:submit()