• cdi
  • components
  • contexts
  • converters
  • el
  • eventlisteners
  • exceptionhandlers
  • facesviews
  • filters
  • functions
  • managedbeans
  • push
  • resourcehandlers
  • scripts
  • servlets
  • taghandlers
  • utils
  • validators
  • viewhandlers
 - FixViewState

Available since OmniFaces 1.0

This script fixes the JSF view state if necessary. In Mojarra, it get lost on certain forms during certain ajax updates (e.g. updating content which in turn contains another form). Normally, the jsf.js script adds the JSF view state back to the updated form, but it does that only for the enclosing form, not for other forms when they are not explicitly specified in the render/update attribute. When this script is loaded after the standard jsf.js script containing standard JSF ajax API, then it will be automatically applied on all JSF ajax requests.

 <h:outputScript library="javax.faces" name="jsf.js" target="head" />
 <h:outputScript library="omnifaces" name="fixviewstate.js" target="head" />

This script also recognizes jQuery ajax API as used by some component libraries such as PrimeFaces. If jQuery is present, then it will also be automatically applied on all jQuery ajax requests.

 <h:outputScript library="primefaces" name="jquery/jquery.js" target="head" />
 <h:outputScript library="omnifaces" name="fixviewstate.js" target="head" />

Explicit declaration of jsf.js or jquery.js via <h:outputScript> is not strictly necessary. You only need to make sure that the <h:outputScript> on fixviewstate.js is being placed inside the <h:body> so that you can ensure that it's loaded after the JSF and/or jQuery script.

 <h:head>
     ...
 </h:head>
 <h:body>
     <h:outputScript library="omnifaces" name="fixviewstate.js" target="head" />
     ...
 </h:body>

In case your JSF component library doesn't utilize standard JSF nor jQuery ajax API, but a proprietary one, and exposes the same "missing view state" problem, then you can still apply this script manually during the "complete" event of the ajax request whereby the concrete XMLHttpRequest instance is available as some argument as follows:

 function someOncompleteCallbackFunction(xhr) {
     OmniFaces.FixViewState.apply(xhr.responseXML);
 });

This was scheduled to be fixed in JSF 2.2 spec, however it was postponed to JSF 2.3. We can't wait any longer, so it's been added to OmniFaces. Note that this fix is not necessary for MyFaces as they have internally already fixed it for long in their jsf.js.

In the below demo, try to subsequently press the both buttons in turn as long until a faces message shows up. When the fixviewstate.js is not loaded, you'll notice that after the first time, you need to press the other button twice in order to see it. This problem is fixed by loading the fixviewstate.js.

Demo

FixViewState is disabled

Submit the both forms in turn until a message shows up

When FixViewState is disabled, you'll notice that after the first time, you've to press the other button twice in order to see the message.

Demo source code
<!-- Note: this is demo code. In real code, add target="head" attribute and remove rendered attribute. -->
<h:outputScript library="omnifaces" name="fixviewstate.js" rendered="#{param.fixviewstate}" />

<p>
    FixViewState is #{param.fixviewstate ? 'enabled' : 'disabled'} 
    <h:button value="#{param.fixviewstate ? 'disable' : 'enable'} it">
        <f:param name="fixviewstate" value="#{not param.fixviewstate}" />
    </h:button>
</p>

<h3>Submit the both forms in turn until a message shows up</h3>
<p>
    When FixViewState is disabled, you'll notice that after the first time, 
    you've to press the other button twice in order to see the message.
</p>
<h:panelGroup id="panel1" layout="block">
    <h:form id="form1">
        <h:commandButton value="submit form1 and update panel2" action="#{fixViewStateBean.submit1}">
            <f:ajax execute="@form" render=":panel2 :messages" />
            <f:param name="fixviewstate" value="#{param.fixviewstate}" />
        </h:commandButton>
    </h:form>
</h:panelGroup>
<h:panelGroup id="panel2" layout="block">
    <h:form id="form2">
        <h:commandButton value="submit form2 and update panel1" action="#{fixViewStateBean.submit2}">
            <f:ajax execute="@form" render=":panel1 :messages" />
            <f:param name="fixviewstate" value="#{param.fixviewstate}" />
        </h:commandButton>
    </h:form>
</h:panelGroup>
<h:messages id="messages" />
Documentation & Sources

JavaScript source code