Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the default size for the select element rendered by a h:selectOneMenu?

According to the JSF specification, a h:selectOneMenu is rendered as an HTML <select> element, with the "size" attribute set to the number of items:

Use the number of items as the value of the "size" attribute.

(from the tag documentation for selectOneMenu)

However, when I use h:selectOneMenu in a page (using Mojarra or MyFaces), the size attribute of the rendered <select> is always set to 1.

Googling around also finds many pages which simply claim that h:selectOneMenu is suposed to render a "dropdown menu" (which is what most browsers render for <select size="1">[...].

So is this a bug in the JSF spec, or is there some detail I overlooked? Why is the size not behaving as described in the spec?

like image 740
sleske Avatar asked Feb 03 '26 05:02

sleske


1 Answers

After looking at the source code of the MenuRenderer class, from the com.sun.faces.renderkit.html_basic package, it's not clear whether it's a bug in the specification or not.

In order to render the h:selectOneMenu component, as well as the h:selectManyMenu component, the renderSelect method is called. About the size attribute :

  • If it is not specified (which is the selectOneMenu case), a default value is set.
  • If it is specified, the "size" attribute will be rendered as one of the "pass thru" attributes.

Here is the source code :

 protected void  [More ...] renderSelect(FacesContext context,
                            UIComponent component) throws IOException {

    [...]

    // Determine how many option(s) we need to render, and update
    // the component's "size" attribute accordingly;  The "size"
    // attribute will be rendered as one of the "pass thru" attributes

    [...]

    // If "size" is *not* set explicitly, we have to default it correctly
    Integer size = (Integer) component.getAttributes().get("size");
    if (size == null || size == Integer.MIN_VALUE) {
        size = count;
    }
    writeDefaultSize(writer, size);

    RenderKitUtils.renderPassThruAttributes(context,
                                    writer,
                                    component,
                                    ATTRIBUTES,
                                    getNonOnChangeBehaviors(component));

    [...]

}

The confusion lies in the writeDefaultSize method. It always sets the default size to 1, even if the number of options to be rendered is given by an itemCount parameter :

 protected void  [More ...] writeDefaultSize(ResponseWriter writer, int itemCount)
    throws IOException {
     // if size is not specified default to 1.
     writer.writeAttribute("size", "1", "size");
 }

So the size is neither behaving as described in the JSF spec, nor as described in the code's comments. It may not be a bug but it's a little confusing.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!