2

Is it possible to conditionally update JSF components only when validation succeeds?

I would like to be able to do something like

<p:commandLink process="@form" listener="#{foo}" 
  update="something somethingElse"> 

where "something" only gets updated if validation is successful.

Is there any way that can be done or is that just not supported in JSF?

I've been able to rig up kind of a hack with hidden commandLinks but not entirely satisfied:

<p:commandLink process="@form" listener="#{foo}" 
  update="somethingElse" oncomplete="if (!args.validationFailed) $("#link").click();">
<p:commandLink style="display:none" id="link"
  update="something">
wrschneider
  • 17,913
  • 16
  • 96
  • 176

2 Answers2

3

I don't think the message suggestion necessarily answers the question asked. Suppose he wants to update something OTHER than a message?

I've not tried this myself, but another approach that might work is to use remotecommand.

<p:remoteCommand id='good' update='goodUpdates'/>  
<p:remoteCommand id='bad' update='badUpdate'/>  
<p:commandButton oncomplete='if (your-test) good() else bad()'/>  

Note, this would necessitate another round-trip to the server and thus performance is a consideration.

DaBlick
  • 898
  • 9
  • 21
2

The <h:message> (or PrimeFaces' counterpart <p:message>) is intented for this. Or, in your case maybe better, the <h:messages> (or <p:messages>).

public void submit() {
    // ...

    if (fail) {
        FacesContext.getCurrentInstance().addMessage(null, 
            new FacesMessage(FacesMessage.SEVERITY_ERROR, "Fail", null));
    }
}

with

<h:messages id="messages" />
<p:commandLink process="@form" action="#{bean.submit}" update="messages something" />

Note that you're as well supposed to use a normal Validator implementation to perform the validation. If it throws a ValidatorException, then the action won't be invoked anyway. Doing validation inside action method is a smell.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I'm trying to do the opposite: update something only when validation is successful. – wrschneider Mar 09 '12 at 20:53
  • 1
    Do the same, but then use `SEVERITY_INFO` with a "Success" message instead. The action method won't be invoked anyway when the validation has failed. An alternative is to let the action method set some property and use `rendered="#{not empty bean.someProperty}"`. – BalusC Mar 10 '12 at 02:08
  • Another variation on @BalusC last suggestion: `FacesCopntext.getPartialViewContext().getRenderIds().add("updateComponentId")` in the action listener. Only executed if validation succeeds. – wrschneider Mar 28 '12 at 13:44
  • Can you please elaborate with the code.. I am not able to understand the how to update conditionally basically when validation fail I want to update 2 components but If validation got success I want to update 3 component... 2 previous and one extra.. Kindly help\ – Dhruv Jun 15 '12 at 11:08
  • I don't think the `message` suggestion necessarily answers the question asked. Suppose he wants to update something OTHER than a `message`? I've not tried this myself, but another approach that might work is to use `remotecommand`. – DaBlick May 20 '15 at 13:00