简体   繁体   English

Primefaces p:picklist-如何捕获在目标列表中选择项目的事件?

[英]Primefaces p:picklist - how I capture the event of selecting an item in the target list?

I'd like to re-render a component when a item from the picklist target list is selected by the user. 当用户从选择列表目标列表中选择一项时,我想重新渲染组件。

How do I do that? 我怎么做?


UPDATE (December 17th, 2013) 更新(2013年12月17日)

I've described the full solution for this problem here - http://leonotepad.blogspot.com.br/2013/12/primefaces-capturing-target-list-item.html 我已经在此处描述了此问题的完整解决方案-http://leonotepad.blogspot.com.br/2013/12/primefaces-capturing-target-list-item.html

Thanks @Hatem I could not solve this without your answer. 谢谢@Hatem,如果没有您的回答,我将无法解决。

Basically, it was this: 基本上是这样的:

I have a @ViewScoped managed bean with ap:pickList filtered by ap:selectMany component using ap:ajax update event. 我有一个@ViewScoped托管bean,其中使用ap:ajax更新事件通过ap:selectMany组件过滤了ap:pickList。

Like this 像这样

<p:outputLabel for="siteFilter" value="Site Filter:" style="width:100px;"/>
<p:selectOneMenu converter="#{siteTypeConverter}" id="siteFilter" value="#{myMB.selectedSiteType}" style="width:200px;">              
   <f:selectItem itemLabel="Select Site Type" itemValue="#{null}" />
   <f:selectItems value="#{myMB.siteTypeFilterList}" var="st" itemLabel="#{st.name}" itemValue="#{st}" />
   <p:ajax update="sites" listener="#{myMB.handleSiteTypeFilterChange}" oncomplete="rebindClicks()"/>
</p:selectOneMenu>

<p:outputLabel for="sites" value="Sites:" style="width:100px;"/>
<p:pickList
   widgetVar="xyzabc"
   id="sites"
   value="#{myMB.sites}"
   var="site"                 
   converter="#{siteConverter}"
   itemLabel="#{site.siteType.name}.#{site.name}"
   itemValue="#{site}" /> 

The idea here is to trigger a new event when the user clicks on some pickList target list item. 这里的想法是当用户单击某些pickList目标列表项时触发一个新事件。

So, as suggested by @Hatem, we have to bind the click event to each one of the target elements. 因此,正如@Hatem所建议的,我们必须将click事件绑定到每个目标元素。 Like this 像这样

(...)
   <p:remoteCommand name="updateCommand" action="#{myMB.updateAccounts}" update="accounts"/>
</h:form>
<h:outputScript library="js" name="pickListHack.js" />   
(...)

Notice that I had to add it AFTER the form. 注意,我必须在表单之后添加它。

and pickListHack.js is located at WebContent/resources/js/pickListHack.js 并且pickListHack.js位于WebContent / resources / js / pickListHack.js

function rebindClicks() {
    xyzabc.jq.on('click','.ui-picklist-target li',function(){
        var item = $(this).attr('data-item-value');
        alert(item);
        updateCommand([{name:'param', value:item}]);
   });
};

$(document).ready(function() {
    rebindClicks();
});

The trick here seems to be that, after the update event, the binds are lost, so we have to rebind them after the update. 这里的技巧似乎是,在更新事件之后,绑定会丢失,因此我们必须在更新后重新绑定它们。 That's why p:ajax has that oncomplete event. 这就是为什么p:ajax具有该oncomplete事件。

Finally, when the user clicks on the element from the target list, we call the updateCommand, declared via p:remoteCommand. 最后,当用户单击目标列表中的元素时,我们调用通过p:remoteCommand声明的updateCommand。

Notice that the selected item is passed as a parameter called "param". 请注意,所选项目作为名为“ param”的参数传递。 We get this parameter back in the managed bean like this 我们像这样在托管bean中获取此参数

public void updateAccounts(){
   String value = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("param");
   System.out.println(">"+value);
   this.accounts = value;
}

In this case, the value is just the ID, because that's what my siteConverter does to the object. 在这种情况下,值只是ID,因为那是我的siteConverter对对象执行的操作。

@ManagedBean
@RequestScoped
public class SiteConverter implements Converter,Serializable{
    private static final long serialVersionUID = -194442504109002565L;

    @EJB
    private MyEJB myEJB;

    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2)
            throws ConverterException {

        if (arg2 != null){
            Site s = myEJB.getSiteById(Long.parseLong(arg2));
            return s;
        }else{
            return null;
        }
    }

    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2)
            throws ConverterException {

        if (arg2 != null){
            Site s = (Site)arg2;
            return String.valueOf(s.getId());
        }else{
            return null;
        }
    }
}

This way should do it. 这种方式应该做到这一点。

remoteCommand remoteCommand

<p:remoteCommand name="updateCommand" update="componentId" />  

p:pickList 电话号码:PICKLIST

<p:pickList id="pickList" widgetVar="pickListVar" value="#{pickListBean.cities}" 
 var="city" itemLabel="#{city}" itemValue="#{city}" />

JS JS

$(document).ready(function() {
   PF('pickListVar').jq.on('click','.ui-picklist-target li',function(){
       updateCommand();//remoteCommand to update
       //and you can get the item value and lable
       $(this).attr('data-item-value');
       $(this).attr('data-item-lable');
   });
});

EDIT: 编辑:

And if your pickList is updated regularly by another component, you would lose the click event after all. 而且,如果您的pickList由另一个组件定期更新,那么您最终会丢失click事件。

In this case you might want to bind the click on the parent container component of the pickList. 在这种情况下,您可能希望绑定对pickList的父容器组件的单击。

For example: 例如:

 $('#formId').on('click','.ui-picklist-target li',function(){
       updateCommand();//remoteCommand to update
       //and you can get the item value and lable
       $(this).attr('data-item-value');
       $(this).attr('data-item-lable');
   });

But again if any other component has updated the whole form, you would lose the event binding.. 但是,如果任何其他组件更新了整个表单,则同样会丢失事件绑定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM