2017-08-11 76 views
0

我有以下选择一个菜单。我的“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属性都将传递给转换器,因此我的转换器将其视为新值并尝试创建新的机构。这是JSFPrimeFaces中的已知错误吗?


至于建议的兔子宫本,<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; 
} 
+0

不要使用'HTML' /'JavaScript' /'CSS'片段显示'Java' /'XHTML'来源,那些不会运行... –

+0

应该使用''而不是... –

+0

@UsagiMiyamoto它不会在没有bean和服务器的情况下运行,但是我应该使用什么呢?我是新来的stackoverflow –

回答

0

这是RichFaces 3.x,所以JSF 1.x,但类似的东西应该在JSF 2.xPrimeFaces中工作。

XHTML:

<a4j:region> 
    <h:inputText id="person" value="#{bean.item.id}"> 
    <a4j:support event="onblur" action="#{bean.listener}" reRender="partner" /> 
    </h:inputText> 
    <rich:suggestionbox id="partnerSuggest" for="partner" var="part" fetchValue="#{part.id}" 
         suggestionAction="#{bean.suggest}" reRender="partner"> 
    <rich:column><h:outputText value="#{part.id}"/></rich:column> 
    <rich:column><h:outputText value="#{part.name}"/></rich:column> 
    <a4j:support event="onselect" action="#{bean.listener}" reRender="partner" /> 
    </rich:suggestionBox> 
</a4j:region> 

Bean.java:

public class Bean 
{ 
    // Currently selected/edited Person 
    private Person item = new Person(); 

    // Getters and Setters omitted... 

    // This method is invoked to present a list fro the <rich:suggestionbox> component. 
    // It receives the typed in text as parameter. 
    public List<Partner> suggest(Object value) 
    { 
    // Returns a list of partner filtered by the given value. 
    // In my case it could be a name or an ID... 
    } 

    // This method (an action) is called when the input field is lost focus (onblur event) or 
    // a selection is made from the suggestion list. 
    // It checks wheter the input field contains a valid ID, and sets the bean to the correct 
    // partner it loaded. 
    public String listener() 
    { 
    String value = this.item.getId(); 
    final Partner who = Partner.find(value); // To retrieve the partner 
    if (null != who) 
    { 
     this.item = who; 
    } 
    return null; 
    } 
} 
相关问题