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

时间:2013-12-16 18:55:47

标签: java jsf primefaces picklist

当用户选择了选项列表目标列表中的项目时,我想重新渲染组件。

我该怎么做?


更新(2013年12月17日)

我在这里描述了这个问题的完整解决方案 - http://leonotepad.blogspot.com.br/2013/12/primefaces-capturing-target-list-item.html

谢谢@Hatem如果没有你的回答,我无法解决这个问题。

基本上就是这样:

我有一个@ViewScoped托管bean,其p:pickList使用p:ajax更新事件由p:selectMany组件过滤。

喜欢这个

<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}" /> 

这里的想法是当用户点击某个pickList目标列表项时触发一个新事件。

因此,正如@Hatem所建议的那样,我们必须将click事件绑定到每个目标元素。喜欢这个

(...)
   <p:remoteCommand name="updateCommand" action="#{myMB.updateAccounts}" update="accounts"/>
</h:form>
<h:outputScript library="js" name="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();
});

这里的诀窍似乎是,在更新事件之后,绑定会丢失,因此我们必须在更新后重新绑定它们。这就是p:ajax有完成事件的原因。

最后,当用户点击目标列表中的元素时,我们调用updateCommand,通过p:remoteCommand声明。

请注意,所选项目作为名为“param”的参数传递。我们将此参数返回到托管bean中,如此

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

在这种情况下,值只是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;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

这种方式应该这样做。

remoteCommand

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

号码:选取列表

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

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

修改

如果你的pickList被另一个组件定期更新,那么你毕竟会丢失点击事件。

在这种情况下,您可能希望绑定pickList的父容器组件上的单击。

例如:

 $('#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');
   });

但是,如果任何其他组件更新了整个表单,您将失去事件绑定..