Achaius
Achaius

Reputation: 6124

h:selectOneMenu is not working with jsf2

Recently we migrated to jboss-6.0.0.Final wiith richfaces-3.3.3.Final and jsf-2.0. After deployment we found the <h:selectOneMenu/> is not working properly if selectItems has the attribute 'noSelectionLabel' even <s:convertEnum/> is passed to the component. For example

        <h:selectOneMenu id="gender" value="#{user.gender}">
            <s:selectItems noSelectionLabel="Select Gender"/>
            <f:selectItems value="#{user.genderTypes}" />
            <s:convertEnum />
        </h:selectOneMenu>


public Map<String, Gender> getGenderTypes() {
    Gender[] values = Gender.values();
    Map<String, Gender> genderTypes = new LinkedHashMap<String, Gender>(values.length);

    for (Gender gender : values) {
        genderTypes.put(gender.toString(), gender);
    }

    return genderTypes;
}

If value is not provided to this element, on page submit I am getting an error that

"Constant 'Select Gender' is not found on enum Gender"

. Then I analysed JSF 2 is initialized under Mojarra-2.0. I changed this to Mojarra-1.2 in web.xml like this

<context-param>
      <param-name>org.jboss.jbossfaces.JSF_CONFIG_NAME</param-name>
      <param-value>Mojarra-1.2</param-value> </context-param>

After this I am getting the deployment error

Caused by: java.lang.NoClassDefFoundError: org/richfaces/context/PartialViewConextImpl

My web.xml

<?xml version="1.0" ?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

    <!-- RichFaces -->

    <context-param>
        <param-name>org.richfaces.SKIN</param-name>
        <param-value>blueSky</param-value>
    </context-param>

    <!-- Suppress spurious stylesheets -->

    <context-param>
        <param-name>org.richfaces.CONTROL_SKINNING</param-name>
        <param-value>enable</param-value>
    </context-param>

    <context-param>
        <param-name>org.richfaces.CONTROL_SKINNING_CLASSES</param-name>
        <param-value>enable</param-value>
    </context-param>

    <!-- Added to force facelets to ignore comments -->

    <context-param>
        <param-name>facelets.SKIP_COMMENTS</param-name>
        <param-value>true</param-value>
    </context-param>

    <!--
        Change load strategy to DEFAULT to disable sending scripts/styles as
        packs
    -->

    <context-param>
        <param-name>org.richfaces.LoadStyleStrategy</param-name>
        <param-value>ALL</param-value>
    </context-param>

    <context-param>
        <param-name>org.richfaces.LoadScriptStrategy</param-name>
        <param-value>ALL</param-value>
    </context-param>

    <!-- Seam -->

    <listener>
        <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>Seam Resource Servlet</servlet-name>
        <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Seam Resource Servlet</servlet-name>
        <url-pattern>/seam/resource/*</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>Seam Filter</filter-name>
        <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>Seam Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- Facelets development mode (disable in production) -->

    <context-param>
        <param-name>facelets.DEVELOPMENT</param-name>
        <param-value>false</param-value>
    </context-param>

    <!-- JSF -->

    <context-param>
        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        <param-value>.xhtml</param-value>
    </context-param>

    <!-- Session Timeout -->

    <context-param>
        <param-name>org.ajax4jsf.handleViewExpiredOnClient</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>org.ajax4jsf.DEFAULT_EXPIRE</param-name>
        <param-value>86400</param-value>
    </context-param>

    <!-- This param is needed to change the JSF configuration of our WAR -->
    <context-param>
          <param-name>org.jboss.jbossfaces.JSF_CONFIG_NAME</param-name>
          <param-value>Mojarra-1.2</param-value>
     </context-param>

    <!-- Faces servlet -->

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.seam</url-pattern>
    </servlet-mapping>

    <security-constraint>
        <display-name>Restrict raw XHTML Documents</display-name>
        <web-resource-collection>
            <web-resource-name>XHTML</web-resource-name>
            <url-pattern>*.xhtml</url-pattern>
        </web-resource-collection>
        <auth-constraint />
    </security-constraint>

    <session-config>
        <session-timeout>20</session-timeout>
    </session-config>

</web-app>

How to resolve this?

Upvotes: 1

Views: 2792

Answers (2)

BalusC
BalusC

Reputation: 1108852

Since JSF 1.2, there's a builtin enum converter. You do not need a custom converter. To represent a default selection without a value, just use <f:selectItem> without an itemValue. Also, since JSF 2.0 you do not necessarily need a SelectItem[], List<SelectItem> or Map<K, V> for <f:selectItems> anymore. Just an T[] or List<T> is also supported. There's even a var attribute so that the item label and value could be set with the properties of T.

So, this view:

<h:selectOneMenu value="#{bean.gender}" required="true">
    <f:selectItem itemLabel="Select gender" />
    <f:selectItems value="#{bean.genders}" />
</h:selectOneMenu>

with this model:

private Gender gender; // +getter +setter

public Gender[] getGenders() {
    return Gender.values();
}

should work as good without much hassle.

Upvotes: 2

Rasmus Franke
Rasmus Franke

Reputation: 4524

I have noticed this aswell under slightly different circumstances. If you explicitly assign a converter to an inputelement and have null as value (noSelecrtion), it will for some weird reason send the label instead of the value to the converter. I go around the problem by using the forClass attribute of @FacesConverter, or using JSF default converters (the enum one works okay for me).

Upvotes: 0

Related Questions