Questions tagged [selectonemenu]

JSF tag to create a single-select menu.

A <h:selectOneMenu> is a JSF UI component which generates a HTML <select> element which allows you to bind the selected value to a managed bean property.

Basic example

You can use <f:selectItem> to define menu options which get generated as HTML <option> elements.

View:

<h:form>
    <h:selectOneMenu value="#{bean.selectedItem}">
        <f:selectItem itemValue="#{null}" itemLabel="-- select one --" />
        <f:selectItem itemValue="foo" itemLabel="Foo label" />
        <f:selectItem itemValue="bar" itemLabel="Bar label" />
        <f:selectItem itemValue="baz" itemLabel="Baz label" />
    </h:selectOneMenu>
    <h:commandButton value="Submit" action="#{bean.submit}" />
</h:form>

Model:

private String selectedItem; // +getter +setter

public void submit() {
    System.out.println("Selected item: " + selectedItem);
}

The itemValue is what will be set as managed bean property. The itemLabel is what will be displayed as option label in the UI. If the itemLabel is omitted, then it will default to the same value as itemValue.

You can preselect an item by giving the selectedItem a value in the bean's (post)constructor. E.g.

@PostConstruct
public void init() {
    selectedItem = "bar";
}

This will show the menu with "Bar label" preselected.

Dynamic list

You can use <f:selectItems> to display a list which is dynamically populated in the backing bean. You can use javax.faces.model.SelectItem to represent a pair of item value and label.

View:

<h:form>
    <h:selectOneMenu value="#{bean.selectedItem}">
        <f:selectItem itemValue="#{null}" itemLabel="-- select one --" />
        <f:selectItems value="#{bean.availableItems}" />
    </h:selectOneMenu>
    <h:commandButton value="Submit" action="#{bean.submit}" />
</h:form>

Model:

private String selectedItem; // +getter +setter
private List<SelectItem> availableItems; // +getter (no setter necessary)

@PostConstruct
public void init() {
    availableItems = new ArrayList<SelectItem>();
    availableItems.add(new SelectItem("foo", "Foo label"));
    availableItems.add(new SelectItem("bar", "Bar label"));
    availableItems.add(new SelectItem("baz", "Baz label"));
}

The availableItems can also be a SelectItem[]. If you omit the item label and thus can use the item value as both option value and option label, then you can also use a List<String> or String[] instead.

private String selectedItem; // +getter +setter
private List<String> availableItems; // +getter (no setter necessary)

@PostConstruct
public void init() {
    availableItems = Arrays.asList("foo", "bar", "baz");
}

A Set is also supported.

private String selectedItem; // +getter +setter
private Set<String> availableItems; // +getter (no setter necessary)

@PostConstruct
public void init() {
    availableItems = new LinkedHashSet<String>(Arrays.asList("foo", "bar", "baz"));
}

Note that you should use a LinkedHashSet to maintain the insertion order, or a TreeSet if you want automatic sorting by value. A HashSet is by nature unordered.

Dynamic list with groups

You can use SelectItemGroup to group items.

private String selectedItem; // +getter +setter
private List<SelectItem> availableItems; // +getter (no setter necessary)

@PostConstruct
public void init {
    availableItems = new ArrayList<SelectItem>();

    SelectItemGroup group1 = new SelectItemGroup("Group 1");
    group1.setSelectItems(new SelectItem[] {
        new SelectItem("Group 1 Value 1", "Group 1 Label 1"),
        new SelectItem("Group 1 Value 2", "Group 1 Label 2"),
        new SelectItem("Group 1 Value 3", "Group 1 Label 3")
    });
    availableItems.add(group1);

    SelectItemGroup group2 = new SelectItemGroup("Group 2");
    group2.setSelectItems(new SelectItem[] {
        new SelectItem("Group 2 Value 1", "Group 2 Label 1"),
        new SelectItem("Group 2 Value 2", "Group 2 Label 2"),
        new SelectItem("Group 2 Value 3", "Group 2 Label 3")
    });
    availableItems.add(group2);
}

Here's how it look like in the browser (note that Group 1 and Group 2 are unselectable):

alt text

Dynamic map

The <f:selectItems> also supports a Map<K, V> where K is to be represented as item label and V is to be represented as item value.

View:

<h:form>
    <h:selectOneMenu value="#{bean.selectedItem}">
        <f:selectItem itemValue="#{null}" itemLabel="-- select one --" />
        <f:selectItems value="#{bean.availableItems}" />
    </h:selectOneMenu>
    <h:commandButton value="Submit" action="#{bean.submit}" />
</h:form>

Model:

private String selectedItem; // +getter +setter
private Map<String, String> availableItems; // +getter (no setter necessary)

@PostConstruct
public void init() {
    availableItems = new LinkedHashMap<String, String>();
    availableItems.put("Foo label", "foo");
    availableItems.put("Bar label", "bar");
    availableItems.put("Baz label", "baz");
}

If you want to swap the K and V in the view side so that you can populate the item values and labels the other way round like follows

@PostConstruct
public void init() {
    availableItems = new LinkedHashMap<String, String>();
    availableItems.put("foo", "Foo label");
    availableItems.put("bar", "Bar label");
    availableItems.put("baz", "Baz Label");
}

Then you first need to make sure that your environment supports EL 2.2 (part of Servlet 3.0, i.e. target server is Tomcat 7, Glassfish 3, etc and web.xml is declared conform Servlet 3.0), then you can iterate over Map#entrySet() in <f:selectItems> as follows:

<f:selectItems value="#{bean.availableItems.entrySet()}" var="entry" 
    itemValue="#{entry.key}" itemLabel="#{entry.value}" />

Note that you should use a LinkedHashMap to maintain the insertion order, or a TreeMap if you want automatic sorting by map key. A HashMap is by nature unordered.

Dynamic list of objects

Since JSF 2.0, you can also use a List<Bean> or Bean[] instead where Bean is just an arbitrary javabean class. Assuming that you've a Country bean with two String properties code and name and you want to store the code as selected item value and display the name as item label, then you can use the var attribute of <f:selectItems> without the need to convert it to List<SelectItem> or SelectItem[].

View:

<h:form>
    <h:selectOneMenu value="#{bean.countryCode}">
        <f:selectItem itemValue="#{null}" itemLabel="-- select one --" />
        <f:selectItems value="#{bean.countries}" var="country" 
            itemValue="#{country.code}" itemLabel="#{country.name}" />
    </h:selectOneMenu>
    <h:commandButton value="Submit" action="#{bean.submit}" />
</h:form>

Model:

private String countryCode; // +getter +setter
private List<Country> countries; // +getter (no setter necessary)

@EJB
private DataService service;

@PostConstruct
public void init() {
    countries = service.getCountries();
    // If this is a static list, you'd rather put this
    // in a separate application scoped bean instead.
}

public void submit() {
    System.out.println("Selected country code: " + countryCode);
}

Storing objects as item value

From the example in the previous section, you can also set the whole Country as a managed bean property. You'd only need to create a converter which converts between Country and String. A more concrete example can be found in those answers:

Validation Error: Value is not valid

This dreaded error will occur when roughly the following happens under the JSF covers during submitting the form:

String submittedValue = request.getParameter(component.getClientId());
Converter converter = component.getConverter();
Object selectedItem = (converter != null) ? converter.getAsObject(context, component, submittedValue) : submittedValue;

boolean valid = false;

for (Object availableItem : bean.getAvailableItems()) {
    if (selectedItem.equals(availableItem)) {
        valid = true;
        break;
    }
}

if (!valid) {
    throw new ValidatorException("Validation Error: Value is not valid");
}

You see, it will occur when the selected item does not equal any of the available items. This can in turn have 3 causes:

  1. The list of available items from bean has changed during the form submit.
  2. The equals() method of the object type behind the item is missing or broken.
  3. If any used, the converter has returned the wrong item or even null on getAsObject().

See also this answer: Validation Error: Value is not valid.

Static list of enums

You can also use an enum as available items and selected item.

View:

<h:form>
    <h:selectOneMenu value="#{bean.selectedItem}">
        <f:selectItem itemValue="#{null}" itemLabel="-- select one --" />
        <f:selectItems value="#{bean.availableItems}" />
    </h:selectOneMenu>
    <h:commandButton value="Submit" action="#{bean.submit}" />
</h:form>

Model:

public enum Option {
    FOO, BAR, BAZ;
}

private Option selectedItem; // +getter +setter

public void submit() {
    System.out.println("Selected item: " + selectedItem);
}

public Option[] getAvailableItems() {
    return Option.values();
}

See also this answer how to change and internationalize item labels: How to use enum values in f:selectItem(s).

Populate a child menu

You can use the JSF 2.0 <f:ajax> tag to dynamically populate a child menu depending on the selected item of the current menu. Here's an example which does that for countries-cities.

View:

<h:selectOneMenu value="#{bean.country}" converter="countryConverter">
    <f:selectItem itemValue="#{null}" itemLabel="-- select one --" />
    <f:selectItems value="#{bean.countries}" var="country" 
        itemValue="#{country}" itemLabel="#{country.name}" />
    <f:ajax listener="#{bean.loadCities}" render="cities" />
</h:selectOneMenu>
<h:selectOneMenu id="cities" value="#{bean.city}" converter="cityConverter">
    <f:selectItem itemValue="#{null}" itemLabel="-- select one --" />
    <f:selectItems value="#{bean.cities}" var="city" 
        itemValue="#{city}" itemLabel="#{city.name}" />
</h:selectOneMenu>

Model in @ViewScoped bean:

private Country country; // +getter +setter
private City city; // +getter +setter

private List<Country> countries; // +getter
private List<City> cities; // +getter

@EJB
private DataService service;

@PostConstruct
public void loadCountries() {
    countries = service.getCountries();
}

public void loadCities() {
    cities = service.getCities(country);
}
634 questions
0
votes
1 answer

Create dynamic ENUM Menu Tag in JSF 1.2

I'm struggling on this problem because it destroys my modularity a bit. I'm using JSF 1.2 and facing to use an h:selectOneMenu to select one value of a given set of Enums. e.g. public enum State { A,B,C; }; For instance, i'd do sth.…
DmiN
  • 736
  • 1
  • 7
  • 21
0
votes
0 answers

Retrieve two properties using

I am displaying two values in JSF and want to retrieve both values in managed bean. following is my JSF code.
RK.
  • 973
  • 5
  • 19
  • 45
0
votes
1 answer

How can I get item label from selectOneMenu @ JSF page

I'm dealing with a wizard in primefaces like this one: http://www.primefaces.org/showcase/ui/wizard.jsf I would like to get the raw text from a selectOneMenu (from one of the tabs) and show it in the confirmation tab. My selectOneMenu looks like…
Sebastián
  • 1
  • 2
  • 2
  • 4
0
votes
3 answers

JSF getting object from the selectOneMenu

I have a problem again with JSF. I am still learning and your help is much apreciated.
Mateusz Gaweł
  • 673
  • 1
  • 8
  • 22
0
votes
1 answer

JSF selectOneMenu not whole List

Is it possible to choose only specific items from the list in selectOneMenu? For example. I have List Products has many fields like name, id etc. One of it is category (1,2 or 3) I want to have only one category in the selectOneMenu without making…
Mateusz Gaweł
  • 673
  • 1
  • 8
  • 22
0
votes
1 answer

JSF selectOneMenu with Object iteration

I do know that similar problem was announced here few times but I spent a lot of time and still have no idea why that code doesn't work :/ This is my JSF page:
Mateusz Gaweł
  • 673
  • 1
  • 8
  • 22
0
votes
1 answer

I'm stuck on dynamic panel

I met a problem for two days. nowhere I advance my problem is to make a dynamic content in a panel according to the selected element in the list p: selectOneMenu
FERESSS
  • 137
  • 1
  • 5
  • 14
0
votes
1 answer

Keep old values of a List for a back to the previous

i don't know if i can clearly explain my problem but i will try :) I have lot of folder , and each folder depends of an other. Example : Document, Pictures , Other depends of root. Text depends of Documents. PNG,GIF,JPG depends of Pictures. The…
user2239695
  • 57
  • 1
  • 10
0
votes
1 answer

CommandButon 's actionListener not working

Mi actionListener in commandButton is not called after i select an item in a h:selectOneMenu, only it works when i press button witout any selection in selectOneMenu Below you can see my code:
Aredalo
  • 23
  • 2
0
votes
0 answers

many selectOneMenu depending in each other in different lines

I have many lines (in a table). In the first line I have three selectOneMenu: the first contains the names of continents the second contains the names of towns (depending on the continent selected in the first selectOneMenu) the third one contains…
ktaria
  • 423
  • 6
  • 16
0
votes
2 answers

use generic entityConverter (proposed by BalusC) for selectonemenu if primefaces

I want to use this generic converter in all but it doesn't show data and I have no exceptions. I don't know the problem
simonTifo
  • 307
  • 3
  • 12
  • 29
0
votes
2 answers

Setting default value to h: selectOneMenu on button click

I am displaying a output panel on button click, it has an selectonemenu item, by default value 1 is selected, when i change some value and click CANCEL button and reopen output panel, the last selected value is getting displayed. is there any way to…
ziaur25
  • 85
  • 12
0
votes
1 answer

Pick Custom Object from Select one menu JSF Converter Exception

i want to pick custom object from select one menu. it neither shows an error nor values. what to do? please help me. thanks in advance. Now i'm seeing Null pointer exception at getAsObject at this line: return…
Umair
  • 860
  • 2
  • 13
  • 30
0
votes
1 answer

Is there a library for displaying Timezone in a selectOneMenu

Currently, in my application, I use the following snippet to instantiate a timezone list for displaying in a selectOneMenu: @Named @ApplicationScoped public class MrBean { private String[] timezoneIDs; @PostConstruct public void init()…
Mr.J4mes
  • 9,168
  • 9
  • 48
  • 90
0
votes
2 answers

FacesConverter fail when id greater than 127?

I have a primefaces selectOneMenu and it uses a javax.faces.convert.Converter for displaying devices. It works fine only when the key (device's id) is not greater than 127. When it's greater, after clicking a commandButton the selectOneMenu's arrow…
Teodor
  • 1