I am working on Managedbeans and JSF. As shown below that my ManagedBean contains all the requirements that are required for the JSF to get the value. I have initialised my dropdown list as below. In selectOneMenu, I have chosen the country as a string where it will store the value selected by the dropdown list and the dropdown list will bring up the list that I declared in the Beans.
Unfortunately, it is not happening like that. Every time dropdown renders it gives me an empty value. I have spent days on it but cannot figure out the exact solution to it. I have cleaned my server, build workspace and also change servers but nothing is working.
** ManagedBean_list **
private List<String> listCountry;
private String country;
public void tada(){
listCountry=Arrays.asList("India", "pakisatan","America");
}
public List<String> getListCountry() {
return listCountry;
}
public void setListCountry(List<String> listCountry) {
this.listCountry = listCountry;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
JSF
<p:selectOneMenu id="country" value="#{loginBeans.country}">
<f:selectItems value="#{loginBeans.listCountry}" />
</p:selectOneMenu>
Your help is appreciated. Empty dropdown list image
enter image description here
Which bean annotation are you using? You say "Managedbeans", but the source you posted does not show the entire bean, or does it? Check to make sure you are not mixing old style JSF managed bean annotations with CDI annotations.
The issue is that on initialization, the list is not being called up. I resolved it by including the list function inside the constructor of managed beans class. so that when the constructor fired up. It also generates the dropdown list.
Either convert your listCountry to a
private Map<String, String> listCountry = new HashMap<>();
listCountry.put("India", "India");
listCountry.put("Pakistan", "Pakistan");
listCountry.put("America", "America");
or
private List<SelectItem> listCountry = new ArrayList<>();
listCountry.add(new SelectItem("India", "India"));
listCountry.add(new SelectItem("Pakistan", "Pakistan"));
listCountry.add(new SelectItem("America","America"));
Related
I need your help in disabling and enabling an item from the selectManyCheckbox component in a jsf page. First of all, the selectManyCheckbox component is showing three chechboxes which are (Loan - Health - Transfer). The list will be populated from a bean which it has the code:
private List<hrCertificate> hrCertificatesList = new ArrayList<hrCertificate>();
//Getter and Setter
Private String loanFlag="";
#PostConstruct
public void init() {
this.hrCertificatesList.add(new hrCertificate(("Loan"), "LC"));
this.hrCertificatesList.add(new hrCertificate(("Health"), "HI"));
this.hrCertificatesList.add(new hrCertificate(("Trasnfer"), "TE"));
}
In the same bean, I will be running a SQL statement that will return either Yes or No and that value I am adding it to the loanFlag variable.So if the flag="Y", I need to enable the loan checkbox so the user can select it else I need to disable it from the selectManyCheckbox. The issue is that I am facing difficulties in applying the logic to disable and to enable the item selectManyCheckboxwhere in the above code I am listing and enabling them all the time.
The code for the selectManyChexkbox:
<p:selectManyCheckbox id="hrCertificates" value="#{user.selectedHRCertificates}" layout="pageDirectio>
<f:selectItems value="#{user.hrCertificatesList}"
var="hrCertificate" itemLabel="#{hrCertificate.hrCertificateName}"
itemValue="#{hrCertificate.hrCertificateCode}"/>
</p:selectManyCheckbox>
So how to apply the logic
Could you edit your hrCertificate class to add a disabled boolean field? If yes, then you can add itemDisabled="#{hrCerticate.disabled}" to your f:selectItems which should be the easiest solution.
Another option would be to use a Map<hrCertificate, Boolean> instead of a List<hrCertificate>.
private Map<hrCertificate, Boolean> hrCertificatesMap = new HashMap<hrCertificate, Boolean>();
#PostConstruct
public void init() {
hrCertificatesMap.put(new hrCertificate(("Loan"), "LC"), null);
hrCertificatesMap.put(new hrCertificate(("Health"), "HI"), null);
hrCertificatesMap.put(new hrCertificate(("Trasnfer"), "TE"), null);
}
// Then when you're done with your SQL query, update your Map to add the corresponding boolean values...
.xhtml
<p:selectManyCheckbox id="hrCertificates" value="#{user.selectedHRCertificates}" layout="pageDirectio>
<f:selectItems value="#{user.hrCertificatesMap.keySet().toArray()}" var="hrCertificate" itemLabel="#{hrCertificate.hrCertificateName}" itemValue="#{hrCertificate.hrCertificateCode}" itemDisabled="#{user.hrCertificatesMap.get(hrCertificate)}" />
</p:selectManyCheckbox>
First, note that a property does not retire an actual attribute backing it, you only need a getter. So you can have:
public class MyBean implements Serializable {
private FilterEnum certFilter = FilterEnum.NO_FILTER;
private List<Certificate> certificates;
... // including certificates initialization.
public FilterEnum getCertFilter() {
return this.certFilter;
}
public void setCertFilter(FilterEnum certFilter) {
this.certFilter = certFilter;
}
public List<Certificate> getCertificates() {
// I am sure there is a cooler way to do the same with streams in Java 8
ArrayList<Certificate> returnValue = new ArrayList<>();
for (Certificate certificate : this.certificates) {
switch (this.certFilter) {
case FilterEnum.NO_FILTER:
returnValue.add(certificate);
break;
case FilterEnum.ONLY_YES:
if (certificate.isLoan) {
returnValue.add(certificate);
}
break;
case FilterEnum.ONLY_NO:
if (!certificate.isLoan) {
returnValue.add(certificate);
}
break;
}
}
return returnValue;
}
}
If you insist that you want to do the filter "in the .xhtml", you can combine c:forEach from JSTL with <f:selectItem> (note item, not items), but it will make your xhtml more complicated and may cause issues if you want to use Ajax with it.
I want to create selectOneRadio list and selectCheckboxMenu which items get from related bean objects.
For non selected list it is working well.But how can i provide these lists with some item(s) selected by default.
My current selectCheckboxMenu code is like this.
<p:selectCheckboxMenu id="trdays"
value="#{mybean.selectedDay}"
label="Select Days">
<f:selectItems value="#{mybean.dayList}" var="day"
itemValue="#{day.value}" itemLabel="#{day.name}"/>
</p:selectCheckboxMenu>
it should look like this when page loaded and user haven't done anything yet.
EDIT
Day Class :-
public class Day{
private String name;
private String value;
//getters and setters
}
Value attribute of selectCheckboxMenu component should get the your default values.
On bean side you should write a getter for selectedDayList and all daylist.
Example:
#PostConstruct
public void init() {
dayList= new ArrayList<String>();
dayList.add("Mon");
dayList.add("Tue");
dayList.add("Wed");
dayList.add("Thu");
dayList.add("Fri");
dayList.add("Sat");
dayList.add("Sun");
selectedDayList= new ArrayList<String>();
selectedDayList.add("Tue");
selectedDayList.add("Wed");
}
public List<String> getDayList()
{
return dayList;
}
public List<String> getSelectedDaylist()
{
return selectedDayList;
}
.xhtml page should be like this.
<p:selectCheckboxMenu id="trdays"
value="#{mybean.selectedDaylist}"
label="Select Days">
<f:selectItems value="#{mybean.dayList}" var="day"
itemValue="#{day.value}" itemLabel="#{day.name}"/>
</p:selectCheckboxMenu>
Good Luck!
Just add default values in the selectedDay list (or array) in init method (with #PostConstruct annotation). These values should have same value as corresponding itemValue attribute (in your case this is day.value).
I have a problem with the selectManyCheckbox tag..
We are using JSF 1.1 inside a JBoss Portal (i think its version 4.2, but not sure)..
I have the following JSF markup:
<h:selectManyCheckbox layout="lineDirection"
value="#{personBean.selectedPersonsLongArray}"
id="selectedPersons">
<f:selectItems value="#{personBean.persons}" />
</h:selectManyCheckbox>
(And of course I have a button that submits the form). My bean looks like this:
public class PersonBean {
private List<SelectItem> persons;
private List<SelectItem> selectedPersons = new ArrayList<SelectItem>(); // +getter +setter
private List<String> selectedPersonsStringList = new ArrayList<String>();// +getter +setter
private List<Long> selectedPersonsStringList = new ArrayList<Long>();// +getter +setter
private long[] selectedPersonsLongArray = new long[0];// +getter +setter
private String[] selectedPersonsStringArray = new String[0]; // +getter +setter
public void getPersons(){
if(persons == null){
List<Person> personsFromDb = // get from DB
persons = new ArrayList<Person>(personsFromDb.size());
for(Person person : personsFromDb){
// ID of a person is a long
persons.add(new SelectItem(person.getId(), person.getName()));
}
}
return persons;
}
public void setPersons(List<SelectItem> persons){
this.persons = persons;
}
...
}
The bean is session scoped and Person's Id property is of type long. I have tried binding the value of the tag to all the types listed in the bean. On submit, all but selectedPersonLongArray gives a "Validation Error" message. If I bind it to selectedPersonLongArray i get an error saying selectedPersons must be filled out.
As I said, the bean is session scoped, and I have double-checked that the persons list does not change between requests, which seems to be a common problem with this tag.
Any ideas?
The generic type information is lost during runtime. All JSF/EL (actually, reflection) sees is a List, not a List<Long>. The default type is String as that's just the standard return type of request.getParameter(). This can never return true on a equals() check on any of the Long values in the list of available items. That explains the "Validation Error: Value is not valid" error.
You need a fixed type property such as long[] or Long[] so that JSF/EL will be able to determine the right type by reflection.
If you really need it to be a List<Long> due to design restrictions, then you should explicitly specify a converter. Otherwise JSF will just fill it with unconverted String objects which would in the end only cause ClassCastException when the business code starts to iterate over it.
You can use the JSF builtin javax.faces.Long converter for this.
<h:selectManyCheckbox ... converter="javax.faces.Long">
Update: based on the comments, the long[] has most likely caused a conversion error, while Long[] works. This is most likely a JSF 1.1 specific bug. Just stick to Long[] then.
This question already has answers here:
Validation Error: Value is not valid
(3 answers)
Closed 6 years ago.
I am using the managedBean userHome in requestScope, in which the entity 'user' is going to be persist.
The user has the leader column which is mapped in ManyToOne relation.My Code looks like this
#ManagedBean
#RequestScoped
public class UserHome {
private User user = new User();
// Getters and Setters
private List<SelectItem> selectItems = new ArrayList<SelectItem>();
public UserHome() {
for(User user: availableLeaders) {
selectItems.add(new SelectItem(user.getName(), user));
}
}
public void persis();
}
User.java
public class User {
#Id
#Column
private Integer id;
#Column
privat String name;
#ManyToOne
private User leader;
}
I am trying to get the value of this leader through h:selectOneMenu like this
<h:selectOneMenu value="#{userHome.user.leader}" converter="userConverter">
<f:selectItems value="#{userHome.selectItems}"/>
</h:selectOneMenu>
My converter looks like this
#FacesConverter(forClass = User.class, value="userConverter")
public class UserConverter implements Converter {
private Map<String, User> userValues = new HashMap<String, User>();
public UserConverter() {
init();
}
#Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
return userValues.get(value);
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
System.out.println("RAJASEKARAN "+value);
return ((User)value).getName();
}
public void init() {
UserHome userHome = new UserHome();
for(User user:userHome.availableLeaders()) {
userValues.put(user.getName(), user);
}
}
}
While try to save the user I am getting the error UserEdit:j_idt18: Validation Error: Value is not valid
Adding to BalusC's answer: after the postback, you need to make sure that the User instances are either exactly the same ones as you used for rendering the select items, or that you implement equals for your User class.
The code doesn't show where availableLeaders comes from, but if this is fetched from a DB on-demand, then the converter will not convert to the exact same object instance that's in the list that JSF resolves via #{userHome.selectItems}.
After the conversion, JSF will check whether the converted instance can be found in that list using the equals() method.
You've constructed the SelectItem the wrong way. As per the class' documentation, the 1st argument should represent the item value (which is to be converted and submitted) and the 2nd argument should represent the item label (which is to be displayed in list). But you specified them the other way round.
Fix it accordingly:
selectItems.add(new SelectItem(user, user.getName()));
If that still doesn't fix the problem, then it means that the equals() method of User class is not (properly) implemented. JSF will use it to validate the selected User against any of the item values of the list after conversion.
Unrelated to the concrete problem, it may be useful to know that <f:selectItems> in JSF2 offers you the possibility to build the list without the need to build a list of SelectItem manually. Here's an example which achieves exactly the same:
<f:selectItems value="#{userHome.availableLeaders}" var="user"
itemValue="#{user}" itemLabel="#{user.name}" />
This allows you to get rid of the additional selectItems property and the loop in the bean constructor.
I'm having a hard time with a selectManyCheckbox.
Basically what I am doing is loading a List of Categories in a selectManyCheckbox type controller (have done this either with a List or with a List with convertEntity). My problem is with the selected elements (value="#{cardListProvider.categoriesHolder.selectedCategories}"). After some reading I understand it also has to be a List, but what kind? And how can I set the selected categories? I'm not saving them in DB but I need to run some action in the bean with them!
Here's what I have:
<h:selectManyCheckbox id="supportCategoryCardFilter"
value="#{cardListProvider.categoriesHolder.selectedCategories}" styleClass="greyText" required="false" >
<s:selectItems var="filterList" value="#{cardListProvider.categoriesList}" label="#{filterList.label}" />
<a:support id="supportCategoryCardFilter2" event="onchange"
reRender="someHolder, categoriesPanel" eventsQueue="onchange" action="#{cardListProvider.findCards(cardListProvider.categoriesHolder.selectedCategories)}" />
</h:selectManyCheckbox>
I have wasted several hours with this... Can anyone help me?
Thank you
You can bind to a String[] array like so:
public class CheckSelector {
private String[] chosen;
public String[] getChosen() { return chosen; }
public void setChosen(String[] chosen) { this.chosen = chosen; }
public SelectItem[] getChoices() {
return new SelectItem[] { new SelectItem("1"), new SelectItem("2"),
new SelectItem("3") };
}
}
The value of the selectManyCheckbox should be bound to chosen. Alternatively, you can use a List:
public class CheckSelector {
private List<String> chosen;
public List<String> getChosen() { return chosen; }
public void setChosen(List<String> chosen) { this.chosen = chosen; }
public List<SelectItem> getChoices() {
return Arrays.asList(new SelectItem("1"), new SelectItem("2"),
new SelectItem("3"));
}
}
The exact rules for value support are listed in the javadoc:
If the component has an attached Converter, use it.
If not, look for a ValueExpression for value (if any). The ValueExpression must point to something that is:
An array of primitives (such as int[]). Look up the registered by-class Converter for this primitive type.
An array of objects (such as Integer[] or String[]). Look up the registered by-class Converter for the underlying element type.
A java.util.List. Assume that the element type is java.lang.String, so no conversion is required.
If for any reason a Converter cannot be found, assume the type to be a String array.
I see you are using Seam so no need to use Strings or any primitive type, you can bind directly to List. You just have to add another tag inside your selectManyCheckbox component which is and it will automatically do everything.
Better than doing all by yourself, check Seam documentation
http://docs.jboss.org/seam/2.2.0.GA/reference/en-US/html/controls.html#d0e28378