h:selectOneMenu value is always null when submitting the form - jsf

I have a h:selectOneMenu which served me with no issues in the past but for some reason the value in searchResults.selectedCategories is always null when submitting the form.
The widget is inside a form. The backing bean has selectedCategories as a private String with accessor methods. I tried cleaning the project, closing down Eclipse, and republishing it to Tomcat. Nothing works. Any idea why?
This is the widget:
<h:selectOneMenu id="categoriesBoxSimple" value="#{searchResults.selectedCategories}" >
<f:selectItem itemLabel="Category 1" itemValue="283331" />
<f:selectItem itemLabel="Category 2" itemValue="281" />
<f:selectItem itemLabel="Category 3" itemValue="1115"/>
</h:selectOneMenu>

`Add`
<f:ajax listener="#{yourBean.ajaxChangeValue}" />
to h:selectOneMenu
<h:selectOneMenu value = "#{yourBean.numberValue}">
<f:selectItem itemValue="One" />
<f:selectItem itemValue="Two" />
<f:selectItem itemValue="Three" />
<f:ajax listener="#{yourBean.ajaxChangeValue}" />
</h:selectOneMenu>
YourBean.java
public void ajaxChangeValue(final AjaxBehaviorEvent event) {
// do something
}
//getter and setter of numberValue

Related

SelectOneMenu's value is always 0 in the backing bean

I have a problem with getting the selected value.
It is always 0.
XHTML file:
<p:selectOneMenu id="SelectDicimalsInput5" value="#{auction.money}">
<f:selectItem itemLabel="1" itemValue="1"/>
<f:selectItem itemLabel="5" itemValue="5"/>
<f:selectItem itemLabel="10" itemValue="10"/>
<f:selectItem itemLabel="100" itemValue="100"/>
<f:selectItem itemLabel="500" itemValue="500"/>
<f:selectItem itemLabel="1000" itemValue="1000"/>
</p:selectOneMenu>
Backing bean :
#ManagedBean (name="auction")
#RequestScoped
public class AuctionBean implements Serializable {
private int money;
//getters & setters ...
}
The problem here is that your selectonemenu selected value is a String and your variable in the backed bean is an int.
So this selected value can't be converted to int and that's why you always get 0 as the defailt value of the primitive type int here.
You have to convert this String into an int to match the variable type, you can use an IntegerConverter:
<f:convertNumber integerOnly="true" />
and your code will be:
<p:selectOneMenu id="SelectDicimalsInput5" value="#{auction.money}">
<f:selectItem itemLabel="1" itemValue="1"/>
<f:selectItem itemLabel="5" itemValue="5"/>
<f:selectItem itemLabel="10" itemValue="10"/>
<f:selectItem itemLabel="100" itemValue="100"/>
<f:selectItem itemLabel="500" itemValue="500"/>
<f:selectItem itemLabel="1000" itemValue="1000"/>
<f:convertNumber integerOnly="true" /> //This converter should be added
</p:selectOneMenu>
Also note that there's the converter="javax.faces.Integer" attribute that can be used with <h:selectOneMenu> elements but I think it's not supported by primefaces, but may be I am wrong, so you can try :
<p:selectOneMenu id="SelectDicimalsInput5" converter="javax.faces.Integer" value="#{auction.money}">

Primefaces p:tabView: Value of selectOneMenu lost

I have a problem when I use a p:tabView with dynamic="true", and there is a h:selectOneMenu on one tab, and on the other is a commandLink which is ajax="false". After clicking to the commandLink twice the value of the selectOneMenu is lost.
This problem does not occur when the tabView is dynamic="false".
The value of the h:inputText is not lost, but I see the following warning in the logfile:
org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils decodeUIInput WARNING: There should always be a submitted value for an input if it is rendered, its form issubmitted, and it was not originally rendered disabled or read-only. You cannot submit a form after disabling an input element via javascript. Consider setting read-only to true instead or resetting the disabled value back to false prior to form submission. Component : {Component-Path : [Class: javax.faces.component.UIViewRoot,ViewId: /form/regional/region.xhtml][Class: javax.faces.component.html.HtmlBody,Id: j_id_5][Class: javax.faces.component.html.HtmlForm,Id: TestForm][Class: org.primefaces.component.tabview.TabView,Id: tabviewTest][Class: org.primefaces.component.tabview.Tab,Id: j_id_8][Class: javax.faces.component.html.HtmlInputText,Id: j_id_f]}
Here is the form:
<p:tabView dynamic="true" cache="true" id="tabviewTest">
<p:tab title="Tab 1">
<h:selectOneMenu value="#{Region.dropDownValue}" id="dropDown">
<f:selectItem itemLabel="" itemValue=""/>
<f:selectItem itemLabel="1" itemValue="1"/>
<f:selectItem itemLabel="2" itemValue="2"/>
<f:selectItem itemLabel="3" itemValue="3"/>
<f:selectItem itemLabel="4" itemValue="4"/>
</h:selectOneMenu>
<h:inputText value="#{Region.inputValue}" />
</p:tab>
<p:tab title="Tab 2">
<p:commandLink ajax="false"
id="link"
value="Test"
actionListener="#{Region.someActionMethod}" />
</p:tab>
</p:tabView>
And here the Bean:
public class Region {
private Integer dropDownValue = 3;
private String inputValue = "Test";
public void someActionMethod(ActionEvent ev) {
System.out.println("someActionMethod called");
}
public Integer getDropDownValue() {
return dropDownValue;
}
public void setDropDownValue(Integer dropDownValue) {
this.dropDownValue = dropDownValue;
}
public String getInputValue() {
return inputValue;
}
public void setInputValue(String inputValue) {
this.inputValue = inputValue;
}
}
My Environment: Primefaces 5.0/5.1.RC1, Myfaces 2.1/2.2, Tomact 7
Any ideas what could be wrong?
What scope does your ManagedBean have?
When you use a RequestScope you are not able to submit your selectOneMenu with an UICommand component like p:commandLink when you set the ajax attribute to false. The changes are lost in this case.
Here are two possibilities to fix your problem:
Attempt 1: Set your Bean ViewScoped:
In most cases this will work. If you must use special annotations to annotate your beans (like Apache DeltaSpike #ViewAccessScoped for example), try to separate your bean into View and Controller beans, annotating the View with just simple #ViewScope and keeping all the values in it.
Attempt 2: Remove ajax="false" from p:commandLink:
This will work if your use-case allows it. For example, downloading a file with PrimeFaces will require explicit declaration that the ajax is not to be used, so this solution will not be applicable.
add ajax listener
<h:selectOneMenu value="#{Region.dropDownValue}" id="dropDown">
<f:selectItem itemLabel="" itemValue=""/>
<f:selectItem itemLabel="1" itemValue="1"/>
<f:selectItem itemLabel="2" itemValue="2"/>
<f:selectItem itemLabel="3" itemValue="3"/>
<f:selectItem itemLabel="4" itemValue="4"/>
<p:ajax event="change" update="#this"/>
</h:selectOneMenu>

How to preselect one radio button defaultly

When I run my application, "Single User" should be selected automatically.
<h:selectOneRadio onchange="showEmailDiv(this.id);" value="" id="emailValue" required="true">
<f:selectItem itemValue="Single" itemLabel="Single User" />
<f:selectItem itemValue="Multiple" itemLabel="Multiple User"/>
</h:selectOneRadio>
How can I preselect one radio button defaultly?
Set default value like this
<h:selectOneRadio onchange="showEmailDiv(this.id);" value="Single" id="emailValue" required="true">
<f:selectItem itemValue="Single" itemLabel="Single User" />
<f:selectItem itemValue="Multiple" itemLabel="Multiple User"/>
</h:selectOneRadio>
Note: you aren't binding this component with bean, not sure how would you use it
#ManagedBean
public class YourBean {
private String value = "Single User";
// getter & setter
}
And in your page
<h:selectOneRadio onchange="showEmailDiv(this.id);" value="#{yourBean.value}" id="emailValue" required="true">
<f:selectItem itemValue="Single" itemLabel="Single User" />
<f:selectItem itemValue="Multiple" itemLabel="Multiple User"/>
</h:selectOneRadio>

using JSF binding + validator in the same component display message twice

I have 2 components(select and inputText), in which values are dependent to each other. For example if "option 1" is selected then inputText must be numbers.
In my bean I have added attributes for 2 components for binding and a validation method, while in jsp i have added "validator" and "binding" attribute to select and "binding" to inputText.
I used binding to get the submitted value of both components for validation.
Is this the correct way? Is there an alternative to get the submitted value?
The result of doing this is duplicate message shown. If I remove binding attribute from select then it works as expected but I cannot fetch the selected value, rather is uses the cache value (bean value in session).
Thanks in advance.
aalmero
code:
<p:selectOneMenu
value="# {deploymentRequestViewBean.deploymentRequestDTO.deploymentRequest.requestLevel}"
id="requestLevel" required="true" label="requestLevel"
validator="#{deploymentRequestViewBean.validateRequestDate}">
<p:ajax listener="#{deploymentRequestViewBean.processRequestLevelValueChanged}"
binding="#{deploymentRequestViewBean.requestLevelSelectOne}"/>
<f:selectItem itemValue="" itemLabel="Select One" />
<f:selectItem itemValue="DEV" itemLabel="DEV" />
<f:selectItem itemValue="QUA" itemLabel="QUA" />
<f:selectItem itemValue="PRD" itemLabel="PRD" />
</p:selectOneMenu>
<p:calendar
value="#{deploymentRequestViewBean.deploymentRequestDTO.deploymentRequest.deployDate}"
id="deployDate" required="true" label="deployDate" showOn="button" pattern="yyyy- MM-dd" binding="#{deploymentRequestViewBean.requestDateInput}"/>
<p:spacer width="10" height="10" />
//for component-binding
private UISelectOne requestLevelSelectOne;
private UIInput requestDateInput;
//validation method
public void validateRequestDate(FacesContext facesContext,
UIComponent component, Object newValue){
//get the current value of select;
requestLevelSelectOne.getSubmittedValue();
//get the current vallue of input;
requestDateInput.getSubmittedValue()
if(not valid combination){
facesContext.addMessage(requestDateInput.getClientId(facesContext), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", selectedLevel + " deployment request requires at least 2 days."));
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Deployment date must be at least 2 days."));
}
}
You can use a hack bypass by binding a hidden component value with the select component. In the "onchange" method of your <h:selectOneMenu> you can set the value of this hidden component and get the values in the server:
<h:form id="myForm">
<h:selectOneMenu id="cmbOptions"
onchange="document.getElementById('myForm:hidSelectOption').value=this.value">
<f:selectItem itemLabel="Option 1" itemValue="1" />
<f:selectItem itemLabel="Option 2" itemValue="2" />
<f:selectItem itemLabel="Option 3" itemValue="3" />
</h:selectOneMenu>
<h:inputHidden id="hidSelectOption" value="#{bean.selectedOption}" />
<h:commandButton value="Click me" action="#{bean.someAction}" />
</h:form>
The managed Bean
#RequestScope
#ManagedBean
public class Bean {
private String selectedOption;
//getters and setters...
public Bean() {
}
public void someAction() {
//showing the actual value of the hidden component...
//remember that you should use a logger, this is a basic example
System.out.println(selectedOption);
}
}

JSF/PrimeFaces selectOneMenu change view-id

I'm using JSF2 and PrimeFaces3. How can I write selectOneMenu that would invoke JSF navigation to redirect user to another page when he change option in menu?
Attach an ajax listener and let it navigate by NavigationHandler.
E.g.
<h:form>
<h:selectOneMenu value="#{navigator.outcome}">
<f:selectItem itemLabel="Select page..." />
<f:selectItem itemValue="page1" itemLabel="Page 1" />
<f:selectItem itemValue="page2" itemLabel="Page 2" />
<f:selectItem itemValue="page3" itemLabel="Page 3" />
<f:ajax listener="#{navigator.navigate}" />
</h:selectOneMenu>
</h:form>
(the above example expects page1.xhtml, page2.xhtml and page3.xhtml in the same context; you can even make it a <f:selectItems> instead)
with
private String outcome;
public void navigate() {
FacesContext context = FacesContext.getCurrentInstance();
NavigationHandler navigationHandler = context.getApplication().getNavigationHandler();
navigationHandler.handleNavigation(context, null, outcome + "?faces-redirect=true");
}
The ?faces-redirect=true is not necessary, but it effectively sends a redirect so that the URL in browser address bar will properly change which is better for user experience and bookmarkability of the pages.
You could have something like:
<p:selectOneMenu value="#{myBean.mySelectedPage}">
<f:selectItem itemValue="http://www.yahoo.com" itemLabel="yahoo" />
<f:selectItem itemValue="http://www.google.com" itemLabel="google" />
<f:selectItem itemValue="search.jsf" itemLabel="search" />
<p:ajax event="change" listener="#{myBean.myNavigationMethod}" />
</p:selectOneMenu>
and on your navigationMethod you have:
String myPage = mySelectedPage
FacesContext.getCurrentInstance().getExternalContext().redirect(myPage);
The first two selectItem are for a full url and the last one is for another page in your web application(be careful that the extension must be the one set in your web.xml - it could be .jsf, .xhtml, .htm etc)
Instead of using ajax navigation use the following:
<p:selectOneMenu value="#{navigator.outcome}" onchange="window.location =this.options[this.selectedIndex].value">
<f:selectItem itemLabel="Select page..." />
<f:selectItem itemValue="page1" itemLabel="Page 1" />
<f:selectItem itemValue="page2" itemLabel="Page 2" />
<f:selectItem itemValue="page3" itemLabel="Page 3" />
<p:ajax event="change" listener="#{navigator.navigate}" />
</p:selectOneMenu>
This works even if the session times out.

Resources