问题描述
我正在使用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;
}
}
好吧,在这个测试用例中,有两个项目要玩,name1
和name2
.页面加载时,我使用 $(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
假设您的widgetVar
是pickListWV
,这是您要执行的操作:
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");
Here's a small working example on github, and a working demo as requested :)
希望这会有所帮助.
这篇关于为p:pickList构建客户端传输方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!