Quiero hacer una selectOneMenu desplegable para que yo pueda seleccionar un estado en mi pregunta. Es posible que la f:selectItem más flexible teniendo en cuenta lo que sucede si el orden de las enumeraciones de los cambios, y si la lista era grande? Y podría hacer esto mejor? Y es posible de forma automática «seleccionar» el elemento que la pregunta tiene?

Clase Enum

public enum Status {
    SUBMITTED,
    REJECTED,
    APPROVED
}

Pregunta entidad

@Enumerated(EnumType.STRING)
private Status status;

JSF

<div class="field">
    <h:outputLabel for="questionStatus" value="Status" />
    <h:selectOneMenu id="questionStatus" value="#{bean.question.status}" >
        <f:selectItem itemLabel="Submitted" itemValue="0" />
        <f:selectItem itemLabel="Rejected" itemValue="1" />
        <f:selectItem itemLabel="Approved" itemValue="2" />
    </h:selectOneMenu>
    <hr />
</div>
InformationsquelleAutor LuckyLuke | 2011-11-22

4 Comentarios

  1. 203

    JSF se ha incorporado un convertidor enum, por lo que este debe hacer:

    @ManagedBean
    @ApplicationScoped
    public class Data {
    
        public Status[] getStatuses() {
            return Status.values();
        }
    
    }

    con

    <h:selectOneMenu value="#{bean.question.status}" >
        <f:selectItems value="#{data.statuses}" />
    </h:selectOneMenu>

    (nota: desde JSF 2.0 no hay necesidad de proporcionar un SelectItem[] o List<SelectItem>, un T[] y List<T> se aceptan así y usted puede tener acceso al elemento actual por var atributo)

    Si quieres pasar a utilizar JSF utilidad de la biblioteca OmniFaces, entonces usted podría utilizar <o:importConstants> en lugar de un bean.

    <o:importConstants type="com.example.Status" />
    
    <h:selectOneMenu value="#{bean.question.status}" >
        <f:selectItems value="#{Status}" />
    </h:selectOneMenu>

    Si usted tiene la intención de controlar las etiquetas así, se podría añadir a la Status enum:

    public enum Status {
    
        SUBMITTED("Submitted"),
        REJECTED("Rejected"),
        APPROVED("Approved");
    
        private String label;
    
        private Status(String label) {
            this.label = label;
        }
    
        public String getLabel() {
            return label;
        }
    
    }

    con

    <f:selectItems value="#{data.statuses}" var="status"
        itemValue="#{status}" itemLabel="#{status.label}" />

    O, mejor, hacer la enumeración valor de una propiedad clave de un recurso localizado paquete (EL 3.0):

    <f:selectItems value="#{data.statuses}" var="status"
        itemValue="#{status}" itemLabel="#{text['data.status.' += status]}" />

    con esto en un archivo de propiedades asociadas con los recursos bundle #{text}

    data.status.SUBMITTED = Submitted
    data.status.REJECTED = Rejected
    data.status.APPROVED = Approved
    • Una cosa BalusC, es posible «seleccione»/ver el estado en que una pregunta tiene como valor predeterminado (por ejemplo, cuando se está editando una pregunta que ya ha establecido el estado de la cuestión a algo)
    • En el ejemplo anterior, JSF hará por defecto cuando #{bean.question.status} tiene un válido el valor de enumeración. Usted no necesita hacer nada esperar de garantizar que la question tiene el correcto estado de propiedad prellenada.
    • Cómo acceder a valor ordinal de JSF?
    • No funciona. Sólo muestra una lista vacía. Por qué?
    • No, simplemente no. stackoverflow.com/revisions/8229982/5
    • Si, como yo, se obtiene un formato de número a excepción de += status, a continuación, intente utilizar .concat(status) como @Ziletka sugiere.
    • Si prefieres java.util.De la lista sólo puede modificar getStatuses() tipo devuelto a la Lista de<Estado> y devuelven Matrices.asList(de Estado.los valores de());
    • Debido a la herencia (en mi caso) JSF no es capaz de detectar el tipo de destino como una enumeración. Es allí una manera a fuerza de JSF para convertir el valor?
    • Si quiero controlar las etiquetas de los selectOneMenu ‘s elementos con algo como: <f:selectItems value="#{receiptController.allPaymentTypes()}" var="paymentType" itemValue="#{paymentType}" itemLabel="#{msg[paymentType.i18nKey]}" /> por msg es mi mensaje y paquete de i18nKey es un todo-en mayúsculas clave en mi mensaje de paquete.
    • ¿Cómo se le ocurrió que <f:selectItems value="#{Status}" /> está llamando Status.values(). ¿Por qué es suficiente y por qué se prefieren a <f:selectItems value="#{Status.values()}" />. Gracias 🙂
    • Haga clic en el enlace detrás de <o:importConstants> para aprender acerca de su trabajo.
    • No encontré la respuesta a mi pregunta en esa página. Además no he podido encontrar la respuesta de por qué usted prefiere <f:selectItems value="#{Status}" /> más de <f:selectItems value="#{Status.values()}" />. Yo sólo estaba interesado en sus preferencias personales y por qué elegir una forma sobre la otra. Pero no hay problema.

  2. 16

    Para la localización, podemos utilizar también esta solución:

    public enum Status { SUBMITTED, REJECTED, APPROVED }
    
    data.status.SUBMITTED=Submitted
    data.status.REJECTED=Rejected
    data.status.APPROVED=Approved
    
    <h:selectOneMenu value="#{bean.question.status}" >
        <f:selectItems
            value="#{data.statuses}"
            var="status"
            itemValue="#{status}"
            itemLabel="#{text['data.status.'.concat(status)]}" />
    </h:selectOneMenu>

    Por lo que la ruta de acceso a recursos para la localización de las cadenas no están codificados en la Enumeración.

    • Tenga en cuenta que esta sintaxis es sólo compatible desde EL 2.2 que es «relativamente» nuevo. De lo contrario, siempre se puede agarrar <c:set> o <ui:param> o homebrew una costumbre EL de la función.
    • Gracias BalusC. Es posible de alguna manera sustituir #{datos.estados} con Clase enum, sin utilizar la copia de frijol (por ejemplo, value=»#{org.myproject.Estado.los valores}»)?
    • estás seguro? Estoy usando GF 3.1.2 (Mojarra JSF 2.1.6).
    • EL 2.2 es parte de Java EE 6.
  3. 4

    Usted podría utilizar <f:selectItems value="#{carBean.carList}" /> y devolver una lista de SelectItem casos que envuelven el enum (uso Status.values() para obtener todos los posibles valores).

  4. 2

    Puede utilizar la siguiente utilidad el de la función para obtener los valores de enumeración y el uso de ellos en un SelectOneMenu por ejemplo. No hay necesidad de crear frijoles y repetitivo métodos.

    public final class ElEnumUtils
    {
        private ElEnumUtils() { }
    
        /**
         * Cached Enumerations, key equals full class name of an enum
         */
        private final static Map<String, Enum<?>[]> ENTITY_ENUMS = new HashMap<>();;
    
        /**
         * Retrieves all Enumerations of the given Enumeration defined by the
         * given class name.
         *
         * @param enumClassName Class name of the given Enum.
         *
         * @return
         *
         * @throws ClassNotFoundException
         */
        @SuppressWarnings("unchecked")
        public static Enum<?>[] getEnumValues(final String enumClassName) throws ClassNotFoundException
        {
            //check if already cached - use classname as key for performance reason
            if (ElEnumUtils.ENTITY_ENUMS.containsKey(enumClassName))
                return ElEnumUtils.ENTITY_ENUMS.get(enumClassName);
    
            final Class<Enum<?>> enumClass = (Class<Enum<?>>) Class.forName(enumClassName);
    
            final Enum<?>[] enumConstants = enumClass.getEnumConstants();
    
            //add to cache
            ElEnumUtils.ENTITY_ENUMS.put(enumClassName, enumConstants);
    
            return enumConstants;
        }
    }

    Registro como el de la función en un taglib archivo:

    <function>
        <description>Retrieves all Enumerations of the given Enumeration defined by the given class name.</description>
        <function-name>getEnumValues</function-name>
        <function-class>
            package.ElEnumUtils
        </function-class>
        <function-signature>
            java.lang.Enum[] getEnumValues(java.lang.String)
        </function-signature>
    </function>

    Y, finalmente, la llaman así:

    <p:selectOneMenu value="#{bean.type}">
        <f:selectItems value="#{el:getEnumValues('package.BeanType')}" var="varEnum" 
            itemLabel="#{el:getEnumLabel(varEnum)}" itemValue="#{varEnum}"/>
    </p:selectOneMenu>

    Similar a BalusC respuesta debe ser el uso de un recurso paquete con localizadas enum etiquetas, y para un limpiador de código también puede crear una función como getEnumLabel(enum)

    • No hay necesidad de una «función» (método más), cuando se puede utilizar #{myBundle[enumName.i18nKey]} y, a continuación, poner la i18n claves en su enumeración como propiedades: BLA_TYPE("SOME_BLA_TYPE_KEY") por BLA_TYPE es la enumeración de ser utilizado y SOME_BLA_TYPE_KEY es la i18n clave.

Dejar respuesta

Please enter your comment!
Please enter your name here