selectBooleanCheckbox doesn't initiate viewstate id - jsf-2

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>

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.

Related

JSF Validation error not printed in open dialog

I have to validate that a field in a form is not empty.
The problem is that the form is in a JQueryUI dialog (since I don't know how to create "windows" in JSF), so when I click the commandButton the page is refreshed and the JQuery dialog is lost. After refreshing, I can see the error message was printed in the page code by looking at the source code. If I use ajax in the commandButton then the page is not refreshed but I don't get the message printed, I got it as a sort of "Javascript alert" in the browser.
How can I get the error message without refreshing the page?
<h:inputText value="#{myController.name}" id="myname" required="true" requiredMessage="Name required">
<f:ajax />
</h:inputText>
<h:message errorClass="..." for="myname" />
Note: This looked similar to my problem but I don't think the solution is what I'm looking for.
Note: I am not using additional libraries like Primefaces, etc
With the hint of the comment, I was able to solve it this way:
In the commandButton, use ajax with both render and execute (render only doesn't work):
<h:commandButton id="...." action="#{myController.doSomething()}" type="submit" value="Do something">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
Create a "pageUpdate()" method in myController that is called at the end of myController.doSomething(). This way, after the actions, the page is refreshed and the dialog is gone. There are of course other ways to close the dialog, but it is convenient for me to update the page when there is no error in the dialog action, so my objects in memory are updated too.
I think JQuery dialog messes with my styles after the ajax call returns with error, so check that out if you do it.

Ensure that a particular value is submitted with every form / AJAX request

Is there any way to ensure that, along with any other fields that are being submitted, one particular field (a hidden input) on the page is submitted with every form / AJAX submission? For example, if I have
<input type="hidden" id="submitted-value" value="some value"/>
somewhere on the page, and another form, say
<h:form>
<h:inputText value="#{someBean.value}"/>
</h:form>
Is there any way of modifying the submitted data before it is submitted to include the submitted-value field?

JSF2 Dynamic form is not being submitted

I have a form that is defined in a separate jsf page. This is is included to the main page when i click a link. Now the form is being displayed correctly. But the problem is that the submit button is not calling the action function defined.
The code to include the page( As suggested in this question: JSF2 Dynamically loading pages by ajax
<h:panelGroup id="editdivparent" layout="block">
<h:panelGroup id="editdiv" rendered="#{formsBean.edituserdiv}" layout="block">
<h:form id="userform" class="form-horizontal">
<ui:include src="edituserdetails.xhtml">
</ui:include>
</h:form>
</h:panelGroup>
</h:panelGroup>
The included page contains just the form elements with submit button:
<h:commandButton action="#{userBean.register() }" value="Update">
</h:commandButton>
I am getting no errors. On submitting the form the current page is redisplayed. I have put some print statements in the action function. Also there is a query error is put. None of them are being generated.
Am i doing something wrong here?
The commandButton action property already expects a method expression, so just take the parenthesis out, like this:
<h:commandButton action="#{userBean.register}" value="Update" />
Also, make sure you don't have nested forms when making templates with includes.
I hope it helps.

JSF not firing bean setters when using f:ajax

This is an update on a previous post I made regarding conditional rendering of page components. I can now conditionally render different components on the page based on selected user inputs using the f:ajax tag. The trouble is that when I click my commandbutton the inputs that are conditionally rendered using ajax aren't being read on submit. I am guessing it is because the whole page isn't rerendered when I add in the new components and the submit button can't see them, even though they are there. Here is the segment of my form page(it is wrapped in a h:form tag):
<h:outputLabel for="selectPersonType" value="Select Type: "/>
<h:selectOneMenu id="selectPersonType" value="#{addPersonBean.personType}" label="Person Type" required="true">
<f:selectItem itemValue=""/>
<f:selectItems value="#{listBean.personTypes}" />
<f:ajax render="results"/>
</h:selectOneMenu>
<h:message for="selectPersonType" style="color: red"/>
</h:panelGrid>
<h:panelGroup id="results">
<h:panelGroup rendered="#{addPersonBean.personType == 'STUDENT'}">
<h:outputLabel for="selectSchoolType" value="School Type: " />
<h:selectOneMenu id="selectSchoolType" value="#{addPersonBean.schoolType}">
<f:selectItems value="#{listBean.schoolTypes}" />
<f:ajax execute="selectSchoolType"/>
</h:selectOneMenu>
</h:panelGroup>
<h:panelGroup rendered="#{addPersonBean.personType == 'PATIENT'}">
<h:outputLabel for="smoker" value="Smoker? " />
<h:selectBooleanCheckbox id="smoker" value="#{addPersonBean.smoker}">
<f:ajax execute="smoker"/>
</h:selectBooleanCheckbox>
</h:panelGroup>
</h:panelGroup>
<h:commandButton value="Add Person" action="#{addPersonBean.action}"/>
The trouble here is that the components with ids 'selectSchoolType' and 'smoker's values don't get set when I click the commandButton because they are rendered conditionally using the selectPersonType select menu after the page has loaded. Is there a way to fire the components when their values change instead of when I click the submit button (therefore, their values should be processed before I even click submit). As you can see I have tried to use f:ajax with the execute attribute attached to the components in question but it didn't seem to work. (I believe the default events for these components are valueChange so haven't added them to the f:ajax tags, but I have tried 'change' and 'valueChange').
All your <f:ajax> things are inside a conditionally rendered component. This construct will fail when the condition behind rendered attribute evaluates to false during processing the form submit. This will happen when the #{addPersonBean} is in the request scope and doesn't preinitialize the condition behind the rendered attribute during (post)construction, or when it's performing business logic in getters/setters in a wrong way.
Placing the #{addPersonBean} in the view scope and ensuring that you aren't doing business logic in getters/setters should fix this problem.
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated - point 5 applies to you
How to choose the right bean scope?

Explicit url redirect in JSF 2.0

I have the following two pages below.
hello.xhtml, rendered by .../hello.jsf url.
<h:form>
<h:commandButton id="submit" value="Submit" action="response"/>
</h:form>
response.xhtml, rendered by .../response.jsf url.
<h:form>
<h:commandButton id="back" value="Back" action="hello"/>
</h:form>
When Submit button is clicked, the hello page is redirected to the response page but the url remains the same, i.e., the url is still .../hello.jsf.
I'd like the url to be .../response.jsf after the Submit button is clicked. Any help, please?
Many thanks!
If you are actually not using old fashioned JSF navigation cases as implied by kolossus, but are instead using new JSF2 implicit navigation feature, then just add faces-redirect=true query string parameter to the outcome.
<h:form>
<h:commandButton id="submit" value="Submit" action="response?faces-redirect=true" />
</h:form>
However, if you don't need to invoke any bean action at all, and intend to use plain page-to-page navigation, then it makes no sense to perform a POST request for this. Just use the <h:button> then.
<h:button id="submit" value="Submit" outcome="response" />
See also:
Difference between h:button and h:commandButton
When should I use h:outputLink instead of h:commandLink?
Add the redirect attribute to your faces_config.xml file like so:
<navigation-rule>
<from-view-id>/hello.xhtml</from-view-id>
<navigation-case>
<from-outcome>response</from-outcome>
<to-view-id>/response.xhtml</to-view-id>
<!--the redirect element -->
<redirect/>
</navigation-case>
</navigation-rule>
EDIT: I got the impression that you're using a faces-config.xml from your navigation outcome styling. I have confirmed personally that what you're doing is also permissible for the new JSF 2 style navigation. See BalusC's answer for using the redirect url parameter in a JSF2-style navigation handling

Resources