HTML 5 выпадающий и JSF 2.2

Я пытаюсь отправить <select> значение для управляемого JSF-компонента, но я не знаю, как это сделать. Мой код:

<select id="cb-frentes" required="required" jsf:value="#{checkstyleBean.frente}">
    <option value=""/>
    <ui:repeat var="frente" value="#{appBean.frentes}">
        <option value="#{frente}" label="#{frente}"/>
    </ui:repeat>
</select>

Это не работает. Значение frente атрибут всегда null, когда я призываю мой метод действия.

Как я могу сделать это связывание?

5 ответов

Решение

<option> элемент по умолчанию не распознается как промежуточный элемент. Он не указан в таблице 8.4 главы 8.9 учебника по Java EE "HTML5-дружественная разметка".

Вам нужно явно указать базовый компонент JSF. Вы можете сделать это, используя jsfc атрибута, который на удивление не упоминается в руководстве по Java EE 7 (возможно, потому что он является частью Facelets, технологии представления, а не JSF).

<select id="cb-frentes" required="required" size="1" jsf:value="#{checkstyleBean.frente}">
    <option value="#{null}" jsfc="f:selectItem" />
    <ui:repeat value="#{appBean.frentes}" var="frente" jsfc="f:selectItems">
        <option value="#{frente}">#{frente}</option>
    </ui:repeat>
</select>

Обратите внимание, что я установил значение 1-го варианта, чтобы оно было явно #{null}и что я исправил неправильный способ установки метки опции. Далее я также добавил size="1" к <select>в противном случае он по умолчанию отображается как список вместо раскрывающегося списка.

Похоже, JSF конвертирует select элемент к h:selectOneListbox но это не правильно конвертировать option теги. Вы должны затем использовать h:selectItem или же h:selectItems, как это:

<select id="cb-frentes" required="required"
    jsf:value="#{someBean.frente}" size="0">
    <f:selectItem itemValue="" itemLabel=""/>
    <f:selectItem itemValue="1" itemLabel="1"/>
    <f:selectItem itemValue="2" itemLabel="2"/>
</select>

Мне нужно было добавить атрибут size="0", чтобы отобразить параметры в раскрывающемся меню. Это связано с тем, что JSF преобразует элемент select в h:selectOneListbox, который отображается в виде списка.

В качестве альтернативы, чтобы использовать атрибуты HTML5 для элемента JSF, вам не нужно преобразовывать их в теги HTML5 (сквозные элементы). Вы можете использовать сквозные атрибуты:

<html ... xmlns:p="http://xmlns.jcp.org/jsf/passthrough">
...
<h:selectOneMenu id="cb-frentes" p:required="required"
    value="#{someBean.frente}">
    <f:selectItem itemValue="" itemLabel=""/>
    <f:selectItem itemValue="1" itemLabel="1"/>
    <f:selectItem itemValue="2" itemLabel="2"/>
</h:selectOneMenu>

В случае обоих решений вместо использования f:selectItem Вы также можете использовать f:selectItems так что тебе не нужно ui:repeat,

Это решение сработало для меня:

<select jsf:id="province" size="1" jsf:value="#{shippingAddressBackingBean.shippingAddress.provinceCode}" name="province" class="form-control">
    <option value="#{null}" jsfc="f:selectItem" />
    <div value="#{shippingAddressBackingBean.provinces}" var="prov" jsfc="f:selectItems" itemValue="#{prov.code}" itemLabel="#{prov.name}"></div>
</select>

Я использовал код выше, чтобы решить мою проблему.

<select id="language-select" name="language-select" class="form-control input-lg" jsf:value="#{dashboardBean.language}" size="1">
                                <div value="#{dashboardBean.supportedLanguages}" var="language" jsfc="f:selectItems" itemValue="#{language.code}" itemLabel="#{dashboardBean.translate(language.name, null)}"></div>
                            </select>

SupportedLanguages.java

public enum SupportedLanguage implements TShopType {
    UNKNOWN("un", "common.unknown"), DE("de", "common.supportedlanguage.de"), EN("en", "common.supportedlanguage.en"),
    FR("fr", "common.supportedlanguage.fr"), NL("nl", "common.supportedlanguage.nl"), CS("cs",
            "common.supportedlanguage.cs"), ES("es", "common.supportedlanguage.es"), IT("it",
            "common.supportedlanguage.it");

    private String code;
    private String name;

    private SupportedLanguage(String code, String name) {
        this.code = code;
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public String getName() {
        return name;
    }

    public static final SupportedLanguage getLanguage(String code) {
        code = code.toLowerCase();
        switch (code) {
        case "de":
            return SupportedLanguage.DE;

        case "en":
            return SupportedLanguage.EN;

        case "fr":
            return SupportedLanguage.FR;

        case "nl":
            return SupportedLanguage.NL;

        case "cs":
            return SupportedLanguage.CS;

        case "es":
            return SupportedLanguage.ES;

        case "it":
            return SupportedLanguage.IT;

        default:
            return SupportedLanguage.UNKNOWN;
        }
    }

    public Converter getSupportedLanguageConverter() {
        return new Converter() {

            @Override
            public String getAsString(FacesContext context, UIComponent component, Object value) {
                // TODO Auto-generated method stub
                return (value == null) ? null : ((SupportedLanguage) value).getCode();
            }

            @Override
            public Object getAsObject(FacesContext context, UIComponent component, String value) {
                // TODO Auto-generated method stub
                return (value == null) ? null : SupportedLanguage.getLanguage(value);
            }
        };
    }

Если appBean.frentes - это список POJO, вам нужно использовать конвертер в теге selectOneMenu.

Другие вопросы по тегам