通过单击外部隐藏面板时,强制选择突出显示的p:autoComplete项目

时间:2015-04-06 16:01:53

标签: javascript jsf primefaces autocomplete

我的自动完成问题(错误?)。

使用PrimeFaces 5.1的MyFaces 2.2.9

以下仅为重现我的错误的示例。我的模态对话框中有一个自动完成框。

  1. 案例1:我在自动填充中从列表中选择“hello” 并提交。转换器获取我的人ID并搜索合适的人, 一切正常。
  2. 案例2(错误1):我输入“h”并在我的模态区域中单击h 停留并列出关闭。 (当我提交表格时,我只会消失,不会 转换器调用)但我认为h应该因为力而消失 选择?
  3. 案例3(错误2):另一个错误更难。当我输入“你好” (在列表中)在我的框中,然后单击我的模态对话框区域, 你好留下来!当我提交表格时,我在转换器中得到“你好” 并返回“null”,因为他只搜索ids。
  4. 案例3的更多内容:我尝试用更多详细信息解释它(请参阅评论): 我在自动填充框中输入了一些字符串,在我的框中。 enter image description here

    比我点击我的模态区域。 (不!直接在可选择的你好)。比你好,似乎也接受了。

    enter image description here

    现在我点击我的测试按钮,在我的转换器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;
        }
    }
    

1 个答案:

答案 0 :(得分:3)

这不一定是PrimeFaces中的错误,但在使用forceSelection="true"的情况下可能会出现疏忽。您在某种程度上期望与输入中按 Tab 键时的行为相同。

你最好向PF人员报告issue。同时,假设PrimeFaces 5.1:

,您可以自己解决这个问题
  1. raw source code原始autocomplete.jsline 170副本作为/resources/primefaces/autocomplete/autocomplete.js添加到您的网络应用中。

  2. 前往{{3}}。这是处理自动完成面板的隐藏事件的位置。

  3. 在第181行,在第二个和第三个if块之间插入以下代码:

    if ($this.cfg.forceSelection) {
        $this.items.filter('.ui-state-highlight').click();
    }
    

    这将强制在使用forceSelection="true"时自动选择突出显示的项目。

  4. 将自定义的autocomplete.js加载到<h:body>(不是<h:head>!)的顶部,如下所示:

    <h:outputScript library="primefaces" name="autocomplete/autocomplete.js" target="head" />
    
  5. 这确实有点麻烦,但由于这些功能是私人的,因此无法轻易从外部覆盖。另外附加另一个侦听器也不会起作用,因为它在任何先前的侦听器上显式执行$.off()