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

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);
}
}

Related

h:selectOneMenu value is always null when submitting the form

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

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>

p:selectOneMenu value not set in bean

In p:selectOneMenu loginbranchName value is not set in bean.In selectItems having list of branchName.I'm using listener to select value from list but value not set in getLoginBranchId method....
<h:outputLabel value="Branch Name:*" style="text-align: left;display: block;" rendered="#{loginBean.userLoggedIn}"/>
<p:selectOneMenu value="#{loginBean.loginbranchName}"
rendered="#{loginBean.userLoggedIn}"
style="width:175px;">
<f:selectItem itemLabel="Select" itemValue="0" />
<f:selectItems value="#{loginBean.branchName}" />
<p:ajax event="change" listener="#{loginBean.getLoginBranchId}"/>
</p:selectOneMenu>
login.java
public String getLoginbranchName() {
return loginbranchName;
}
public void setLoginbranchName(String loginbranchName) {
System.out.println("loginbranchName"+loginbranchName);
this.loginbranchName = loginbranchName;
}
public void getLoginBranchId()
{
System.out.println("enter into getloginbranchid");
System.out.println("loginbranchName"+loginbranchName);
int unitId=loginDAO.getLoginBranchId(loginbranchName);
System.out.println("unitId"+unitId);
}
#BalusC was correct regarding the above discussion where, JSF2 can work with List and SelectItem https://stackoverflow.com/tags/selectonemenu/info I think you might be missing
<h:form>
</h:form>
tag.

primefaces selectOneMenu how to reload

I use 3 selectOneMenu components in my project. I need to reload content of the second after change in the first. Here are some parts of the files
index.xhtml
<h:form id="form">
<p:selectOneMenu id="Rząd" value="#{birdSelectorBean.selectedState}" effect="fade"
style="width: 150px;">
<f:selectItem itemLabel="Rząd" itemValue="" />
<f:selectItems value="#{birdSelectorBean.rzad}" />
<p:ajax render="#form" listener="#{birdSelectorBean.stateChangeListener}" />
</p:selectOneMenu>
<p:selectOneMenu id="rodzina" value="#{birdSelectorBean.selectedState}" effect="fade"
style="width: 150px;">
<f:selectItem itemLabel="Rodzina" itemValue="" />
<f:selectItems value="#{birdSelectorBean.rodzina}" />
</p:selectOneMenu>
<p:selectOneMenu id="rodzaj" value="#{birdSelectorBean.selectedState}" effect="fade"
style="width: 150px;">
<f:selectItem itemLabel="Rodzaj" itemValue="" />
<f:selectItems value="#{birdSelectorBean.rodzaj}" />
</p:selectOneMenu>
</h:form>
BirdSelectionBean.java:
public class BirdSelectorBean
{
private String selectedState;
private List<SelectItem> rzad;
private List<SelectItem> rodzina;
private List<SelectItem> rodzaj;
public BirdSelectorBean()
{
rzad = new ArrayList<>();
rzad.add(new SelectItem("Rząd_X"));
rzad.add(new SelectItem("Rząd_Y"));
rzad.add(new SelectItem("Rząd_Z"));
rodzina = new ArrayList<>();
rodzaj = new ArrayList<>();
}
public void stateChangeListener(ValueChangeEvent event)
{
rodzina.clear();
rodzina.add(new SelectItem("Rodzina_A"));
rodzina.add(new SelectItem("Rodzina_B"));
rodzina.add(new SelectItem("Rodzina_C"));
}
...
getters and setters
...
}
I read many topics on that but it doesn't work for me. I tried update="rodzina" like it is in example
here
and render option like it is said in that
topic:
But it still doesn't work. Please help me :]
In the p:ajax tag change render="#form" to update="#form". Render is used by f:ajax, primefaces use another name for some reason - see here.
Looks like your stateChangeListener method nevers get called and more important, your managed bean looks like hasn't any scope (at least from your question content), remember that it must be at least #ViewScoped in order to make this work. Also, another problem in your code is that you're using the same attribute to select the data for the three <p:selectOnuMenu> (which is not a problem yet since you haven't achieved what you wanted to begin with).
To make the ajax update work, remove the parameter from your stateChangeListener. Also let's add the other two attributes for the selected items from the dropdownlists.
#ManagedBean
#ViewScoped
public class BirdSelectorBean {
private String selectedState;
private String selectedStateRodzina;
private String selectedStateRodzaj;
//other fields and methods...
public void stateChangeListener() {
rodzina.clear();
rodzina.add(new SelectItem("Rodzina_A"));
rodzina.add(new SelectItem("Rodzina_B"));
rodzina.add(new SelectItem("Rodzina_C"));
}
}
And then update your desired <p:selectOneMenu> in your <p:ajax> call (I removed the non-directly related to the problem attributes from the components like style):
<p:selectOneMenu id="Rząd" value="#{birdSelectorBean.selectedState}">
<f:selectItem itemLabel="Rząd" itemValue="" />
<f:selectItems value="#{birdSelectorBean.rzad}" />
<p:ajax update="rodzina" listener="#{birdSelectorBean.stateChangeListener}" />
</p:selectOneMenu>
<p:selectOneMenu id="rodzina" value="#{birdSelectorBean.selectedStateRodzina}">
<f:selectItem itemLabel="Rodzina" itemValue="" />
<f:selectItems value="#{birdSelectorBean.rodzina}" />
</p:selectOneMenu>

JSF f:selectItem in h:selectManyCheckbox not working in backing bean, but is displayed properly in h:dataTable

The problem occurs with this code:
<h:form>
<rich:panel>
<f:facet name="header">
<h:selectManyCheckbox title="Select which types of requests you want to see"
onchange="submit();" value="#{filterListener.chosenFilters}"
id="selectBoxContainer" >
<f:selectItem id="approvedByITS" itemLabel="Approved by ITS" itemValue="approvedByITS" />
<f:selectItem id="approvedByPO" itemLabel="Approved by Process Owner" itemValue="approvedByPO" />
<f:selectItem id="dob" itemLabel="Date" itemValue="dob" />
<f:selectItem id="externalAssignedTo" itemLabel="External assigned" itemValue="externalAssignedTo" />
<f:selectItem id="internalAssignedTo" itemLabel="Internal assigned" itemValue="internalAssignedTo" />
<f:selectItem id="ITSapprovedBy" itemLabel="ITS approved by" itemValue="ITSapprovedBy" />
<f:selectItem id="severity" itemLabel="Severity" itemValue="severity" />
<f:selectItem id="status" itemLabel="status" itemValue="status" />
<f:valueChangeListener type="no.ngt.tech.rt2.listeners.requestFilterListener" />
</h:selectManyCheckbox>
</f:facet>
<h:dataTable value="#{filterListener.chosenFilters}" var="selects" >
<h:column>
<h:outputText value="#{selects}" />
</h:column>
</h:dataTable>
<br />
<h:messages />
</rich:panel>
</h:form>
As we can see I have the value="#{filterListener.chosenFilters}". The dataTable's value is also the same, so whenever I click one of the selectItem's the dataTable has an element added or removed from it (this is working). In my backing bean I have the following code:
public class requestFilterListener implements ValueChangeListener {
private List<String> chosenFilters;
public requestFilterListener() {
}
public void processValueChange(ValueChangeEvent event) {
System.out.println("processValueChange called");
if (chosenFilters != null) {
System.out.println(chosenFilters.size());
}
}
public List<String> getChosenFilters() {
return chosenFilters;
}
public void setChosenFilters(List<String> chosenFilters) {
this.chosenFilters = chosenFilters;
}
Everytime I click one of the checkboxes, a column is added/removed with the proper data, in my console I get the message "processValueChange called" as I output in the processValueChange method, but during this time chosenFilters is always null, and the if expression is never run. How come? This is a session bean, and I really dont understand why my list cant be used within the backing bean, but is used without a problem by my dataTable.
Thanks for your time in looking into this.
The problem is probably on this tag:
<f:valueChangeListener type="no.ngt.tech.rt2.listeners.requestFilterListener" />
You are instructing the f:valueChangeListener tag to create a new instance of requestFilterListener instead of binding to the one specified by the managed bean configuration. Use the binding attribute to bind to #{filterListener}.

Resources