12 Replies Latest reply on Mar 14, 2007 6:42 PM by dcstewieg

    Action methods not being called

    dcstewieg

      I have a list of items to add to a comparison. Each has an Add button which is a4j:commandButton. It seems that some buttons work fine and others do not, completely randomly. This happens using h:dataTable, ui:repeat (Facelets), or a4j:repeat. All give the same result.

      I can see from FireBug that the AJAX request is going through, but it comes back without hitting my action method. I verified by putting logging in the method and inserting a breakpoint. For certain buttons, the breakpoint is hit and everything works perfectly. For the others, it isn't hit at all.

      Sometimes it seems to have a pattern. The first half of the buttons works, but the rest do not. Any ideas or this just a bug report?

        • 1. Re: Action methods not being called

          How you bind your actions to the buttons?

          • 2. Re: Action methods not being called
            dcstewieg

            The button looks like this:

            <a4j:commandButton action="#{searchItem.addToComparison}" reRender="requestPool" style="display: none;" oncomplete="jsFunction('#{result.id}');">
             <f:param name="resultId" value="#{result.id}" />
            </a4j:commandButton>


            It has a display: none because I need to use a button element with an image on it. That button "clicks" the a4j button in javascript.

            • 3. Re: Action methods not being called

              What is 'searchItem" and "result"?

              • 4. Re: Action methods not being called

                If you want to click an "a4j button" from javascript, the a4j:jsFunction is a right way to do so. a4j:jsFunction is like any other Ajax Components, but invoked from the javascript

                The action method will not be called if some validation or conversion error occurs

                Add on the page:

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


                • 5. Re: Action methods not being called
                  dcstewieg

                  I ended up kinda hacking it to work.

                  I had (highly simplified):

                  <h:dataTable value="#{bean.getItems}" var="item">
                   <h:column>
                   <a4j:commandButton action="#{bean.addItemToComparison}" reRender="someid">
                   <f:param name="itemId" value="#{item.id}" />
                   </a4j:commandButton>
                   </h:column>
                  </h:dataTable>
                  


                  I now have (again simplified):
                  <a4j:commandButton id="addButton" action="#{bean.addItemToComparison}" reRender="someid">
                   <f:param name="itemId" value="ITEM_ID" />
                  </a4j:commandButton>
                  <h:dataTable value="#{bean.getItems}" var="item">
                   <h:column>
                   <button onclick="customAddJS(this, '#{item.id}');">Text</button>
                   </h:column>
                  </h:dataTable>
                  
                  // JavaScript
                  function customAddJS(obj, itemId)
                  {
                   // Copied code from A4J output
                   A4J.AJAX.Submit('_viewRoot', 'form1', obj.event,
                   {
                   'parameters':
                   {
                   'form1:addButton':'form1:addButton','itemId':'' + itemId
                   },
                   'actionUrl':'/ContextRoot/page.jsf'
                   });
                  }
                  


                  The custom function emulates pressing the button, but fills in the id that I want. It is also doing a lot of other things before the Ajax request is made, so it makes sense to put it all together. This has the added benefit of less A4J JavaScript being rendered to the page.

                  • 6. Re: Action methods not being called

                    It looks like you just reinvent the a4j:jsFunction component. Why?

                    • 7. Re: Action methods not being called
                      dcstewieg

                      You know what, I looked at jsFunction really quickly when you first mentioned it but I think I read it wrong. I'll look into it.

                      • 8. Re: Action methods not being called
                        dcstewieg

                        Is there a way to use a variable in the oncomplete? I need to send the itemId of the button clicked to the oncomplete function but I don't see a way to do that. Many requests could be going on at the same time so I can't save it globally.

                        • 9. Re: Action methods not being called

                          This demo shows the jsFunction in use:

                          http://livedemo.exadel.com/richfaces-demo/richfaces/gmap.jsf?c=gmap

                          <h:form>
                           <a4j:jsFunction name="showPlace" data="#{gmBean.currentPlace}" reRender=":zoom"
                           oncomplete="map.setCenter(new GLatLng(data.lat, data.lng),data.zoom)">
                           <a4j:actionparam name="id" assignTo="#{gmBean.currentId}"></a4j:actionparam>
                           </a4j:jsFunction>
                          </h:form>


                          So, the data attribute points to the property of the managed bean. In the oncomplete you can use it as a parameter.

                          In your case, itemId is a string. Assume you have a itemId String property of the managed bean #{foo} and you assign a value to it (using action on a4j:jsFunction, for example). When response comes, you can use it to call a function in oncomplete like that:

                          <a4j:jsFunction data=" #{foo.itemId}" oncomplete="myfunc(data)" ..../>

                          ....


                          function myfunc(id) {
                          alert("The id is " + id);
                          }


                          • 10. Re: Action methods not being called
                            dcstewieg

                            I can look into that but since what I have now works, I may leave it. With the data attribute being set as a value on the managed bean, what happens if...

                            Event 1 request
                            Event 2 request
                            Event 2 response
                            Event 1 response

                            It would seem to me that the value for Event 2 would be there at the end of Event 1...is that case handled?

                            Thanks for the help.

                            • 11. Re: Action methods not being called

                              you need to specify the the queue name - eventsQueue attribute. It guaranties the order. Otherwise, the requests are sent simultaneously.

                              • 12. Re: Action methods not being called
                                dcstewieg

                                I have everything set up now, thanks. Also, I didn't realize you could have any number of attributes with whatever names you want...that's nice.