Building a client side transfer method for p:pickList

我只是一个虾纸丫 提交于 2019-12-12 06:25:07

问题


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;
    }

}

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.

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.

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?


回答1:


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

PrimeFaces.widget.PickList

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
            }
        });
    }

EDIT: 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)}" />

EDIT 2:

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");

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

Hope this helps.



来源:https://stackoverflow.com/questions/22559619/building-a-client-side-transfer-method-for-ppicklist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!