将 p:tabMenu 与 JavaScript 一起使用

Posted

技术标签:

【中文标题】将 p:tabMenu 与 JavaScript 一起使用【英文标题】:Use p:tabMenu with JavaScript 【发布时间】:2017-05-11 15:52:45 【问题描述】:

我目前使用h:selectOneRadio 来显示三个过滤选项。单击单选按钮时,将调用一个 javascript 函数来遍历下面的多个项目,以更改与所选过滤器选项相对应的 display CSS 属性。这很好用,并且不需要往返服务器(没有 POST 或 AJAX)。

这将使您了解当前的实现。

<script type="text/javascript">
function criteria_filterClick(radio)

    radio.value == 'selected' ? criteria_showOnlySelected() :
        radio.value == 'significant' ? criteria_showFirstOrSelected() :
        criteria_showAll();

</script>

<h:selectOneRadio id="filter" onclick="criteria_filterClick(this); return true;"
        value="#searchBean.criterionFilter">
    <f:selectItem itemValue="selected" itemLabel="Selected"/>
    <f:selectItem itemValue="significant" itemLabel="Basic"/>
    <f:selectItem itemValue="all" itemLabel="All"/>
</h:selectOneRadio>

但是,我觉得标签页比单选按钮更适合 UI 隐喻。我正在查看 PrimeFaces 的 p:tabMenu 组件,其中包含 p:menuitems。但是,这两个组件的文档似乎不支持直接的 JavaScript。

这是我的开始,但我不知道从哪里开始:

<p:tabMenu activeIndex="#searchBean.criterionFilter == 'selected' ? 0 : (searchBean.criterionFilter == 'significant' ? 1 : 2)">
    <p:menuitem value="Selected"/>
    <p:menuitem value="Basic"/>
    <p:menuitem value="All"/>
</p:tabMenu>

此时,没有任何功能(当您单击其中一个时,它甚至不会更改选项卡突出显示)。 有没有办法将 JavaScript 添加到 p:tabMenu?或者这不是正确的方法?

【问题讨论】:

请不要在问题中包含答案,因为答案通常不是问题。如果您的答案超过了所有其他已提供给您的答案,请随时针对您自己的问题发布答案。三天后,您可以接受您的答案是正确的。如果不是新答案,只是稍微改进了另一个答案(不与作者的意图相冲突),您也可以提议对该答案进行编辑。 @derM - 谢谢。我将其移至单独的答案。将其添加到 OTM 的现有答案中感觉很尴尬,因为它似乎与轻微的改进不同。 【参考方案1】:

是的,您可以通过在每个 p:menuitem 元素而不是 p:tabMenu 上使用 onclick 属性调用 JavaScript 函数来实现您想要的。

例如,对于“已选择”p:menuitem,您可以拥有

<p:menuitem value=Selected" onclick="criteria_showOnlySelected(); return false;"/>

return false; 是为了防止默认动作提交行为。同样,对于其他两个p:menuitems,您需要调用其他特定的 JavaScript 函数。

[来自 OP 的注意事项:这个答案给出了关键的 JavaScript 调用逻辑,但需要做一些额外的工作来更改选定的选项卡。有关完整的最终解决方案,请参阅上面编辑过的问题。]

【讨论】:

我在p:menuitem 的文档中没有看到onclick,但它确实调用了请求的函数!它唯一不做的就是更改选项卡选择。关于那部分的任何想法?在玩了它之后,我得到了它来切换,但我不知道这是否是最好的方法。请参阅问题末尾的附加说明。有没有更清洁的方法? 请看展示参考:它使用参数为activeIndex做选择切换。看起来更干净。 primefaces.org/showcase/ui/menu/tabMenu.xhtml?i=1 p:menuitem 标签引用有 onclick:primefaces.org/docs/vdl/3.5/primefaces-p/menuitem.html @Pixelstix 我不知道您使用的是什么文档,但它记录在案。请使用 PDF,展示只为您提供一些基本示例。即便如此,并非所有内容都正确记录在 PDF 中,作​​为最后的手段,您可以在 GitHub 上查看源代码。 @Jasper - 我使用了 PDF(6.0 用户指南),可能通读了 4 或 5 次属性,但每次都以某种方式忽略了它;它没有与其他“on...”属性组合在一起。感谢您指出这一点!【参考方案2】:

将我的最终解决方案移至单独的答案以更符合 derM 的说明。我已将 OTM 的答案标记为导致这些确切代码更改的原因。

为 OTM 的 switch tab highlight 答案添加更多逻辑,以下似乎可行,但看起来有点难看:

function updateSettingTo(tabMenu, activeIdx)

    for (var idx = 0; idx &lt; tabMenu.items.length; idx++)
    
        var item = $(tabMenu.items[idx]);
        if (idx == activeIdx)
            item.addClass("ui-state-active");
        else
            item.removeClass("ui-state-active");
    


<p:tabMenu activeIndex="#searchBean.criterionFilter == 'selected' ? 0 : (searchBean.criterionFilter == 'significant' ? 1 : 2)" widgetVar="criteriaSelectionTabs">
    <p:menuitem value="Selected" onclick="criteria_showOnlySelected(); updateSettingTo(PF('criteriaSelectionTabs'), 0); return false;"/>
    <p:menuitem value="Basic" onclick="criteria_showFirstOrSelected(); updateSettingTo(PF('criteriaSelectionTabs'), 1); return false;"/>
    <p:menuitem value="All" onclick="criteria_showAll(); updateSettingTo(PF('criteriaSelectionTabs'), 2); return false;"/>
</p:tabMenu>

【讨论】:

只有一个建议,看看它是否有效。你可以试试 tabMenu.select(activeIdx);在 updateSettingTo 函数中切换选择? 这会导致控制台上出现Uncaught TypeError: tabMenu.select is not a function 错误(在 Google Chrome 中)。我尝试使用tabMenu.jq.get(0).childNodes[0].selectedIndex = (activeIdx); 降低DOM 中的&lt;ul&gt; 级别,但这不会改变样式。我显然对 jQuery 或 PrimeFaces 对象布局知之甚少,无法知道我应该在调试器中寻找什么。感谢您的关注和想法!

以上是关于将 p:tabMenu 与 JavaScript 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

在 p:tabmenu 中隐藏 p:menuItem

正在准备中的选项卡菜单

使用javascript将字幕与电影同步

(JavaScript) 将 forEach 循环与内部回调同步

将单行 JavaScript 注释 (//) 与 re 匹配

javascript - 将字符串与正则表达式数组匹配