6 Replies Latest reply on Jun 7, 2013 6:48 PM by bleathem

    a4j:ajax support for action calls with an argument

    stozer

      Hi all,

       

      We're currently deep into a RF3-->RF4 migration. It's been a lot of work, since it's a fairly big project, but I wouldn't say it's gone un-smoothly so far, at least from a RichFaces perspective. However, we've now run into an issue which I can't seem to find a clean workaround for. It seems like it should be a relatively simple thing to migrate:

       

      {code}<a4j:support action="#{backingBean.save(item)}"/>{code}

       

      That is, an ajax support call to an action method which takes a parameter. There are many other examples of methods and arguments, but that's a reasonably representative case.

       

      Without a parameter, we can do

       

      {code}<a4j:ajax listener="#{backingBean.save}" />{code}

       

      which works, although it seems kind of hackish to be treating an action method as a listener. It's really an action that just happens to be taking advantage of the fact that listener methods don't require that you accept the ActionEvent argument. It works, but it doesn't seem right. However, I can live with that.

       

      For methods that need a parameter, though, there doesn't seem to be any reasonable workaround for passing that argument. I've seen some mentions of using an a4j:jsFunction, but that's even more hackish, hard to maintain, and doesn't really work very cleanly over iteration. I've just had a quick look at PrimeFaces, which seems to have the same issue. That leads me to believe that it's some problem with the underlying JSF spec. That would be fine, except that RF3 had that functionality, which makes it a big issue for migrations. Is there any hope of a4j:ajax supporting a proper action method in the near future? If not, is there any workaround, or should we instead be thinking about refactoring (potentially dramatically, in some cases) to try to avoid needing parameters?

       

      Thanks in advance!

       

      Sean

        • 1. Re: a4j:ajax support for action calls with an argument
          bleathem

          Hi Sean,

           

          The listener attribute of a4j:ajax (and f:ajax for that matter) can indeed be a method that tages an argument, provided your environment is running EL >= 2.2.  This is the case for JBoss AS 7.

           

          I created an Arquillian graphene test demonstrating that this indeed works:

          https://github.com/richfaces/components/blob/develop/core/ui/src/test/integration/org/richfaces/component/ajax/TestAjax.java

           

          But our VDL documentation clearly says you cannot pass arguments to the listener method:

          http://docs.jboss.org/richfaces/latest_4_X/vdldoc/a4j/ajax.html

           

          We'll need to fix that in the VDL docs.  Would mind filing an RF issue requesting that fix?

          Since we are doing a code-freeze monday for 4.3.0.CR1 I went ahead and filed the issue: RF-12716

           

          Thanks,

          Brian Leathem

          • 2. Re: a4j:ajax support for action calls with an argument
            stozer

            Thanks Brian, that's great. I'll work through our various actions and see if there are any that cause any futher problems.

             

            Just a note, it seems a bit odd that your listener_with_parameter() @Test doesn't actually take a parameter. Perhaps I'm misunderstanding something there.

             

             

             

            Oh, one other related issue: https://issues.jboss.org/browse/RFPL-1594

             

            Our listener on h:selectBooleanCheckbox isn't being called at all. We've worked around that for now with an a4j:jsFunction, but I'd like to clean that up. Any idea when that might be resolved?

            • 3. Re: a4j:ajax support for action calls with an argument
              bleathem

              Sean Tozer wrote:

               

              Thanks Brian, that's great. I'll work through our various actions and see if there are any that cause any futher problems.

               

              Just a note, it seems a bit odd that your listener_with_parameter() @Test doesn't actually take a parameter. Perhaps I'm misunderstanding something there.

               

              Sure it does, look at line 61

               

              Oh, one other related issue: https://issues.jboss.org/browse/RFPL-1594

               

              Our listener on h:selectBooleanCheckbox isn't being called at all. We've worked around that for now with an a4j:jsFunction, but I'd like to clean that up. Any idea when that might be resolved?

               

              Can you file an RF issue, and include some sample code to reproduce?  Refer to: https://community.jboss.org/wiki/SubmittingEffectiveIssueReports

              • 4. Re: a4j:ajax support for action calls with an argument

                Hi Brian,

                 

                I had a look at your example and gave it a try in our application. It works fine with Strings being passed as parameters. Do you know how I would be able to pass through a selected value from a autocomplete component? Similar to Sean I've seen various solutions but none of them really work. Here's my code so far:

                 

                <rich:autocomplete id="suggestionEntity" mode="cachedAjax" autocompleteMethod="#{userTree.suggest}"

                          var="entity" fetchValue="#{entity.name}" minChars="3" autoFill="false" selectFirst="false" layout="table">

                          <rich:column label="Name" style="width:250px">

                                    <h:outputText value="#{entity.name}" />

                          </rich:column>

                          <rich:column label="Level" style="width:50px">

                                    <h:outputText value="#{entity.level}" />

                          </rich:column>

                          <a4j:ajax listener="#{userTree.searchTest(entity)}" event="selectitem"/>

                </rich:autocomplete>

                 

                I'm happy to pass through an id as a String but the a4j:ajax seems to have lost the reference to the entity and can't resolve it. Can you think of any way around this?

                 

                Thanks,

                 

                Holger

                • 5. Re: a4j:ajax support for action calls with an argument

                  Any solution for this?

                  • 6. Re: a4j:ajax support for action calls with an argument
                    bleathem

                    The RF 4 autocomplete component only works with Strings.  This has proved to be an ongoing problem that we plan to resolve as one of the first new components implemented in RichFaces 5.

                     

                    If you are ok working with Strings, and want to look up an object in your backing bean from that String ID, then you can programmatically invoke your JSF converter to retrieve an Object from the String in the action of your backing bean.  I don't have any examples doing this, but look at the JSF API docs for details on how to get programmatic access to a converter.