http://stackoverflow.com/questions/25339056/understanding-process-and-update-attributes-of-primefaces
process
The process
attribute is server side and can only affect UIComponent
s implementing EditableValueHolder
(input fields) or ActionSource
(command fields). The process
attribute tells JSF by a spaceseparated collection of client IDs which components exactly must be processed through the entire JSF lifecycle upon (partial) form submit. This covers applying the request values (finding HTTP request parameter based on component's own client ID and then either setting it as submitted value in case of EditableValueHolder
components or queueing a new ActionEvent
in case of ActionSource
components), performing conversion, validation and updating the model values (EditableValueHolder
components only) and finally invoking the queued ActionEvent
(ActionSource
components only). JSF will skip processing of all other components which are not covered by process
attribute.
Note that it's in case of ActionSource
components (such as <p:commandButton>
) very important that you also include the component itself in the process
attribute, particularly if you intend to invoke the action associated with the component. So the below example which intends to process only certain input component(s) when a certain command component is invoked ain't gonna work:
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="foo" action="#{bean.action}" />
It would only process the #{bean.foo}
and not the #{bean.action}
. You'd need to include the command component itself as well:
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@this foo" action="#{bean.action}" />
Or, as you apparently found out, using @parent
if they happen to be the only components having a common parent:
<p:panel><!-- Type doesn't matter, as long as it's a common parent. -->
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@parent" action="#{bean.action}" />
</p:panel>
Or, if they both happen to be the only components of the parent UIForm
component, then you can also use @form
:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@form" action="#{bean.action}" />
</h:form>
This is sometimes undesirable if the form contains more input components which you'd like to skip in processing, more than often in cases when you'd like to update another input component(s) or some UI section based on the current input component in an ajax listener method. You namely don't want that validation errors on other input components are preventing the ajax listener method from being executed.
Then there's the @all
. This has no special effect in process
attribute, but only in update
attribute. A process="@all"
behaves exactly the same as process="@form"
. HTML doesn't support submitting multiple forms at once anyway.
There's by the way also a @none
which may be useful in case you absolutely don't need to process anything, but only want to update some specific parts via update
, particularly those sections whose content doesn't depend on submitted values or action listeners.
The standard JSF equivalent to the PrimeFaces specific process
is execute
from <f:ajax execute>
. It behaves exactly the same expect that it doesn't support a commaseparated string while the PrimeFaces one does (although I personally recommend to just stick to spaceseparated convention). Also, it may be useful to know that <p:commandXxx process>
defaults to @form
while <p:ajax process>
and <f:ajax execute>
defaults to @this
. Finally, it's also useful to know that process
supports the so-called "PrimeFaces Selectors", see also How do PrimeFaces Selectors as in update="@(.myClass)" work?
update
The update
attribute is client side and can affect the HTML representation of all UIComponent
s. The update
attribute tells JavaScript (the one responsible for handling the ajax request/response) by a spaceseparated collection of client IDs which parts in the HTML DOM tree need to be updated as response to the form submit. JSF will then prepare the right ajax response for that, containing only the requested parts to update. JSF will skip all other components which are not covered by update
attribute in the ajax response, hereby keeping the response payload small.
Usually, you'd like to update only the components which really need to be "refreshed" in the client side upon (partial) form submit. The example below updates the entire parent form via @form
:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" required="true" />
<p:message id="foo_m" for="foo" />
<p:inputText id="bar" value="#{bean.bar}" required="true" />
<p:message id="bar_m" for="bar" />
<p:commandButton action="#{bean.action}" update="@form" />
</h:form>
(note that process
attribute is omitted as that defaults to @form
already)
Whilst that may work fine, the update of input and command components is in this particular example unnecessary. Unless you change the model values foo
and bar
inside action
method (which would in turn be unintuitive in UX perspective), there's no point of updating them. The message components are the only which really need to be updated:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" required="true" />
<p:message id="foo_m" for="foo" />
<p:inputText id="bar" value="#{bean.bar}" required="true" />
<p:message id="bar_m" for="bar" />
<p:commandButton action="#{bean.action}" update="foo_m bar_m" />
</h:form>
However, that gets tedious when you have many of them. That's one of the reasons why PrimeFaces Selectors exist. Those message components have in the generated HTML output a common style class of ui-message
, so the following should also do:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" required="true" />
<p:message id="foo_m" for="foo" />
<p:inputText id="bar" value="#{bean.bar}" required="true" />
<p:message id="bar_m" for="bar" />
<p:commandButton action="#{bean.action}" update="@(.ui-message)" />
</h:form>
(note that you should keep the IDs on message components, otherwise @(...)
won't work! Again, see How do PrimeFaces Selectors as in update="@(.myClass)" work? for detail)
The @parent
updates only the parent component, which thus covers the current component and all siblings and their children. This is more useful if you have separated the form in sane groups with each its own responsibility. The @this
updates, obviously, only the current component. Normally, this is only necessary when you need to change one of the component's own HTML attributes in the action method. E.g.
<p:commandButton action="#{bean.action}" update="@this"
oncomplete="doSomething('#{bean.value}')" />
Imagine that the oncomplete
needs to work with the value
which is changed in action
, then this construct wouldn't have worked if the component isn't updated, for the simple reason that oncomplete
is part of generated HTML output (and thus all EL expressions in there are evaluated during render response).
The @all
updates the entire document, which should be used with care. Normally, you'd like to use a true GET request for this instead by either a plain link (<a>
or <h:link>
) or a redirect-after-POST by ?faces-redirect=true
or ExternalContext#redirect()
. In effects, process="@form" update="@all"
has exactly the same effect as a non-ajax (non-partial) submit. In my entire JSF career, the only sensible use case I encountered for @all
is to display an error page in its entirety in case an exception occurs during an ajax request. See also What is the correct way to deal with JSF 2.0 exceptions for AJAXified components?
The standard JSF equivalent to the PrimeFaces specific update
is render
from <f:ajax render>
. It behaves exactly the same expect that it doesn't support a commaseparated string while the PrimeFaces one does (although I personally recommend to just stick to spaceseparated convention). Both update
and render
defaults to @none
(which is, "nothing").