对单击的MenuButton做出反应

时间:2015-03-31 18:45:53

标签: jsf primefaces

我们有定期刷新文档的代码。我们还有JSF页面的一部分,menuButtons(primefaces),最初是作为列中dataTable单元格的一部分。我们想要在单击menuButton时(菜单被展开)禁用刷新,并在menuButton关闭时重新启用它(以防止从关闭菜单刷新页面)。

我试图使用java脚本捕获menuButton事件,但无济于事。部分问题是我不知道如何从javascript中唯一地识别JSF组件,因为ID在尝试捕获事件时似乎不起作用。还没有任何令人满意的事件属性(作为Primefaces menuButton的一部分),我可以连接到javascript。

下面是我可以提取的最小代码。为简单起见,我已经将菜单提取为自己(不是dataTable的一部分),因为问题仍然存在。我可能会在那里引用bean和字典文件,但你应该明白这个想法:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition 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"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                xmlns:ui="http://java.sun.com/jsf/facelets">

   <h:form id="virtualMachineTableForm">

      <!-- Lazy load table -->
      <p:remoteCommand name="lazyload" 
                       update=":vmGroupTabs:virtualMachineTableForm:testMenu" 
                       actionListener="#{backupGroupController.refreshHard()}" />

      <!-- Refresh hard button -->
      <p:commandButton id="refreshButton" 
                       update=":vmGroupTabs:virtualMachineTableForm:testMenu" 
                       icon="ui-icon-refresh" 
                       immediate="true" 
                       title="#{msg.action_refresh}" 
                       actionListener="#{backupGroupController.refreshHard()}"/>

      <p:menuButton
         id="testMenu"
         value="#{msg.menuButton_SelectItem}">
         <p:menuitem
            value="Toggle refresh"
            onclick="toggleRefreshState()">
         </p:menuitem>
      </p:menuButton>

      <!-- Poller -->
      <p:poll interval="5" listener="#{backupGroupController.refreshSoft()}" 
              update=":vmGroupTabs:virtualMachineTableForm:testMenu" widgetVar="poll" />
   </h:form>

   <script type="text/javascript">

      var toggleRefreshState = function(){
         if (poll.isActive()) {
            poll.stop();
            alert("Poller stopped" );
         }
         else {
            poll.start();
            alert("Poller started" );
         }
      };

      $(document).ready(function(){
         poll.start();
         setTimeout("lazyload();", 100);
      });
//
//      $("???SomeWayToIdentifyMenu???").on({
//            onMenuOpen???: function(){
//               alert("Opening menu - stopping refresh");
//            }
//            onMenuClose???: function(){
//               alert("Closing menu - starting refresh");
//            }
//      });
</script>

</ui:composition>
  • 是否可以使用Java脚本捕获客户端上jsf primefaces菜单按钮的菜单打开/关闭(或任何事件)事件?
  • 是否可以确定menubutton是否已打开/关闭以禁用刷新以防止菜单消失。

您的帮助表示赞赏,谢谢,

沃纳

2 个答案:

答案 0 :(得分:2)

最后它是html,javascript和css。 PF中的Javascript主要是jquery,所有组件都有javascript代码,可以在客户端运行。

有几种方法可以插入。将普通jquery事件处理程序附加到正确的元素(可通过浏览器开发人员工具检查和/或检查PrimeFaces javascript的功能)是一个选项,但是你必须在例如重新应用它们时重复应用它们。 ajax调用发生。另一个选项是覆盖基本菜单按钮功能而不更改PF原始源。

由于代码是开源的,您可以尝试查找PrimeFaces MenuButton的javascript源代码。在这种情况下,所有这些都在menu.js中定义,这可以很容易地看到(并且写得很干净)

在那里,您可以看到添加到组件的所有事件以及例如是不是onBeforeShow处理程序(PrimeFaces中的某些组件有那些,MenuButton对你来说不是很不幸,但到目前为止我还没有看到像这样的用例)。

不幸地覆盖基本功能的缺点是所有菜单按钮都是如此。所以你必须实现一些逻辑来决定你是否真的需要执行一些自定义操作。有几种方法可以做到这一点,但我认为最简单的方法是检查是否存在特定的样式类(例如'stopPoll')。

现在到了实际的重写:

var oldPFShow = PrimeFaces.widget.MenuButton.prototype.show
PrimeFaces.widget.MenuButton.prototype.show = function() {
  alert("before show");
  oldPFShow.apply(this, arguments);
}

var oldPFHide = PrimeFaces.widget.MenuButton.prototype.hide
PrimeFaces.widget.MenuButton.prototype.hide = function() {
  oldPFHide.apply(this, arguments);
  alert("after hide");
}

(别忘了调用原来的功能)

在我放置警报的地方,您必须实施检查是否存在类,或者如果您在该页面上有一个菜单按钮或想要所有menubuttons的行为,则将其保留

一些一般性评论:(稍后会删除,但很难在评论中格式化)

  

我试图使用java脚本捕获menuButton事件,但是没有   果。

发布尝试可能有所帮助,因为有时候你很接近,只是有一些小的疏忽)。在这些情况下,为试图提供支持的人写一个答案会更容易

  

部分问题在于我不知道如何识别   JSF组件来自javascript,

这是一个通用的PrimeFaces(与组件集不同)。应用widgetVar属性,使用PF(''),您可以获得特定组件的句柄。

正如您可以看到使用PrimeFaces menuButton的明确事实是最重要的。有一小段代码(现在比你现在小,但对mcve的称赞)是对此的确认(假设是所有人的母亲......)添加'javascript'作为一个非常通用的标签,经常吸引'错误'人们,就像'java'一样,请下次将这些留下来

答案 1 :(得分:0)

实现此目的的最简单方法是将javascript添加到menuButtons以更改全局变量,并使定期刷新读取该全局变量并相应地执行操作。由于您没有代码或指示您正在使用哪些组件,因此我无法获得更具体的信息。这将是我希望看到的javascript代码

window.preventRefresh = false;

function doPeriodicRefresh() {
  if(!preventRefresh) {
    window.location.reload();
  }
} 

setInterval(doPeriodicRefresh, 60000);

function showMenu() {
  window.preventRefresh = true;
  menu.show();
}

function hideMenu() {
  window.preventRefresh = false;
  menu.hide();
}

菜单的mouseover / mouseout应该调用showMenu和hideMenu,任何参数都必须通过代理。

这还取决于您定期刷新的方式。如果您使用的是refresh标题或元标记,我不相信您可以通过javascript停止这些操作。