HTML 5 个下拉菜单和 JSF 2.2
HTML 5 dropdown and JSF 2.2
我正在尝试将 <select>
值发送到 JSF 托管 bean,但我不知道如何发送。
我的代码是:
<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
。
我该如何绑定?
看起来 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。
或者,要在 JSF 元素上使用 HTML5 属性,您不需要将它们转换为 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
.
<option>
元素默认不被识别为 直通元素 。 table 8.4 of Java EE tutorial chapter 8.9 'HTML5-Friendly Markup'.
中未列出
您需要明确告知底层 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>
请注意,我将第一个选项的值固定为明确 #{null}
,并且我修正了设置选项标签的错误方式。此外,我还将 size="1"
添加到 <select>
,否则它默认呈现为列表框而不是下拉列表。
如果 appBean.frentes 是 POJO 的列表,您需要在 selectOneMenu 标签中使用转换器。
这个解决方案对我有用:
<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);
}
};
}
我正在尝试将 <select>
值发送到 JSF 托管 bean,但我不知道如何发送。
我的代码是:
<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
。
我该如何绑定?
看起来 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。
或者,要在 JSF 元素上使用 HTML5 属性,您不需要将它们转换为 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
.
<option>
元素默认不被识别为 直通元素 。 table 8.4 of Java EE tutorial chapter 8.9 'HTML5-Friendly Markup'.
您需要明确告知底层 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>
请注意,我将第一个选项的值固定为明确 #{null}
,并且我修正了设置选项标签的错误方式。此外,我还将 size="1"
添加到 <select>
,否则它默认呈现为列表框而不是下拉列表。
如果 appBean.frentes 是 POJO 的列表,您需要在 selectOneMenu 标签中使用转换器。
这个解决方案对我有用:
<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);
}
};
}