考虑到以下代码,它显示了一个带有一列的表和一个用于显示活动/非活动记录的过滤器。如何根据过滤器中选择的值禁用菜单项"非活动"?换句话说,如果筛选器值为"inactive",则应禁用"Inactivate"菜单。
<p:contextMenu for="ratingScaleTable" id="RsContextMenuId">
<p:menuitem value="Edit" update=":templateForm:tabView, :templateForm:dirtyFlag" icon="ui-icon-search" action="#{ratingScaleBK.edit}" />
<p:menuitem id="inactivate" value="Inactivate" icon="ui-icon-close" action="#{ratingScaleBK.inactivate}" disabled="#{ratingScaleBK.selectedRatingScale.active==0}" />
<p:menuitem value="Activate" update=":templateForm:tabView" icon="ui-icon-close" action="#{ratingScaleBK.activate}"/>
<p:menuitem value="View Archive" update=":templateForm:tabView" icon="ui-icon-close"/>
</p:contextMenu>
<p:dataTable id="ratingScaleTable" widgetVar="tableWidget"
value="#{ratingScaleBK.ratingScaleList}" var="item1"
selectionMode="single"
selection="#{ratingScaleBK.selectedRatingScale}"
rowKey="#{item1.name}"
rendered="#{not empty ratingScaleBK.ratingScaleList}"
filteredValue="#{ratingScaleBK.filteredRatingscale}">
<p:ajax event="rowSelect" process="ratingScaleTable" listener="#{ratingScaleBK.edit}" update=":templateForm:tabView, :templateForm:dirtyFlag, :templateForm:tabView:RsContextMenuId " />
<p:column id="activeCol" filterBy="#{item1.active}"
filterOptions="#{ratingScaleBK.activeOptions}"
filterMatchMode="exact" width="30">
<h:outputText value="#{item1.active}" />
</p:column>
</p:dataTable>
现在此代码不起作用,上下文菜单从未在rowSelect上更新(菜单项"非活动"始终处于启用状态)。我想,在特定行上单击鼠标右键以显示菜单并不会真正触发rowSelect事件,即使该行被高亮显示也是如此。正确的方法是什么?
我最终使用了PF论坛上的这个解决方案:
<p:contextMenu for="ratingScaleTable" id="RsContextMenuId" widgetVar="ctxMenu" beforeShow="return true;">
<p:dataTable id="ratingScaleTable" widgetVar="tableWidget"
...
<p:ajax event="rowSelect" process="ratingScaleTable" listener="#{ratingScaleBK.edit}" update=":templateForm:tabView, :templateForm:dirtyFlag, :templateForm:tabView:RsContextMenuId" />
<p:ajax event="contextMenu" update=":templateForm:tabView:RsContextMenuId" oncomplete="ctxMenu.show(currentEvent);"/>
以及相关的JavaScript:
<script type="text/javascript">
var currentEvent;
$(document).ready(function() {
PrimeFaces.widget.ContextMenu.prototype.show = function(e) {
//hide other contextmenus if any
$(document.body).children('.ui-contextmenu:visible').hide();
if(e) {
currentEvent = e;
}
var win = $(window),
left = e.pageX,
top = e.pageY,
width = this.jq.outerWidth(),
height = this.jq.outerHeight();
//collision detection for window boundaries
if((left + width) > (win.width())+ win.scrollLeft()) {
left = left - width;
}
if((top + height ) > (win.height() + win.scrollTop())) {
top = top - height;
}
if(this.cfg.beforeShow) {
this.cfg.beforeShow.call(this);
}
this.jq.css({
'left': left,
'top': top,
'z-index': ++PrimeFaces.zindex
}).show();
e.preventDefault();
};
});
</script>
使用contextMenu事件进行尝试:
<p:contextMenu for="ratingScaleTable" id="RsContextMenuId" widgetVar="ctxMenu">
...
</p:contextMenu>
<p:dataTable ... >
...
<p:ajax event="contextMenu" process="ratingScaleTable" listener="#{ratingScaleBK.edit}" update=":templateForm:tabView, :templateForm:dirtyFlag, :templateForm:tabView:RsContextMenuId" oncomplete="PF('ctxMenu').show();" />
...
</p:dataTable>