本文介绍了为p:pickList构建客户端传输方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Mojarra JSF 2.1.28和Primefaces 3.5.我想为 p:pickList 组件实现客户端传输输入,用户在其中键入内容,然后在可用元素列表中的标签中搜索值,然后将其转移到目标列表.这就是我的代码的样子:

I'm working with Mojarra JSF 2.1.28 and Primefaces 3.5. I want to implement a client-side transferring input for the p:pickList component, where the user types something and the value is searched through the labels at the list of available elements, then it's transferred to the target list. That's how my code looks like:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
    <script>
        //Just for testing, transfer the second element
        //to the target list when document is ready. Works well
        $(document).ready(function(string) {
            transfer("name2");
        });
        //Transfer function. It takes each list item from the source list and checks if it matches with the given pattern
        //If it does, moves it to the target list
        function transfer(string) {
            $(".ui-picklist-source li").each(function() {
                var re = new RegExp(string);
                if ($(this).attr('data-item-label').match(re)) {
                    $(".ui-picklist-target").append($(this));
                }
            });
        };
    </script>
    <h:form>
        <p:inputText
            onkeypress="if (event.keyCode == 13) { transfer(this.value); return false;}" />
    </h:form>
    <h:form id="form">
        <p:pickList value="#{bean.elements}" var="element"
            itemLabel="#{element.name}" itemValue="#{element.name}" id="picklist" />
        <p:commandButton value="Send" action="#{bean.send}" />
    </h:form>
</h:body>
</html>
@ManagedBean
@ViewScoped
public class Bean implements Serializable{

    public class Element {

        private String name;

        public Element(String n) {
            name = n;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return "Element [name=" + name + "]";
        }

    }

    private DualListModel<Element> elements;

    public Bean() {
        List<Element> source = new ArrayList<Bean.Element>();
        List<Element> target = new ArrayList<Bean.Element>();
        source.add(new Element("name1"));
        source.add(new Element("name2"));
        elements = new DualListModel<Bean.Element>(source, target);
    }

    public DualListModel<Element> getElements() {
        return elements;
    }

    public void send() {
        System.out.println("Available: " + elements.getSource() + " assigned: "
                + elements.getTarget());
    }

    public void setElements(DualListModel<Element> elements) {
        this.elements = elements;
    }

}

好吧,在这个测试用例中,有两个项目要玩,name1name2.页面加载时,我使用 $(document).ready() 调用我的transfer(string)函数以移动到目标列表.页面已正确加载,如果单击Send按钮,则会正确分配第二个元素.

Well, in this test case, there are two items to play with, name1 and name2. When page loads, I use $(document).ready() to call my transfer(string) function in order to move name2 to the target list. Page gets properly loaded and if we click on Send button, we get the second element properly assigned.

问题.在这里,我们侦听Enter键事件以发送当前给定值并执行传输.在客户端,它的工作原理很合理,表现出预期的效果.但是,单击Send时,无法在服务器端正确更新模型.

Problem comes when calling the function using the p:inputText component. Here, we listen to the Enter key event to send the current given value and perform a transfer. At client side it works fair enough, it behaves as expected. However, when clicking on Send, model doesn't get properly updated at server side.

我推断这是由JSF保留的视图状态引起的,但是如何处理呢?有没有办法实现它,还是我必须遵守Ajax请求?

I infer this is caused by the view state kept by JSF, but how to deal with this? Is there a way to implement it or do I have to stick to Ajax requests?

推荐答案

实现此目标的正确"方法是使用Primefaces的Javascript API

The "right" way to achieve this is to use Primefaces's Javascript API of

PrimeFaces.widget.PickList

假设您的widgetVarpickListWV,这是您要执行的操作:

Assuming your widgetVar is pickListWV, here's how you would do:

function transfer(string) {
        PF('pickListWV').sourceList.children().each(function() {
            var re = new RegExp(string, "i");
            if ($(this).attr('data-item-label').match(re)) {
                PF('pickListWV').selectItem($(this));// select the item
                PF('pickListWV').add();// add it to the target
            }
        });
    }

另外,您还可以使其变得更有趣,例如实时过滤.

Also you can make it more interesting, like live filtering..

 <p:inputText
        onkeypress="if (event.keyCode == 13) { transfer(this.value); return false;} else{PF('pickListWV').filter(this.value, PF('pickListWV').sourceList)}" />

如我所见,您具有区分大小写的匹配项,因此必须将RegExp声明为不区分大小写

As I can see that you have a case-sensitive match, so you have to declare your RegExp as case-insensitive

var re = new RegExp(string, "i");

这是 github ,以及按要求运行的演示:)

Here's a small working example on github, and a working demo as requested :)

希望这会有所帮助.

这篇关于为p:pickList构建客户端传输方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 20:00