ChristopherS
ChristopherS

Reputation: 883

selectBooleanCheckbox doesn't initiate viewstate id

I have a backing bean which is ViewScoped. I have some ajax enabled SelectBooleanCheckboxes in a form. Example:

<p:selectBooleanCheckbox value="#{formBean.value2}">  
    <p:ajax update=":theform"/>  
</p:selectBooleanCheckbox>

Normally, some hidden input fields should be in the html to pass through the viewstate id. The problem is that those don't get initiated on the first page request. When I click one of the checkboxes, the form (and thus the checkboxes) get refreshed. From this moment the view state id is being sent with those checkboxes so the viewstate can be preserved.

The biggest problem in this is that on the first ajax call a set of new ViewScoped beans is initiated and so I lose data about the first action. From then on everything seems to work properly.

Can anyone give me any directions on what might be the problem?

The exact code:

        <p:panel header="Schedule" toggleable="true">
            <form>
                <p:outputPanel id="schedule">
                    <ui:repeat var="scheduleDay" value="#{jobBean.jobScheduleDays}">
                        <div>
                            <p:selectBooleanCheckbox value="#{scheduleDay.selected}" style="margin:4px">
                                <p:ajax update=":schedule" />
                            </p:selectBooleanCheckbox>
                            <h:outputText value="#{scheduleDay.readableDay}" style="text-transform:capitalize"/>
                        </div>
                    </ui:repeat>
                </p:outputPanel>
            </form>
        </p:panel>

Upvotes: 0

Views: 340

Answers (1)

BalusC
BalusC

Reputation: 1108642

Your problem is caused by using plain HTML <form> instead of JSF <h:form>. The <h:form> will not only generate the right HTML <form> element with the proper method and action URL set, but it also takes care of generating two additional hidden fields identifying the form being submitted and the JSF view state identifier.

E.g.

<h:form id="foo">

generates

<form id="foo" name="foo" action="ViewHandler#getActionURL()" method="post">
    <input type="hidden" name="foo" value="foo" />
    <input type="hidden" name="javax.faces.ViewState" value="..." />

(the form action URL is filled with result of ViewHandler#getActionURL())

That the plain HTML <form> works with JSF ajax requests is because they don't exactly use the form element to send the HTTP POST request, but instead uses JavaScript's XMLHttpRequest object to send the HTTP POST request whose parameters are been populated by traversing the input elements in the parent form using JavaScript's form.elements. The JSF ajax response will automatically update the JSF view state hidden field, that's why JSF will be able to process the form submit from the 2nd request and on.

However, using plain HTML <form> would have failed hard when using non-ajax requests.

Upvotes: 3

Related Questions