Boolean value in backing bean not updated with ajax call - java

I'm trying to set the value in the backing bean based on the checkbox selection.
Here is the Checkbox:
...
<f:view>
<p:panel header="HEADER">
<p:selectBooleanCheckbox id="TEST_CB" itemLabel="TEST CB"
value="#{myBB.test}">
<p:ajax execute="#this" update="someComponent"/>
</p:selectBooleanCheckbox>
...
In the backing bean, I have a boolean property test with public getter and setter.
When I click on the checkbox, the setter in the backing bean is called(so far so good), but the value which is passed as a parameter is always false.
I've been messing with it for two hours, trying different combinations of p:ajax parameters, immediate and partial on the p:selectBooleanCheckbox, I've also tried using h:selectBooleanCheckbox, but it is still false.
I use Apache MyFaced 2.1.10 and Primefaces 3.5

The button was not in the form.
After adding <h:form> tag, everything is ok.

Related

ui:include dependent on viewParam

I have a page where I want to include a part of the page (footer in this instance) dependant on values given from a view parameter.
I have my ViewScoped backing bean initializing on preRenderView
<f:metadata>
<f:viewParam name="racecode" value="#{displayResults.racecode}" />
<f:event type="preRenderView" listener="#{displayResults.init}" />
</f:metadata>
This queries the database to get the name of the footer to be included. This then, is used in this fashion :
<h:panelGroup id="customFooter" display="block">
<ui:include src="#{displayResults.customFooter}" />
</h:panelGroup>
This always gives me a missing page. But if I enter the page name manually it works. Same if I replace the ui:include with an h:outputText.
I understand that it has something to do with the phases of JSF and that at the time the ui:include is done, the value is not set yet. (reading up and better understanding the phases is something on my TODO list).
The question remains. How can I get something of the sort done. Have a bean use the viewParam, query the database and use that value in a ui:include?
#wemu has already explained the cause. The <ui:include src> is evaluated before init() method is called. His proposed <f:phaseListener> solution is however clumsy.
Just use #ManagedProperty/#PostConstruct on a #RequestScoped bean.
#ManagedProperty("#{param.racecode}")
private String racecode;
#PostConstruct
public void init() {
// ...
}
PreRenderView listeners are called within the RenderResponsePhase, before components are rendered BUT AFTER the TagHandlers are called. This means that TagHandlers will NOT see data initialized within a PreRenderView event.
If you are using a <ui:include value="#{myBean.myViewId}" /> to dynamically switch an include you can't use a PreRenderView event listener to set the myViewId property of myBean.
If you need to do that use a <f:phaseListener>.

How can I reset JSF UIInput components to their managed bean values

I want to reset JSF inputs to their original managed bean values after validation failed.
I have two forms inside the same page - the first form has a commandLink to initialize the second form. The second form is rendered as a dialog whose visibility is toggled through jQuery - for the purpose of this exercise, though, I can illustrate just with two forms on the same page. Also, while I'm using PrimeFaces 2.2.x in my app, the same behaviors appear with regular h:commandLink as well.
The issue I'm having is:
click link in first form to initialize second form
submit invalid values in second form
click link in first form again to initialize second form - invalid values still there and/or UIInput state is still invalid.
For example - take the following form
<h:form id="pageForm">
<h:commandLink actionListener="#{testBean.initialize}">Initialize, no execute
<f:ajax render=":dialogForm"/>
</h:commandLink>
<br/>
<h:commandLink actionListener="#{testBean.initialize}">Initialize, execute=#this
<f:ajax execute="#this" render=":dialogForm"/>
</h:commandLink>
</h:form>
<h:form id="dialogForm">
<h:messages/>
String property - Valid: <h:outputText value="#{property.valid}"/>
<br/>
<h:inputText id="property" binding="#{property}" value="#{testBean.property}">
<f:validateLength minimum="3"/>
</h:inputText>
<br />
Int property - Valid: <h:outputText value="#{intValue.valid}"/>
<h:inputText id="intValue" binding="#{intValue}" value="#{testBean.intValue}">
<f:validateLongRange maximum="50" />
</h:inputText>
<br/>
<h:commandLink actionListener="#{testBean.submit}">
Submit
<f:ajax render="#form" execute="#form"/>
</h:commandLink>
<h:commandLink actionListener="#{testBean.initialize}">Initialize, execute=#this
<f:ajax execute="#this" render="#form"/>
</h:commandLink>
</h:form>
Bean class:
#ManagedBean
#ViewScoped
public class TestBean {
private String property = "init";
private Integer intValue = 33;
// plus getters/setters
public void submit() { ... }
public void initialize() {
intValue = 33;
property = "init";
}
}
Behavior #1
click either "Initialize" link on the pageForm
inputs get initialized to "init", "33"
now submit something invalid for both fields like "aa", "99"
now click any of the "initialize" links again (they all seem to behave the same - makes no difference whether it's in the same form or different, or whether I have specified execute="#this" or not.)
Result => UIInput.isValid() = false, both values reset though ("init", "33").
Expected => valid = true (or is this not reasonable to expect?)
Behavior #2
click either "Initialize" link on the pageForm
inputs get initialized to "init", "33"
now submit something invalid for the text field but valid for the int field ("aa", "44")
now click any of the "initialize" links again
Result => "init", valid=false; 44, valid=true
Expected => "init", valid=true; 33, valid=true
I have also looked at:
JSF 2 - Bean Validation: validation failed -> empty values are replaced with last valid values from managed bean
and
How can I populate a text field using PrimeFaces AJAX after validation errors occur?
The suggestion to explicitly reset the state of UIInputs with resetValue does work, but I'm not happy with it.
Now, I sort of understand why the isValid is not resetting - my understanding of the JSF lifecycle is that once a value is submitted to a component, isValid is not reset until the component is successfully submitted and validated and the Update Model Values phase sets the bean value. So there may be no way around explicitly resetting the valid state in this case, since I want to use #{foo.valid} for conditional CSS styling.
What I don't understand, though, is why the components that successfully validated are not re-initializing from the bean. Perhaps my understanding of the JSF lifecycle is slightly off?
I understand the rules layed out in the answer to How can I populate a text field using PrimeFaces AJAX after validation errors occur? as they pertain to an individual component but not to the form as a whole - i.e., what happens if a component succeeds validation but the validation overall fails?
In fact, there may turn out to be no better way than explicitly calling resetValue on components. In my case, all of the dialogs are in the same big JSF view tree with the underlying page that opens them. So from JSF's perspective, the same view component state including invalid input values should be preserved until we navigate away from the view, as it has no visibility into how we're toggling display attributes client-side.
The only other thing that might work is if the components that make up the dialog are actually not rendered in the JSF view tree unless they're visible. In my case, they're always rendered, using CSS to toggle visibility.

h:commandLink not working when inside a list

I have a problem with RichFaces and creating lists of links. If you attempt to use any type of commandLink inside a list (I've tried ui:repeat and rich:list) the action on that link is not called. I've also tried commandButton and the a4j variations of those. I'm using JSF 2, RichFaces 4 on Jboss 6.
<rich:list var="venue" value="#{searchManager.results}" type="definitions" stateVar="status">
<h:form>
<h:commandLink value="CLICK IT" immediate="true" action="#{score.selectVenue}" />
</h:form>
</rich:list>
The position of the form also doesn't matter.
<h:form>
<rich:list var="venue" value="#{searchManager.results}" type="definitions" stateVar="status">
<h:commandLink value="CLICK IT" immediate="true" action="#{score.selectVenue}" />
</rich:list>
</h:form>
If I just have the link by itself (no list) it works.
Any help would be greatly appreciated.
When you click a command link or press a command button to submit a form, JSF will during the apply request values phase scan the component tree for the command link/button in question so that it can find the action expression associated with it, which is in your case #{score.selectVenue}.
However to be able to ever reach that, you would need to ensure that #{searchManager.results} returns exactly the same list as it did when the form was displayed. Because with an empty result list, there would be no command link/button in the view at all during the apply request values phase of the form submit.
Your #{searchManager} bean seems to be request scoped. Request scoped beans have a lifetime of exactly one request-response cycle. So when you submit the form, you'll get a brand new and another instance of the request scoped bean than it was when the form was displayed. The results property seems not to be preserved during (post)construction of the bean and thus remains empty. So JSF cannot find the command link/button in question and thus cannot find the action expression associated with it and thus cannot invoke it.
As you're using JSF2, an easy fix is to place the bean in the view scope. This way the bean will live as long as you're submitting and navigating to exactly the same view by returning null or void in action methods.
#ManagedBean
#ViewScoped
public class SearchManager {
// ...
}
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated

Get the value that has been selected in the selectOneMenu ListBox

This is how my JSF looks like.
<h:selectOneMenu value="#{HotelDataForm.listHotel}">
<f:selectItems value="#{HotelDataForm.listHotel}" var="user" itemValue="#{user[1]}" itemLabel="#{user[1]}" />
</h:selectOneMenu>
I need to get the value selected in my ListBox to my Java code, so i could write a business logic using it. So how do i get the value selected in the ListBox to my java code.
<h:selectOneMenu value="#{HotelDataForm.selectedHotel}">
The value-attribute of selectOneMenu is the setter that is invoked with the value of the selected item as a parameter. So in your bean, the method setSelectedHotel() is called.
In your code, you set the value to the list of items.

JSF: Selecting value in one drop down enables another drop down

Lets say I have two selectOneMenu drop-downs:
Drop-down A:
<h:selectOneMenu value="valA"
immediate="false"
required="true"
valueChangeListener="#{JavaClass.someJavaMethod}"
id="caImplClassSelector"
rendered="#{JavaClass.someOtherMethod}">
Drop-down B:
<h:selectOneMenu value="valB"
immediate="false"
required="true"
valueChangeListener="#{JavaClass.someJavaMethod}"
id="caImplClassSelector"
disabled="what should I write here?"
rendered="#{JavaClass.someOtherMethod}">
How can I make sure that drop down B is disabled until a user selects a value in drop down A? I can make a method within the JavaClass that returns true or false depending on if a value in drop-down A has been selected or not, but is there any way to do the above wihout making that method?
Any help would be appreciated.
I have no idea what JSF/RF versions you are using, so here's just a generic answer.
Bind the value of the 1st dropdown to a bean property:
<h:selectOneMenu value="#{bean.firstMenu}">
Then let the disabled attribute of the 2nd dropdown intercept on that:
<h:selectOneMenu disabled="#{bean.firstMenu == null}">
Note that with JSF2/RF4 you don't need the valueChangeListener/immediate hacks which are been used in old ajaxless JSF 1.x versions.
Declare a boolean property in your managed bean and generate the getter and setter methods for it.
By default set it to true.
In <h:selectOneMenu value="valA"
immediate="false"
required="true"
valueChangeListener="#{JavaClass.someJavaMethod}"
id="caImplClassSelector"
rendered="#{JavaClass.someOtherMethod}">
In the first drop down based on application logic on the value change listener set the disabled property to false.
In the second drop down refer to the disabled property.
There could be some additional logic that you may have to handle.

Categories