As already said Primefaces Captcha component can't be updated by ajax request. But there is a simple solution - update everything but not Captcha component itself.
Your XHTML:
<h:form id="myForm">
<h:panelGroup id="updateFormAllValuesButNotCaptcha">
Name: <p:inputText id="name" value="#{captchaBean.name}" required="true"/>
<br/>
Comment: <p:inputTextarea id="comment" value="#{captchaBean.comment}" required="true"/>
<br/>
</h:panelGroup>
<p:captcha/>
<p:commandButton value="click me" update="updateFormAllValuesButNotCaptcha"
actionListener="#{captchaBean.someAction}" oncomplete="Recaptcha.reload()"
onerror="Recaptcha.reload()"/>
</h:form>
<p:messages globalOnly="false" autoUpdate="true"/>
Your backing bean:
@ManagedBean
@ViewScoped
public class CaptchaBean implements Serializable {
private String name;
private String comment;
public String getComment() { return comment; }
public void setComment(String comment) { this.comment = comment; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public void someAction() {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Done", "");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
Note that I am updating updateFormAllValuesButNotCaptcha
panel which contains all form input fields but not Captcha itself. It is also important to notice that Captcha can't be reused, so you have to reload it always when ajax request has been completed or ended with error.
What you update after commandButton's action succeeded is up to you. You can hide form (do not render it) and show only confirmation message to make sure user won't try to send comment again.