[英]How to use PrimeFaces SelectOneMenu ItemLabel & ItemValue with Lists?
[英]SelectOneMenu passes itemLabel instead of itemValue when attribute editable is true
我有以下選擇一個菜單。 我有一個用於“Foo”對象的轉換器。
<p:selectOneMenu id="sender" filter="true" filterMatchMode="contains" required="true" converter="fooConverter" disabled="#{myView.disabled}" value="#{myView.sender}" placeholder="Pick one or create new!" editable="true">
<f:selectItem noSelectionOption="true" itemLabel="Pick one:" itemValue="#{null}" itemDisabled="#{myView.sender ne null}" />
<f:selectItems value="#{dataFromDBean.foos}" var="foo" itemLabel="#{foo.name}" itemValue="#{foo}" />
</p:selectOneMenu>
@FacesConverter(value = "fooConverter")
public class FooConverter 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());
Foo object = null;
try {
UUID guid = UUID.fromString(id);
object = objects.getFoo(guid);
} catch (IllegalArgumentException e) {
e.printStackTrace();
object = new Foo(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 ((Foo) obj).getId().toString();
}
}
在getAsObject
調用的構造函數是:
public Foo(String name) {
super();
this.id = UUID.randomUUID();
this.name = name;
this.passive = false;
}
基本上我的邏輯是selectOneMenu
使用現有對象作為值,用戶可以選擇這些值,並添加新值,它是一個字符串,如果傳遞一個字符串,則不會找到 id,因此傳遞字符串改為 id,然后如果 id 無法解析為 UUID,則它不是 UUID 字符串,因此會創建一個新對象,該對象將在提交表單時由服務器保存。
然而,問題是,當editable="true"
存在時, selectOneMenu
總是將String
傳遞給轉換器,但不僅僅是任何String
,而是itemLabel
值,它是機構的名稱表示。 甚至 noselectoption 也作為 itemLabel 傳遞,而不是#{null}
。 因此,無論用戶輸入新值還是選擇現有值, itemLabel
屬性始終傳遞給轉換器,因此我的轉換器將其視為新值並嘗試創建新機構。 這是JSF
或PrimeFaces
的已知錯誤嗎?
正如 Usagi Miyamoto 所建議的, <p:autoComplete>
是我的問題的一種解決方法。
以下代碼按我原先想要的方式工作(在功能方面):
<p:autoComplete id="sender" value="#{myView.sender}" completeMethod="#{myView.completeFoo}"
var="foo" itemLabel="#{foo.name}" itemValue="#{foo}" converter="fooConverter" dropdown="true" disabled="#{myView.disabled}"/>
使用以下完整方法:
public Collection<Foo> completeFoo(String query) {
Collection<Foo> filteredFoo = new ArrayList<>();
for (Foo foo : foos) {
if (foo.getName().toLowerCase().contains(query.toLowerCase().trim())) {
filteredFoo.add(foo);
}
}
return filteredFoo;
}
它是RichFaces 3.x
,所以是JSF 1.x
,但類似的東西也應該在帶有PrimeFaces
JSF 2.x
工作。
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>
豆.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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.