【发布时间】:2015-06-11 01:26:15
【问题描述】:
我的自动完成有问题(错误?)。
MyFaces 2.2.9 和 PrimeFaces 5.1
以下只是重现我的错误的示例。我的模态对话框中有一个自动完成框。
- 案例 1:我输入了一些内容,从自动完成列表中选择“你好” 并提交。转换器获取我的个人 ID 并搜索合适的人, 一切正常。
- 案例 2(错误 1):我输入“h”并在我的模态区域中单击 h 停留并列出关闭。 (当我提交表单时,h 只会消失,没有 转换器调用)但我认为 h 应该消失,因为力 选择?
- 案例 3(错误 2):另一个错误更难。当我输入“你好” (在列表中)在我的框中,然后单击我的模态对话框区域, 你好留下!当我提交表单时,我的转换器中会出现“你好” 并返回“null”,因为他只搜索 id。
更多案例 3:我尝试用更多细节来解释它(参见 cmets): 我在我的自动完成框中输入了一些东西,带有一个字符串,就在我的框中。
比我点击我的模态区域。 (NOT!直接就choosable hello)。比你好似乎也可以接受。
现在我点击我的测试按钮,在我的转换器中public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) { 是 arg2 而不是来自 hello 的 ID,它是字符串“hello”。只有字符串。
我的预期行为应该是我的身份。只有当我使用正常选择时才会出现 id。
希望你能帮助我。 谢谢你的时间:)
问题:这是一个错误还是我的误解?
XHTML:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>test</title>
</h:head>
<h:body>
<h:form onkeypress="return event.keyCode != 13">
<p:commandButton value="show Dialog"
oncomplete="PF('dgl').show()"
update=":dglform"/>
</h:form>
<p:dialog widgetVar="dgl" modal="true" resizable="false">
<h:form id="dglform" onkeypress="return event.keyCode != 13">
<p:autoComplete id="auto"
forceSelection="true"
converter="personConverter"
value="#{myController.selectedPerson}"
var="per"
itemLabel="#{per.name}"
itemValue="#{per}"
completeMethod="#{myController.search}">
</p:autoComplete>
<p:commandButton value="test" update="@form" />
</h:form>
</p:dialog>
</h:body>
</html>
转换器:
@FacesConverter("personConverter")
public class PersonConverter implements Converter{
@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
System.out.println(arg2);
//Search my entity with id...
return null;
}
@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
if(arg2 instanceof Person){
Person p = (Person) arg2;
return String.valueOf(p.getId());
}
return null;
}
}
控制器:
@ManagedBean
@ViewScoped
public final class MyController implements Serializable {
private static final long serialVersionUID = 1L;
private Person selectedPerson;
private List<Person> persons;
@PostConstruct
public void init() {
persons = new ArrayList<Person>();
persons.add(new Person(1, "hello"));
persons.add(new Person(2, "hello2"));
}
public void selectListener(SelectEvent event){
System.out.println("SELECT!");
}
public Person getSelectedPerson() {
return selectedPerson;
}
public void setSelectedPerson(Person selectedPerson) {
this.selectedPerson = selectedPerson;
}
public List<Person> search(String qry) {
return persons;
}
}
【问题讨论】:
-
我没有看到任何可能被称为“unexpected”或“bug”的东西。您列出的所有这三种情况都可以正常工作。现在的问题是什么? 1) “我输入一些东西,从自动完成列表中选择“你好”并提交。转换器获取我的人员 ID 并搜索合适的人员,一切正常。” - 没什么好说的。 2)“但我认为 h 应该因为强制选择而消失?” - 是。 3)“当我提交表单时,我在转换器中得到“hello”并返回“null”,因为他只搜索 id。” - 这与自动完成无关全部。待续。
-
这完全取决于您如何使用标量值(字符串到对象的转换)在
getAsObject()中构造Person的实例,并由getAsString()(对象到字符串的转换)返回转身,当你显示。 -
我认为存在误解 ;) ...案例 2 和 3 的工作方式与预期不同。案例 2:当我点击我的模态区域时,h 不会消失,当我点击它工作的表单时,它会保持不变。案例 3:当键入自动完成框中的单词并单击模态区域时,该单词将保留并在我的转换器中提供与 case1 不同的字符串。当我直接在我的盒子里选择东西时。
-
我确实得到了所描述的行为。对于#2,您应该添加
required="true" requiredMessage="Please select existing person"左右以使其更直观。对于#3,我不确定您的意图是什么,因为您明确表示您的转换器返回 null,但不清楚它是否只是为了演示或您的实际问题而省略“不相关”代码的一部分(但是你为什么在问题中明确说明这一点?) -
知道了。我重现了你的问题。这确实是与
<p:autoComplete>关联的JavaScript 中的一个错误。我还没有检查它的 JS,但我的印象是实际值仅在单击事件期间设置,而不是在模糊事件期间设置,因此修复将相当简单:在模糊事件上也附加相同的侦听器,或者至少到菜单的隐藏事件,如果有的话。
标签: javascript jsf primefaces autocomplete