Comment utiliser les valeurs enum dans f: selectItem(s)

je veux faire un dropdown selectOneMenu de sorte que je puisse choisir un État sur ma question. Est-il possible de rendre le f:selectItem plus flexible compte tenu de ce qui se passe si l'ordre des énums change, et si la liste était grande? Et pourrais-je faire mieux? Et est-il possible de automatiquement "sélectionner" l'élément de la question?

classe Enum

public enum Status {
    SUBMITTED,
    REJECTED,
    APPROVED
}

Question morale

@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>
90
demandé sur Karl Richter 2011-11-22 19:52:03

4 réponses

JSF a un convertisseur intégré pour enum , donc cela devrait faire:

@ManagedBean
@ApplicationScoped
public class Data {

    public Status[] getStatuses() {
        return Status.values();
    }

}

avec

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

(note: depuis JSF 2.0 Il n'y a plus besoin de fournir un SelectItem[] ou List<SelectItem> , un T[] et List<T> sont acceptés aussi et vous pouvez accéder à l'article courant par var attribut)

Si vous arrive d'utiliser JSF utility library OmniFaces , alors vous pouvez utiliser <o:importConstants> au lieu d'un haricot.

<o:importConstants type="com.example.Status" />

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

si vous avez aussi l'intention de contrôler les étiquettes, vous pouvez les ajouter au 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;
    }

}

avec

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

Ou, mieux, faire l'énumération de la valeur d'une propriété clé d'une ressource localisée bundle (EL 3.0):

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

avec ceci dans un fichier de propriétés associé à l'ensemble de ressources #{text}

data.status.SUBMITTED = Submitted
data.status.REJECTED = Rejected
data.status.APPROVED = Approved
184
répondu BalusC 2016-03-05 10:14:26

pour la localisation nous pouvons utiliser aussi cette solution:

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>

ainsi le chemin de ressource pour les chaînes de localisation ne sont pas codé en dur dans Enum.

16
répondu Ziletka 2012-04-05 20:27:14

vous pouvez utiliser <f:selectItems value="#{carBean.carList}" /> et retourner une liste des instances SelectItem qui enveloppent l'enum (utilisez Status.values() pour obtenir toutes les valeurs possibles).

4
répondu Thomas 2011-11-22 16:04:05

vous pouvez utiliser la fonction utilitaire el suivante pour obtenir les valeurs enum et les utiliser dans un SelectOneMenu par exemple. Pas besoin de créer des haricots et des méthodes standard.

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;
    }
}

enregistrer comme une fonction el dans un fichier taglib:

<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>

et finalement l'appeler comme:

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

Semblable à BalusC réponse, vous devriez être en utilisant un regroupement de ressources locales enum étiquettes et pour nettoyeur code vous pouvez également créer une fonction comme getEnumLabel(enum)

2
répondu djmj 2016-02-13 21:36:13