a4j:commandbutton within f:ajax nested does not execute oncomplete - ajax

As you can see below, I have a f:ajax nested in a a4j:commandLink, something similar to what I read here in order to solve a saving-on-db issue.
Now, when I click the commandLink, oncomplete is never call. That means, the modal does not close and the cursor keeps on "waiting" mode. If I remove the f:ajax, oncomplete is called but the saving-on-database comes back.
I have already tried several things but no one actually worked. Does anyway what might be the problem here?
Thanks in advance
<a4j:commandLink value="#{msg.label_accept}"
onclick="this.disabled=true; document.body.style.cursor='wait';"
action="#{backingBeanRef['select']}"
oncomplete="this.disabled=false; document.body.style.cursor='auto';closeModal('modalDocumentationCenter');"
styleClass="btn btn-default btn-einvoice"
render="#this">
<f:ajax execute="inputTitle inputDescription"/>
</a4j:commandLink>

a4j:commandLink has ajax already. So use execute from a4j:commandLink directly. Don't use another ajax tag. You can't (or, for sure, you shouldn't) use both.
Or I you really want to use f:ajax, then use h:commandLink instead of a4j:commandLink.
PS. You can try to use a4j:ajax, but I'm pretty sure the result will be the same as for f:ajax.

Related

Click on h:panelgroup

I am struggling to get the click event on h:panelgroup which will call a method in my managedbean. I don't want binding as it is only for property.
Also can someone explain the function of below line.
<f:ajax event="click" render="#all" listener="#{ABC.abc}" />
This is taking click listener on the whole page. I only need it to trigger when the input is clicked. So after this was not working I am trying to get a click on panelgroup. Is there any other way.
Thanks.
So figured it out why it was taking click on whole page. I was not wrapping f:ajax call in jsf component. So it was attacking to main h:panelgroup. Wrapped it around a new panelgroup and it started working fine.
But I am getting click twice on each call. :/

passing input text's value to server side on click of a button in JSF

I have a text box which takes a search value, and i want to send this string to the server side on click of a button. Not by a form submit, by an ajax call.
I had added an actionListener to the input tag itself, which is called on blur. But what i really want is for the user to click the button to trigger the search function.
I got an idea from this question, and implemented it this way:
<h:inputText id="likeMaterial" value="#{createBookingForm.searchText}"></h:inputText>
<a4j:jsFunction name="setParameterAndRerender" actionListener="{bean.searchMaterials}" reRender="searchResult">
<a4j:actionparam name="param1" assignTo="#{createBookingForm.searchText}"/>
</a4j:jsFunction>
<h:commandButton value="Search" onclick="setParameterAndRerender('mySearchText');return false;"></h:commandButton>
The value received at server side is of course, "mySearchText". How do i pass what the user enters? Or how do i bind #{createBookingForm.searchText} before the button's action listener is called?
Im open to any other approach to. I have limitations though : Im working on enhancing a legacy application, built using JSF 1.1. I cant upgrade, not without a fight at least!
Edit : I tried doing it this way, but i get "undefined" on the server side.
Why not use a4j:commandButton instead of h:commandButton? It will execute ajax request and render what you want. No form submit will happen. Loks like what you need.
h:commandButton by default submit the form when clicked. So no need to send specially using a4j:jsFunction or in any other way. You can completely remove your js function unless if you have something else to do. If you want to test that add an action method and print the value of searchText variale in createBookingForm bean.
Hope this helps!!
This is the whole solution
<h:inputText id="likeMaterial" value="#{createBookingForm.searchText}"></h:inputText>
<a4j:commandButton reRender="searchResult" actionListener="#{createBookingForm.searchMaterials}">
<a4j:actionparam name="param1" noEscape="true" value="document.getElementById('likeMaterial').value" assignTo="#{createBookingForm.searchText}" />
</a4j:commandButton>

JSF Ajax Link performs partial ajax render before the link action

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.
<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:
Why JSF calls getters multiple times
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
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).

JSF Ajax's listener is reached before the event itslef

i'm trying to figure out the ajax's tag 'listener' property, and from what i read here
An ajax listener, connected to your ajax event with the listener attribute, is a method that will be called every time the ajax request is made
which is exactly what i'm looking for. i've also tried the first sample of code on that web page and it works as expected.
however, when i add the following code -
<h:commandButton id="d" image="#{CodeBean.imgSrc}" action="#{CodeBean.clickImg()}">
<f:ajax event="action" render="d" listener="#{CodeBean.update}" />
</h:commandButton>
both 'clickImg' and 'update' functions are called (and 'clickImg' does its task), but the 'update' is being performed BEFORE the 'clickImg' (i've added to both function 'System.out.println(...)'). and yes - in that sample code the 'update' is being performed after the 'setHello'
that makes no sense to me - or did i miss something?
cheers,
eRez
That's fully by specification. Action listeners are called before actions during invoke action phase. If you need to execute a business action and/or to navigate, do it in action. If you need to listen on the action event so that you can if necessary do some preprocessing, use listener.
In your particular case, it look like you don't need the action listener at all. Just remove it and move the job into the action method. The event attribute is by the way superfluous. It already defaults to action. Just remove it. This works equally good:
<h:commandButton image="#{CodeBean.imgSrc}" action="#{CodeBean.clickImg}">
<f:ajax render="#this" />
</h:commandButton>
See also:
Differences between action and actionListener
in the example you looked at setHello was a setter of h:inputText value and not an action like in your code , that is what you missed...
And that's why in the example the setter was called before the ajax listener...

What is <f:ajax execute="#all"> really supposed to do? It POSTs only the enclosing form

sorry if I am being thick but what is the execute="#all" in an f:ajax tag really supposed to do? I expected it to submit all the elements on a page but it seems to POST only the values in the enclosing form, not all forms on page.
For example
<h:body>
<h:form id="form1">
Input1/Form1 <h:inputText id="testinput" value="#{testBean.input1}" />
</h:form>
<h:form id="form2">
Input2/form2 <h:inputText id="testinput2" value="#{testBean.input2}" />
<h:commandButton value="Ok" actionListener="#{testBean.al}">
<f:ajax execute="#all" />
</h:commandButton>
</h:form>
</h:body>
Only form2 is posted on click.
Using mojarra 2.0.2..
The execute="#all" was just a major oversight during designing JSF2 spec. JSF kind of abstracted away too much of its HTML form based nature, forgetting that it's ultimately actually a HTML code generator.
In HTML, submitting a different form than the enclosing one is disallowed. So execute="#all" will never work from that perspective on. It will behave exactly the same as execute="#form". Given that JSF is just a HTML code generator, the same "problem" will hit JSF too. It's not possible to process multiple <h:form> components at once.
If you really need to have this feature for some reason, you should take a step back and reconsider the incorrect way how you look at HTML forms. You need to make sure your forms are designed in such way that you never need information from another form.
See also:
How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?.
PrimeFaces already realized early that #all was fundamentally wrong. That's exactly why they never supported #all in process attribute, their equivalent of execute. They initially also never supported #all in update, their equivalent of render. However, the only real world use case where that made sense was handling a full error page during an ajax exception, so they ultimately brought update="#all" back after I created the FullAjaxExceptionHandler. The process="#all" will still have exactly the same effect as process="#form".
However, the very same PrimeFaces library also unintentionally made the imagined behavior of execute="#all" possible via its later introduced partialSubmit="true" feature whereby you explicitly specify all other forms like below (the PFS #(form) is just for simplification, a hardcoded collection like :formId1 :formId2 :formId3 etc is also just possible).
<p:commandButton ... process="#(form)" partialSubmit="true" />
This works because partialSubmit="true" prepares the process="xxx" at client side rather than server side. In other words, instead of sending the entire enclosing form from server to client and then processing the specified inputs, it sends only the specified inputs from server to client and then processes them all. Do note that when partialSubmit is absent or set to false, then it would still only send the enclosing form. This misbehavior should rather not be relied upon. They may fix this misbehavior on their side sooner or later.
See also:
Any significant technical difference between JSF non-AJAX submit and a "#all" AJAX submit?
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
Here is a quote from JavaServer Faces 2.0 - The complete reference, page 352:
The execute and render keywords accept a set of special keywords, each with the meaning shown in this table:
#all (using with execute): Every component on the page is submitted and processed. This is useful when you want to do a full-page submit.
I think this quite clearly states that the fields from all forms should be submitted with the AJAX request.
However, even with Mojarra 2.0.3 this doesn't happen. Despite of contents of the execute attribute (whether you put a list of forms or #all) only the enclosing form gets its' fields submitted. So this seems like a bug. I am raising an issue about this unless there are altering views?
It would have to be execute=":form1 form2" (if you have the default separator), but anyway no, it doesn't. It only sends the second one.
If you put #all in the first form, it only sends the first. At least on Safari 5/Firefox 3.6.3 anyway. I guess one would have to look at the mojarra javascript to find out more.
Have you tried this?
<f:ajax execute="form1 form2" />
Does it send both forms' data if you explicitly mention them?
AFAIK, you are right: #all represents the whole page.

Resources