我有以下选择一个菜单。我的“Intezet”(机构)对象有一个转换器。当属性可编辑为true时,SelectOneMenu传递itemLabel而不是itemValue
<p:selectOneMenu id="bekuldo" filter="true" filterMatchMode="contains" required="true" converter="intezetConverter" disabled="#{iratFelvitelView.disabled}" value="#{iratFelvitelView.bekuldo}" placeholder="Válaszd ki vagy add meg!" editable="true">
<f:selectItem noSelectionOption="true" itemLabel="Válassz egyet:" itemValue="#{null}" itemDisabled="#{iratFelvitelView.bekuldo ne null}" />
<f:selectItems value="#{dataFromDBean.intezetek}" var="intezet" itemLabel="#{intezet.name}" itemValue="#{intezet}" />
</p:selectOneMenu>
@FacesConverter(value = "intezetConverter")
public class IntezetConverter implements Converter {
@Override
public Object getAsObject(FacesContext ctx, UIComponent uiComponent, String id) {
ValueExpression vex = ctx.getApplication().getExpressionFactory().createValueExpression(ctx.getELContext(),
"#{dataFromDBean}", DataFromDBean.class);
DataFromDBean objects = (DataFromDBean) vex.getValue(ctx.getELContext());
Intezet object = null;
try {
UUID guid = UUID.fromString(id);
object = objects.getIntezet(guid);
} catch (IllegalArgumentException e) {
e.printStackTrace();
object = new Intezet(id);
}
return object;
}
@Override
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object obj) {
if (obj == null)
return "";
if (obj.getClass().equals(String.class)) {
return (String) obj;
}
return ((Intezet) obj).getId().toString();
}
}
之称的getAsObject
构造是:
public Intezet(String name) {
super();
this.id = UUID.randomUUID();
this.name = name;
this.passziv = false;
}
基本上我的逻辑是selectOneMenu
使用现有对象作为值,用户可以选择,也可以增加新的价值,这是一个字符串,如果传递一个字符串,比没有id将被找到,所以该字符串作为id传递,而如果一个id不能被解析成一个UUID,那么它不是一个UUID字符串,所以创建了一个新的对象,服务器在提交表单时将保存该对象。
然而,问题是,当editable="true"
存在时,selectOneMenu
总是通过一个String
到转换器,但不是任何String
,但itemLabel
值,这是机构的名称表示。即使是noselectoption也是因为它是itemLabel而且从不#{null}
。 因此,无论用户输入新值还是选择现有值,itemLabel
属性都将传递给转换器,因此我的转换器将其视为新值并尝试创建新的机构。这是JSF
或PrimeFaces
中的已知错误吗?
至于建议的兔子宫本,<p:autoComplete>
是一个解决方法,我的问题。
下面的代码工作,因为我本来想它(在功能方面):
<p:autoComplete id="bekuldo" value="#{iratFelvitelView.bekuldo}" completeMethod="#{iratFelvitelView.completeIntezet}"
var="intezet" itemLabel="#{intezet.name}" itemValue="#{intezet}" converter="intezetConverter" dropdown="true" disabled="#{iratFelvitelView.disabled}"/>
用下面的完整方法:
public Collection<Intezet> completeIntezet(String query) {
Collection<Intezet> filteredIntezet = new ArrayList<>();
for (Intezet intezet : intezetek) {
if (intezet.getName().toLowerCase().contains(query.toLowerCase().trim())) {
filteredIntezet.add(intezet);
}
}
return filteredIntezet;
}
不要使用'HTML' /'JavaScript' /'CSS'片段显示'Java' /'XHTML'来源,那些不会运行... –
应该使用'
'而不是... –
@UsagiMiyamoto它不会在没有bean和服务器的情况下运行,但是我应该使用什么呢?我是新来的stackoverflow –