10
votes

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..

4
This one has me stumped. If execute="@form" execute's all inputs within the form, one would assume @all would do more than the form, ie. all the forms.Brian Leathem
The JIRA cases noted are closed as incomplete, and works as designed.John Yeary

4 Answers

9
votes

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:


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:

4
votes

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?

1
votes

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.

0
votes

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.