This question already has answers here:
commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated
(12 answers)
Closed 5 years ago.
My JSF radio button doesn't work and I don't really know why. Here' some code:
<h:selectOneRadio value="#{jSFDatabase.type}">
<f:selectItem itemValue="0" itemLabel="Database" />
<f:selectItem itemValue="1" itemLabel="Webservice" />
</h:selectOneRadio>
<h:outputLabel value="#{jSFDatabase.type }" />
If I click the other radio button the value is still 0 (default). Why is this code not working? The Getter and Setter are here:
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
How can I fix that issue?
You would need to either use <f:ajax /> to re-render the affected regions of the page, or, if you prefer not to use AJAX, post the form. Otherwise, the data won't be updated.
For example, you could do this:
<h:selectOneRadio value="#{jSFDatabase.type}">
<f:selectItem itemValue="0" itemLabel="Database" />
<f:selectItem itemValue="1" itemLabel="Webservice" />
<f:ajax execute="#form" render="myValue" />
</h:selectOneRadio>
<h:outputLabel id="myValue" value="#{jSFDatabase.type }" />
See:
http://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/f/ajax.html
https://www.mkyong.com/jsf2/jsf-2-button-and-commandbutton-example/
Related
I have a JSF2 implementation using PrimeFaces. I am using a <p:selectOneRadio /> component. When the user selects "No" in the radio component, I would like to show a custom message. I have created a custom validator for this purpose, and along with the message component everything works fine. However, the component is also required. I do not want the "Value is required" validation error for the required component to show up in the message component. In this case, I only want the field and the label to be highlighted.
So, the question is: How do I specify that a given <p:message /> component display only the error from my custom validator, and not the error from the required validator?
I saw an answer to a similar question from a few years ago that said you could set the message for attribute to a component that doesn't actually exist, and add the message to that component via the FacesContext. Such as this:
<p:message for="fooMsg" /> ... FacesContext.getCurrentInstance().addMessage("fooMsg",msg)
However, that does not seem to work. JSF throws an error that it cannot find the component "fooMsg".
Here is my current code.
Component:
<p:outputLabel for="foo" id="foolbl"
value="Some label text." />
<br />
<p:message for="foo" />
<p:selectOneRadio id="foo" layout="pageDirection"
widgetVar="fooVar" required="true">
<f:selectItem itemLabel="Yes" itemValue="Yes" />
<f:selectItem itemLabel="No" itemValue="No" />
<p:ajax update="#this foolbl" process="#this" />
<f:validator validatorId="FooValidator" />
</p:selectOneRadio>
Validator:
#FacesValidator("FooValidator")
public class FooValidator implements Validator {
#Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (value != null) {
String sValue = (String) value;
if (sValue.trim().equalsIgnoreCase("No")) {
FacesMessage msg = new FacesMessage("Summary",
"Detail");
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(msg);
}
}
}
}
First of all this is default JSF behavior. To solve your
problem, you could use jQuery to check if no radio button is choosen and hide the message in that
case, for example:
<h:form id="form">
<p:outputLabel for="foo" id="foolbl" value="Some label text." />
<br />
<p:message id="foomsg" for="foo" />
<p:selectOneRadio id="foo" layout="pageDirection" widgetVar="fooVar"
required="true">
<f:selectItem itemLabel="Yes" itemValue="Yes" />
<f:selectItem itemLabel="No" itemValue="No" />
<p:ajax process="#this" update="#this foolbl foomsg" />
<f:validator validatorId="FooValidator" />
</p:selectOneRadio>
<p:commandButton process="#this foo" update="foo foolbl foomsg"
oncomplete="if( !PF('fooVar').checkedRadio.length ) $('#form\\:foomsg').hide();" />
</h:form>
Have a look at the oncomplete attribute of the commandButton.
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
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>
This question already has an answer here:
h:messages does not display messages when p:commandButton is pressed
(1 answer)
Closed 2 years ago.
JsfUtil addErrorMessage is not working while calling ajax function to bean method..
<h:outputLabel value="Effect Date" styleClass="boldFound,rsInput" />
<p:calendar value="#{salarypromotionBean.salarypromotiondto.effectDate}"
pattern="dd-MM-yyyy" yearRange="#{c-100}" navigator="true"
size="21">
<p:ajax event="dateSelect" listener="#{salarypromotionBean.salaryPromotion}" update="emp,empName,empDept,empDesig,empDate"/>
</p:calendar>
<h:outputText value="Employee No" />
<p:selectOneMenu value="#{salarypromotionBean.salarypromotiondto.employeeNo}" id="emp">
<f:selectItem itemLabel="select" itemValue="0" />
<f:selectItems value="#{salarypromotionBean.empid}" />
</p:selectOneMenu>
Java method:
public void salaryPromotion() throws ParseException{
JsfUtil.addErrorMessage("New salary should be greater than current salary");
}
<p:messages autoUpdate = "true"/>
This would resolve your issue for the error messages to be displayed:
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.