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
5
votes
2 answers

IE8 and Primefaces p:selectOneMenu misbehave when having a lots of p:selectOneMenu in a form

First of all, I want to apologize for the long code I post, they are very simple, it is just a p:selectOneMenu that repeat 17 times (that why it is long). The problem that I experience is that if I have too many p:selectOneMenu in a form, the…
Thang Pham
  • 38,125
  • 75
  • 201
  • 285
5
votes
1 answer

Adding Primefaces components dynamically

I want to add Primefaces components dynamically. I'm using solution similar to this one, which was discussed there earlier:
nikagra
  • 835
  • 2
  • 9
  • 23
5
votes
2 answers

JSF selectOneMenu is refreshing and going back to its previous state rather than showing the new value

I have a datatable where a lot of selectOneMenu items are available , for example, for 10 items each having one selectOneMenu combo. now if i click on any of the combos, they are supposed to save the value in the database and they do it. but after…
Ikthiander
  • 3,917
  • 8
  • 37
  • 54
5
votes
1 answer

Lazy loading f:selectItems when opening p:selectOneMenu

I would like to load list of only when user opens . I tried this way but doesn't work:
Mathew Rock
  • 989
  • 2
  • 14
  • 32
5
votes
2 answers

doesn't seem to have any effect

I have following select one menu. but case sensitive is not working in it. when I press small a or capital A, it always shows small a (whichever occurs first).
Imran Khurram
  • 377
  • 8
  • 18
5
votes
1 answer

selectonemenu jsf on objects with converter

Here is my SelectOneMenu
Loric
  • 1,678
  • 8
  • 28
  • 48
5
votes
1 answer

p:selectOneMenu dropdown not attached to the component inside a dialog

I have a p:selectOneMenu inside a p:dialog. Whenever I scroll the page, the dropdown detaches from the p:selectOneMenu label and moves according to the mouse scroll. Is there any way to attach it to the label so that it doesn't move? Here's a…
Rajath
  • 2,178
  • 6
  • 32
  • 38
5
votes
3 answers

Navigate using p:selectOneMenu

I'm using a select one menu to do navigation to different parts of my site:
DD.
  • 21,498
  • 52
  • 157
  • 246
5
votes
1 answer

Getting selected value of a SelectOneMenu

I'm testing the component "SelectOneMenu" on a jsf page. I'm populating this component dinamically though my ManageBean (that will get all Animals from database). I would like to know if is possible to see the user selected item of that…
Luis Pereira
  • 1,481
  • 3
  • 19
  • 46
5
votes
1 answer

Error with p:selectOneMenu in Primefaces 3.4.2

I recently updated Primefaces from 3.4 to 3.4.2 and now I have problems on some pages where there is p:selectOneMenu component. I see error in JavaScript console which says: TypeError: e.offset(...) is undefined. This error is logged immediately on…
partlov
  • 13,789
  • 6
  • 63
  • 82
5
votes
1 answer

p:selectOneMenu preselects previous item when noSelectionOption item is present

There is a problem with p:selectOneMenu selection when adding a f:selectItem. View:
ehab refaat
  • 854
  • 2
  • 12
  • 23
5
votes
1 answer

Update SelectOneMenu if value of ohter SelectOneMenu is set (Event isn't fired)

In my application I'm trying to set/update a SelectOneMenu if another SelectOneMenu is set. We're using primefaces, so I checked the primefaces showcase and found exactly what I was looking for. Unfortunately it's not working. The Event isn't fired…
Raphael_S
  • 152
  • 2
  • 3
  • 13
5
votes
2 answers

JSF . SelectOneMenu and SelectItems

I'm trying to let user select an item of a collection from a dropdown list in JSF. This is the code I'm using:
andreaxi
  • 931
  • 5
  • 15
  • 28
4
votes
2 answers

How can I get values out of a selectOneMenu inside a JSF datatable?

I have a JSF datatable with a bunch of rows, with each row having a selectOneMenu inside of it like this:
Galen
4
votes
1 answer

How to preselect an option of h:selectOneMenu

Is it possible to preselect one of the options from the select menu? I have this UI Component: The values of…
Ionut
  • 2,788
  • 6
  • 29
  • 46
1 2
3
42 43