2017-08-11 22 views
0

次の選択メニューがあります。私は "Intezet"(Institution)オブジェクト用のコンバータを持っています。属性編集可能がtrueの場合、SelectOneMenuはitemValueの代わりにitemLabelを渡します

<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に呼び出されるコンストラクタされています。基本的に私のロジックはselectOneMenuは、ユーザが選択可能な値として、既存のオブジェクトを使用し、また、新しい値を追加することである

public Intezet(String name) { 
     super(); 
     this.id = UUID.randomUUID(); 
     this.name = name; 
     this.passziv = false; 
    } 

これはStringであり、Stringが渡された場合、idが見つからないため、文字列はidとして渡されます。次に、idをUUIDに解析できない場合は、UUID文字列ではありません、新しいオブジェクトが作成され、フォームの送信時にサーバーによって保存されます。

しかし、問題はeditable="true"が存在する場合、selectOneMenuは常にコンバータにStringを渡し、それだけではない任意のStringが、機関の名称で表現したものですitemLabel値、ということ、です。 noselectoptionもitemLabelとして渡され、決して#{null}となります。 したがって、ユーザーが新しい値を入力するか、既存の値を選択しても、常にitemLabel属性がコンバーターに渡されるため、マイナーコンバータは新しい値として認識し、新しい機関を作成しようとします。これはJSFまたはPrimeFacesの既知のバグですか?うさぎ宮本、<p:autoComplete>によって示唆されるように


は私の問題に対する回避策です。

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

として、 'Java' /' XHTML'ソースを表示するには、 'HTML' /' JavaScript'/'CSS'スニペットを使用しないでください。それらは実行されません... –

+0

代わりに ''を使用する必要があります... –

+0

@UsagiMiyamotoそれは豆とサーバーのいずれかがなくても実行されませんが、代わりに何を使うべきですか?私はstackoverflowを新しくしました –

答えて

0

それは、とてもJSF 1.xRichFaces 3.xですが、似たような次の完全な方法で

<p:autoComplete id="bekuldo" value="#{iratFelvitelView.bekuldo}" completeMethod="#{iratFelvitelView.completeIntezet}" 
        var="intezet" itemLabel="#{intezet.name}" itemValue="#{intezet}" converter="intezetConverter" dropdown="true" disabled="#{iratFelvitelView.disabled}"/> 

:私はもともと(機能性の面で)それを望んでいたよう

次のコードは動作します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; 
    } 
} 
関連する問題