JSF 2.0 buttons click problems

Problem

It is not a discovery, but when you do not know this it can be frustrating.

If you notice that your buttons (h:commandButton or a4j:commandButton) do not response on first click, when you must click two time (double click) to perform an action, this may be a solution for you.

The problem may be caused by form you rendered earlier than click or you rendered element that contains that form.

The case can be like this

<h:form id="rendered"> <!--(1)-->
 <h:commandButton id="button" value="click me twice"/> <!--(2)-->
</h:form>
<h:form> <!--(3)-->
 <a4j:commandButton id="action" action="#{view.action}" render="rendered"/> <!--(4)-->
</h:form>

(1) – FORM THAT LOOSES ITS STATE AFTER “ACTION” BUTTON CLICK
(2) – BUTTON THAT MUST BE CLICKED TWICE TO SEND ACTION REQUEST
(3) – OTHER FORM
(4) – BUTTON THAT WILL RE-RENDER MAIN FORM

or other case

<h:panelGroup id="rendered"> <!--(1)-->
 <h:form><!--(2)-->
  <h:commandButton id="button" value="click me twice"/><!--(3)-->
 </h:form>
</h:panelGroup>
<h:form> <!--(4)-->
 <a4j:commandButton id="action" action="#{view.action}" render="rendered"/><!--(5)-->
</h:form>

(1) – ELEMENT THAT CONTAINS MAIN FORM BUT WILL BE RE-RENDER
(2) – FORM THAT LOOSES ITS STATE AFTER “ACTION” BUTTON CLICK
(3) – BUTTON THAT MUST BE CLICKED TWICE TO SEND ACTION REQUEST
(4) – OTHER FORM
(5) – BUTTON THAT WILL RE-RENDER ELEMENT THAT CONTAINS MAIN FORM

Analyze request

In firebug or other development tool that records requests you can analyze this problem in POST parameters of the request.
After form re-rendering first request on first click will not have javax.faces.ViewState parameter.

rendered rendered
rendered:button click me twice

second request on second click will have this parameter.

javax.faces.ViewState -7190851117743915418:1300621591202567154
rendered rendered
rendered:button click me twice

This is how you can diagnose problem tiwh view state.

Solution

Main cause of this problem is that h:form looses its view state (javax.faces.ViewState). You rendered it first time when page is loaded, and then you re-render this form when you clicked at “action” button, so it is not the same form “rendered” you wanted to react.

Solution is to load all forms (h:form) once per page load. In other words you must render elements elements that is inside form. To solve example problem I just add h:pandelGroup inside form, and named it with form id.

 <h:form>
  <h:panelGroup id="rendered">
   <h:commandButton id="button" value="click me twice"/>
  </h:panelGroup>
 </h:form>
<h:form>
 <a4j:commandButton id="action" action="#{view.action}" render="button"/>
</h:form>

References

http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#AjaxRenderingOfContentWhichContainsAnotherForm

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s