5

I have the following in a JSF page:

<h:commandLink action="#{manager.removeEntity(row.id)}" value="Remove">
    <f:ajax event="action" render=":form:table" />
</h:commandLink>

The rendering works perfectly, though it renders the component before the action is performed. (I know this through logging)

Is there any way for me to render the components after the action function is performed on the server?

Any help will be greatly appreciated

Update 1

I removed the action attribute and added a listener to the tag, though unfortunately it doesn't seem to help, the method is still called after the component tree is rendered.

Sheldon Irwin
  • 121
  • 1
  • 5
  • 1
    Rendering phase is after application logic phase so what you are claiming is not really possible. Can you try to describe your problem in more details? – mrembisz Mar 11 '12 at 12:57
  • are you saying that the render of the f:ajax happens before the listener of the f:ajax ? – Daniel Mar 11 '12 at 13:26

3 Answers3

1
<h:commandLink action="#{manager.removeEntity(row.id)}" value="Remove">
    <f:ajax event="action" render=":form:table" />
</h:commandLink>

The rendering works perfectly, though it renders the component before the action is performed. (I know this through logging)

This is not true. You must be misinterpreting the logging. Perhaps you have put a log statement inside the getter method of the table's value in a misassumption that it's only called during render response. This is thus not true. The getter is called as many times as an EL expression referencing the property is been evaluated. This can happen in a different phase before and after invoke action phase. As you've the command link inside a datatable, the table's value getter method will also be called during apply request values phase in order to find find the row associated with the link.

Pass FacesContext#getCurrentPhaseId() along with the log to learn during which phase the getter method is been called. Also note that doing business job (like calling database and so on) inside a managed bean getter method is a bad idea.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
0

kinda late but i had the same problem. The ajax renders before my jsf logic completed. My solution? Well i added a confirmation dialog. I know it's not a technical solution but hey, it works. Once the user presses ok on the dialog(which takes about a sec, in this time the logic should be done) the component should be rendered. Good Luck Hope this helps.

Before changes:

<h:commandButton action="#{bean.buisnessLogic(param1, param2)}">
  <f:ajax
      execute="components"
      render="table"
  />
</h:commandButton>

After Changes:

<h:commandButton onclick="javascriptCofirm();" action="#{bean.buisnessLogic(param1, param2)}">
  <f:ajax
      execute="components"
  />
</h:commandButton>
<h:commandButton id="button" style="display: none">
  <f:ajax
     render="table"
  />
</h:commandButton>

javascript:

function javascriptConfirm() {
   bootbox.alert("Se agrego la accion con exito.", function () {
      var boton = document.getElementById("button");
      boton.click();
   });
   e.preventdefault();
   return false;
}

What i did:

Ok so before changes were made. My commandButton would render the table before the registers were added. For example i would add row 2 and it would not show changes until the page was refreshed or row 3 was added. I did some research and my conclusion is that jsf translate the ajax tag to javascript, and javascript directly executes the code without waiting for the the action to finish.

Solution:

So now i remove the render attribute from ajax and i create another commandButton and in the new commandButton i add the render. The javascriptConfirm method calls the button and "clicks it". This renders the page, but by the time they confirm the buisness logic is complete. So yeah. This is probably confusing. Well whatever you just comment and i will try to respond as quickly as possible (probably not that quick).

0

You can use the listener of the f:ajax to execute your logic and pass the row.id with one of the following ways (remove the action="#{manager.removeEntity(row.id)}")

Pass a parameter on ajax call 1

Pass a parameter on ajax call 1

Community
  • 1
  • 1
Daniel
  • 36,833
  • 10
  • 119
  • 200