Rendering other form by ajax causes its view state to be lost, how do I add this back? Rendering other form by ajax causes its view state to be lost, how do I add this back? ajax ajax

Rendering other form by ajax causes its view state to be lost, how do I add this back?


This is a known problem in the auto-included jsf.js library of JSF which handles ajax responses. See also JSF spec issue 790 which is fixed in the upcoming JSF 2.3. In the meanwhile, with JSF 2.0/2.1/2.2, you have to explicitly specify the ID of the other <h:form> inside the render attribtue to trigger proper addition of the view state.

<h:form>    <h:commandLink action="#{my_fake_ajax_link}">        <h:outputText value="Link" />        <f:ajax render=":mydiv :mydivForm" />    </h:commandLink></h:form><h:panelGroup layout="block" id="mydiv">    <h:form id="mydivForm">        <h:commandLink action="#{mybean.delete(0)}">            <h:outputText value="Here" />            <f:ajax render="@form" />        </h:commandLink>    </h:form></h:panelGroup>

No, this does not cause any overhead or markup duplication in the ajax response. Alternatively, use OmniFaces fixviewstate.js.

See also:


Workaround for that:

First you need to set an onevent handler for the button that sends the ajax request:

<h:form id="newComment">    <h:commandButton id="saveNewComment" action="#{postBean.actionSaveNewCommentAjax}" value="#{rb['speichern']}">        <f:ajax execute="@form" render=":commentsBox" onevent="function(data) { fixOtherFormsViewState(data, 'newComment') }" />    </h:commandButton></h:form>

Then you need to declare this javascript methods that will take the correct viewState value and add it to all forms which doesn't have it:

<h:outputScript>function fixOtherFormsViewState(data, goodFormId) {    if (data.status != "success") {        return;    }    var viewState = jQuery("#" + goodFormId + " input[name='javax.faces.ViewState']").val();    jQuery("form:not(:contains(input[name='javax.faces.ViewState']))").each(function (idx, elem) {        var form = jQuery(elem);        var input = jQuery("<input type='hidden' name='javax.faces.ViewState' />").val(viewState);        form.append(input);    });}</h:outputScript>