This question already has answers here:
commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated
(12 answers)
Closed 3 years ago.
I need some help. I'm developing for jsf and primefaces web application and I'm facing a problem when I'm selecting from a drop down list to get the selected value but I'm getting an empty string in the action.
This is my xhtml code for selectOneMenu tag
<p:selectOneMenu value="#{tanAllot.batchName}" id="batchName">
<f:selectItem itemLabel="Select Batch" itemValue="" />
<f:selectItems value="#{tanAllot.batchList}" />
<p:ajax event="change" listener="#{tanAllot.test}" />
</p:selectOneMenu>
this is the method I'm using in the action class
private String batchName;
public String getBatchName() {
return batchName;
}
public void setBatchName(String batchName) {
this.batchName = batchName;
}
public void test() {
System.out.println(batchName);
}
My problem is when I select a value from p:selectOneMenu tag the default method should invoke in the action and retrieve the value but I'm getting an empty string.
Can anyone help me to solve this problem?
Consider the nature of batchList. batchList must be List of Strings. Using itemValue attribute (in f:selectItem) can be helpful.
Check my example. It uses a list of provinces (instances of "Province" class). However I only need the "id" value which is a "Long"; if I wanted the whole picked province as a "Province object" I would need a "Converter". (Example works perfectly):
<p:selectOneMenu id="provinceField"
value="#{addAddressesMB.formAddress.provinceId}">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{addAddressesMB.provinceList}" var="i"
itemLabel="#{i.description}" itemValue="#{i.id}" />
<p:ajax update=":formId:cityField"
listener="#{addAddressesMB.provinceChangeHandler}" />
</p:selectOneMenu>
And here comes the listener method:
public void provinceChangeHandler() {
//do whatever you want with formAddress.provinceId
System.out.println(this.formAddress.provinceId);
//In my case I filter the cities according to the selected provinceId
// After that I update the cities dropdown(cityField) in the view.
}
Check your code and feel free to ask. Good luck.
Related
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/
This question already has an answer here:
How to clear out and reuse p:dialog when adding new items
(1 answer)
Closed 6 years ago.
folks.
I'm stuck on the following problem. I have a modal dialog with two selectOneMenu components in it. When I close the dialog and open it again the values in selectoneMenu's are still selected. This is my menus:
<p:selectOneMenu id="fromCurrency"
value="#{dialog.exchangeRateManageContainer.currencyIdFrom}"
styleClass="ui-input-required"
required="true"
requiredMessage="#{msgs['validation.maintenance.exchangeRate.fromCurrency']}">
<f:selectItem
itemLabel="#{msgs['label.maintenance.selectCurrency']}"/>
<f:selectItems value="#{dialog.currencies}" var="currency"
itemLabel="#{currency.code}"
itemValue="#{currency.currencyId}"/>
</p:selectOneMenu>
<p:outputLabel for="toCurrency" value="#{msgs['label.maintenance.toCurrency']}" />
<p:selectOneMenu id="toCurrency"
value="#{dialog.exchangeRateManageContainer.currencyIdTo}"
styleClass="ui-input-required"
required="true"
requiredMessage="#{msgs['validation.maintenance.exchangeRate.toCurrency']}">
<f:selectItem itemLabel="#{msgs['label.maintenance.selectCurrency']}"/>
<f:selectItems value="#{dialog.currencies}" var="currency"
itemLabel="#{currency.code}"
itemValue="#{currency.currencyId}"/>
This is the cancel button:
<p:commandButton id="cancelButton"
value="#{msgs['label.button.cancel']}"
icon="ui-icon-cancel"
action="#{dialog.cancel()}"
immediate="true"
process="#this"
oncomplete="addExchangeRateDialog.hide();"/>
And this is the cancel method:
public void cancel() {
manageCurrenciesDialog = null;
}
Any help will be appreciated.
The solution for me was to add update atribut on the command buton which opens the dialog with the dialog id. And it works.
In order to reset selections, you need to set the values of your components to null.
Change your cancel method to:
public void cancel() {
manageCurrenciesDialog = null;
exchangeRateManageContainer.currencyIdFrom = null;
exchangeRateManageContainer.currencyIdTo = null;
}
Reset values of all components
I reseted values of all components by calling action to my backing bean method.
Inside of this method I assigned all values of components such as p:selectOneMenu and p:selectBooleanCheckbox to null.
It works perfectly.
I want to achieve sth similar to http://www.primefaces.org/showcase/ui/pprSelect.jsf but i need a collection of double-combos, so i wrapped it in ui:repeat
I need on the backend check which element from collection of double-combos was changed and what I need to reload. For communication is used p:ajax as in the example, but AjaxBehaviorEvent not bring me any idea of index of element ( i mean index of double-combos element generated by ui:repeat)
My client code, the idea is to update bean:selectedIndex everytime when a ajax event will be raised ( on change value of selectOneMenu ), and value of bean:selectedIndex will be set as index of changed selectOneMenu
private List<State> productStates
private int selectedIndex;
private List<Group> groups;
private Map<Integer, Collection<Device>> availableDevicesMap;
<ui:repeat var="state" value="#{bean.productStates}" varStatus="iter">
<p:selectOneMenu id="devGroup" value="#{state.group}">
<f:selectItems value="#{bean.groups}" />
<p:ajax update="refreshable" process="devGroup, #this" listener="#{bean.refreshDevicesForState}" >
<f:setPropertyActionListener target="#{bean.selectedIndex}" value="#{iter.index}"/>
</p:ajax>
</p:selectOneMenu>
<!-- THIS WILL BE UPDATED -->
<h:panelGroup id="refreshable">
<p:selectManyButton id="devices" value="#{state.devices}" >
<f:selectItems value="#{bean.availableDevicesMap[status.index]}" />
</p:selectManyButton>
</h:panelGroup>
</ui:repeat>
Backend which doesn't work as expected. setPropertyActionListener is not invoked and selectOneMenu component hasn't got selected group as value
public refreshDevicesForState(AjaxBehaviorEvent e) {
SelectOneMenu menu = (SelectOneMenu)e.getComponent();
// this value is not as selected on frontend
Group group = (Group)menu.getValue();
// selectedIndex will not be set, so I assume that setPropertyActionListener didn't invoked
availableDevicesMap.put(selectedIndex, group.getDevices());
}
I tried also with code below which works but in my opinion it is ugly
// id will be grandpaId:parentId:index:myId
String selectedIndex = IdHelper.getIdPart(e.getComponent().getClientId(), -2);
State state = productStates.get(Integer.parseInt(selectedIndex));
I am using latest primefaces on glassfish and Mojarra as jsf reference implementation
Thank you for any help
In more general sense:
I have list of objects on backed bean, lets say Cars
List<Car> cars
on frontent I iterate over them and create select brand and select model combos for every car. When user select brand for i.e 4th car i want to get to know on backend that 4th car will be changed and i will reload list of available model for this one car
<ui:repeat var="state" value="#{bean.cars}" >
<p:selectOneMenu id="brands"/>// select brand
<p:selectOneMenu "models"/>// show available models depends on selected brand
</ui:repeat>
How to handle it correct in the JSF world ?
My first suggestion is to use converter for Group.
SelectOneMenu cannot set custom class, only with the help of a converter. (an example is at autocomplete: http://www.primefaces.org/showcase/ui/autoCompletePojo.jsf)
Second, in your bean handler, productStates variable contains already the selected values (of selectOneMenus). You can use it easier, than access it from the event.
If the values of selectOneMenus depend on State, you have to modify this:
<f:selectItems value="#{bean.groups}" />
to be able to express which group values should be displayed.
If you want debug it (without eclipse debugging), you can use messages, for example:
add this to xhtml:
<p:growl id="msgs" showDetail="true"/>
and in bean:
public refreshDevicesForState(AjaxBehaviorEvent e) {
...
FacesMessage msg = new FacesMessage("Selected", "any debug info" + productStates.get(0).getGroup());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
I modified my answer, according to your mods. I would do it this way:
xhtml:
<ui:repeat var="state" value="#{bean.productStates}" varStatus="iter">
<p:selectOneMenu id="devGroup#{iter.index}" value="#{state.group}"
valueChangeListener="#{bean.updateSubProperty}" immediate="true">
<f:selectItems value="#{bean.groups}" />
<f:attribute name="index" value="#{iter.index}" />
</p:selectOneMenu>
<p:selectOneMenu id="subDevGroup#{iter.index}">
...
</p:selectOneMenu>
</ui:repeat>
bean:
public void updateSubProperty(ValueChangeEvent vce) {
String index = vce.getComponent().getAttributes().get("index").toString();
int i = Integer.parseInt(index); //this is the index of the selected selectOneMenu
///...
//update sub selectOneMenu
RequestContext.getCurrentInstance().update("subDevGroup" + index);
}
This question already has answers here:
Validation Error: Value is not valid
(3 answers)
Closed 7 years ago.
I have two cascading p:selectOneMenu components. The first shows areas from a hashmap and the second shows cities for the selected area by ajax. But when submitting the form with the city selected, I get
Validation Error: Value is not valid
Here's the view
<p:selectOneMenu id="area" value="#{bean.area}">
<f:selectItem itemLabel="Select Area" itemValue="" />
<f:selectItems value="#{bean.areas}" />
<p:ajax update="city" listener="#{bean.handleAreaChange()}" />
</p:selectOneMenu>
<p:selectOneMenu id="city" value="#{bean.city}">
<f:selectItem itemLabel="Select City" itemValue="" />
<f:selectItems value="#{bean.cities}" />
</p:selectOneMenu>
Here's the bean:
private String area;
private String city;
private Map<String, String> areas = new HashMap<String, String>();
private Map<String, String> cities = new HashMap<String, String>();
private Map<String, Map<String, String>> allCities = new HashMap<String, Map<String,String>>();
public void handleAreaChange() {
if (area != null && !area.isEmpty()) {
cities = allCities.get(area);
} else {
cities = new HashMap<String, String>();
}
}
How is this caused and how can I solve it?
You will get this error when the submitted value of the dropdown is not contained in the list of available values. So this means that the list of available values has incompatibly changed during the HTTP request of the form submit as compared to the HTTP request of displaying the form. This in turn often means that the backing bean is request scoped and that the list of available values is not preinitialized in its (post)constructor.
Either putting the bean in the view scope, or adding code which properly preinitializes the list of available values based on request parameters, should fix your problem.
As BalusC said the value (identifier) of the selectItem has changed. This can happen if your bean is request scoped or if the objects have changed server side.
A common solution I use is to set the value of the selectItem to an id of the object it represents.
Lets assume City and Area have unique identifiers (id) and looks like this:
public class City //or Area
{
private Long id;
private String name;
//Rest of class
}
You can then introduce a converter for City and Area:
#FacesConverter("cityConverter")
public class CityConverter implements javax.faces.convert.Converter
{
#Override
public Object getAsObject(FacesContext ctx, UIComponent cmp, String str)
{
//Convert id to Object (City) and return it
}
#Override String getAsString(FacesContext ctx, UIComponent, Object obj)
{
//Return the id that represents the Object (City) here
return ((City)obj).getId().toString();
}
}
In your JSF page make use of the converter:
<p:selectOneMenu id="area" value="#{bean.area}" converter="areaConverter">
<f:selectItem itemLabel="Select Area" itemValue="" />
<f:selectItems value="#{bean.areas}" />
<p:ajax update="city" listener="#{bean.handleAreaChange()}" />
</p:selectOneMenu>
<p:selectOneMenu id="city" value="#{bean.city}" converter="cityConverter">
<f:selectItem itemLabel="Select City" itemValue="" />
<f:selectItems value="#{bean.cities}" />
</p:selectOneMenu>
More about how to implement a FacesConverter on this site.
The first thing you need to do is to tell link the ajax to an event. So you probably want it to happen on the valueChange event so your ajax should be:
<p:ajax update="tmil2" event="valueChange" listener="#{BeanAreaAndCity.handleCityChange()}"></p:ajax>
I am trying to set the value of <h:selectOneMenu> using the bean setter, but it is not working. Here is my .xml code:
<h:selectOneMenu value="#{adminActionController.tempBean.selectType}">
<f:selectItem itemLabel="Check" itemValue="Check" />
<f:selectItem itemLabel="Cash" itemValue="Cash"/>
<f:ajax event="change" listener="#{adminActionController.tempBean.changeType}"/>
</h:selectOneMenu>
And here is my bean code:
protected String selectType;
public String getSelectType() {
return selectType;
}
public void setSelectType(String selectType) {
this.selectType = selectType;
}
I tried a lot of ways, but something is still missing. I don't know what.
It sets h:inputText values to bean, but I have a problem with dropdown values.
Can anybody help me?
Try without immediate="true".And selectOneMenu must be inside h:form.When selectOneMenu is changed,your listener is working,right ?