为 Primefaces 多选数据表实现动态上下文菜单

2023-11-21

我有一个带有上下文菜单的分页 PrimeFaces 数据表,我希望实现多选,其中上下文菜单中的菜单项将取决于所选项目的数量,因为某些操作仅在仅选择一个项目时才可用,其他选择一项或多项后才有效。

我的第一个想法是使用各个菜单项的“渲染”选项,该选项在控制器 bean 中设置。这种方法有效,因为确实显示了正确的菜单项。问题在于,使用菜单项的渲染功能会导致数据表上的选择丢失,从而违背了练习的目的。

    <p:dataTable id="orders" dynamic="true" var="item" rowKey="#{item.id}" value="#{ordersController.orders}"
                 emptyMessage="#{uistrings['datatable.nodata']}" paginator="true" paginatorPosition="both"
                 paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink}  {PageLinks}  {NextPageLink} {LastPageLink}"
                 paginatorAlwaysVisible="false" rows="10" selectionMode="multiple" selection="#{ordersController.selectedOrders}" widgetVar="orderList">

        <p:ajax event="sort" listener="#{ordersController.onSort}" update="orders"/>
        <p:ajax event="rowSelect" update="contextMenu"/>
        <p:ajax event="rowUnselect" update="contextMenu"/> 

        <p:column id="balance_date" sortBy="#{item.balanceDate}">
            <f:facet name="header">
                <h:outputText value="#{uistrings['orders.column.label.balancedate']}"/>
            </f:facet>
            <h:outputText value="#{item.balanceDate}">
                <f:converter converterId="isoDateTimeConverter"/>
                <f:attribute name="#{webUiConstBean.ISO_CONVERTER_ATTRIBUTE_TYPE}" value="#{webUiConstBean.ISO_DATE_CLASS}" />
                <f:attribute name="#{webUiConstBean.ISO_CONVERTER_ATTRIBUTE_PATTERN}" value="#{webUiConstBean.ISO_DATE_FORMAT}" />
            </h:outputText>
        </p:column>
        <p:column id="recipient_name" sortBy="#{item.recipient.displayName}">
            <f:facet name="header">
                <h:outputText value="#{uistrings['orders.column.label.recipient.displayName']}"/>
            </f:facet>
            <h:outputText value="#{item.recipient.displayName}"/>
        </p:column>

    [snip]

    </p:dataTable>

    <p:contextMenu id="contextMenu" for="orders">
        <p:menuitem value="#{uistrings['orders.menu.details']}" update="details, orders"
                    oncomplete="detailDialog.show()" icon="ui-icon-search" rendered="#{ordersController.renderDisplayDetails}" />

        <p:menuitem value="#{uistrings['orders.button.label.delete']}" icon="ui-icon-trash"
                    update="orders" ajax="true" onclick="confirmDelete.show()"
                    rendered="#{ordersController.renderDeleteDocuments}"/>
    </p:contextMenu>

在这个论坛和其他论坛中寻找解决方案、找到一些提示并自己找出一些替代方案之后,我做了其他一些尝试,包括:

1)使用两个完整的上下文菜单:一个用于选择一个项目时,另一个用于选择多个项目时,并使用上下文菜单本身而不是其项目上的呈现选项。

在这种情况下, rowSelect 和 rowUnselect 事件都会更新

    <p:ajax event="rowSelect" update="contextMenu1Selected contextMenuManySelected"/>
    <p:ajax event="rowUnselect" update="contextMenu1Selected contextMenuManySelected"/> 

上下文菜单看起来像这样

    <p:contextMenu id="contextMenu1Selected" for="orders" rendered="#{ordersController.render1Selected}">
        <p:menuitem value="#{uistrings['orders.menu.details']}" update="details, orders"
                    oncomplete="detailDialog.show()" icon="ui-icon-search"/>

        <p:menuitem value="#{uistrings['orders.button.label.delete']}" icon="ui-icon-trash"
                    update="orders" ajax="true" onclick="confirmDelete.show()"/>
    </p:contextMenu>

    <p:contextMenu id="contextMenuManySelected" for="orders" rendered="#{ordersController.renderManySelected}">
        <p:menuitem value="#{uistrings['orders.button.label.delete']}" icon="ui-icon-trash"
                    update="orders" ajax="true" onclick="confirmDelete.show()"/>
    </p:contextMenu>

但这根本不起作用。没有显示任何菜单。

2) 将两个上下文菜单放置在outputPanel 中,并更新面板。这与我第一次尝试的结果相同。即菜单项正确呈现但失去了选择

        <p:outputPanel id="contextMenuPanel" autoUpdate="true">
            <p:contextMenu id="contextMenu1Selected" for="orders" rendered="#{ordersController.renderDisplayDocument}">
                [menu items]
            </p:contextMenu>

            <p:contextMenu id="contextMenuManySelected" for="orders" rendered="#{ordersController.renderDeleteDocuments}">
        [menu items]
            </p:contextMenu>
        </p:outputPanel>

3) 使用控制器提供的 menuModel 定义 contextMenu 模型,该控制器本身有两个模型可用于这两种情况,并根据所选项目的数量提供正确的模型。也在输出面板中

        <p:outputPanel id="contextMenuPanel" autoUpdate="true">
            <p:contextMenu id="contextMenu" for="orders" model="#{ordersController.menuModel}"/>
        </p:outputPanel>>

这也行不通。菜单项已正确呈现,但多选仍像以前一样丢失。

我已经用尽了我所知道的选项。

有人成功地为数据表实现了多选动态上下文菜单吗?

或者有人有任何可能有效的进一步想法吗?

Cheers.


也许为时已晚,但这是我的解决方案......

使用 JavaScript 的上下文菜单:

<p:contextMenu id="searchResultTableContextMenuId" for="searchResultTableId" beforeShow="return true;"
    widgetVar="searchResultTableContextMenuVar">
    <p:menuitem value="#{msgs['label.resultlistAction.edit']}"
        disabled="#{curSelectedDocsCount ne 1}" icon="fa fa-pencil"
        oncomplete="PF('editPropertyDialogVar').show();" update=":editPropertyFormId" />
    <p:menuitem value="#{msgs['label.resultlistAction.delete']}"
        disabled="#{curSelectedDocsCount le 0}" icon="fa fa-trash"
        actionListener="#{deleteDocumentBL.initFromResultList()}"
        oncomplete="PF('deleteDocumentsDialogVar').show();" update=":deleteDocumentsFormId" />
    <p:menuitem value="#{msgs['label.resultlistAction.download']}"
        disabled="#{curSelectedDocsCount ne 1}" icon="fa fa-download" ajax="false"
        action="#{contentBL.downloadMainContent(curSearch.getViewId(), curSearch.selectedSearchResults.get(0))}" />
    <p:menuitem value="#{msgs['label.resultlistAction.clearSelectionId']}" disabled="#{curSelectedDocsCount lt 1}" icon="fa fa-times-circle-o"
        action="#{curSearch.clearSelectedSearchResults()}" update="@(.resultlistActionGrid) @(.searchResultTable)"
        oncomplete="PF('hitlistTableVar').unselectAllRows();" />
</p:contextMenu>

<!-- javascript to fix problem that the context menu hides if it is updated in ajax event contextMenu -->
<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>

dataTable 需要处理一些 ajax 事件来显示和更新上下文菜单:

<p:dataTable id="searchResultTableId" ...>
    <p:ajax event="rowSelect" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" />
    <p:ajax event="rowUnselect" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" />
    <p:ajax event="toggleSelect" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" />
    <p:ajax event="rowSelectCheckbox" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" />
    <p:ajax event="rowUnselectCheckbox" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" />
    <p:ajax event="contextMenu" update=":searchInstancesFormId:listResultTabViewId:searchResultTableContextMenuId" oncomplete="PF('searchResultTableContextMenuVar').show(currentEvent);" />
</p:dataTable>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为 Primefaces 多选数据表实现动态上下文菜单 的相关文章

随机推荐

  • 在 C 中传递时,“Char”将提升为“int”

    我有个问题 我的程序中有一行 sprintf buff Nieznany znak d char va arg x const char break 为什么编译后出现错误 error c In function error error c
  • 在react-select中的input元素之前添加一个图标

    我试图在反应选择的输入元素前面添加一个图标 我可以在占位符中获取图标 但占位符的问题是 当我从下拉列表中选择一些数据时 占位符图标会被删除 我需要一些帮助来获取 Select 语句前面的图标 这是我到目前为止所取得的成就的代码 import
  • 将谷歌静态图像中的像素转换为 LatLng 坐标

    我正在加载图像谷歌静态地图API 加载的卫星图像是一个宽和长数百米的地方 https maps googleapis com maps api staticmap center 53 4055429 2 9976502 zoom 16 si
  • 找到数字列表中最大(最大、最大)的数字

    如何轻松找到给定数字列表中的最大数字 See also How do I find the maximum larger greater of 2 numbers in that special case the two values ca
  • InAPPBilling 中 IABHelper 和 IInAppBillingService 的区别

    在 InAppBilling V3 的 google 文档中 他们使用 IInAppBillingService 进行购买 检查以下网址 http developer android com google play billing bill
  • 通过 PHP 呈现纯文本

    出于某种原因 我想通过 PHP 脚本提供 robots txt 我已经设置了 apache 以便 robots txt 文件请求 实际上是所有文件请求 到达单个 PHP 脚本 我用来渲染 robots txt 的代码是 echo User
  • iOS:CellForRowAtIndexPath 单元格变得混乱

    首先要说我已经看到了这些问题 iOS UITableView 滚动太快时会混合数据 自定义 UITableViewCell 滚动后混合 在 UITableView 中滚动后项目混合在一起 第一个和最后一个似乎与我的问题非常相关 但是我相当确
  • 我可以将哪些参数传递给 dbConnect?

    要连接到 SQLite 数据库 相当简单 传递驱动程序和 SQLite 文件的路径 对于他人DBI 兼容的数据库后端 PostgreSQL MySQL 等 您可以传递给什么dbConnect不明显 也没有很好的记录 我如何知道我可以传递给什
  • 组合字典时Dask延迟未指定长度的对象不可迭代错误

    我正在尝试使用 dask 并行构建字典 但是我遇到了TypeError Delayed objects of unspecified length are not iterable 我正在尝试计算add subtract and multi
  • 值得删除大型代码库中未使用的导入吗?

    运行检查未使用的脚本后imports例如import XYZ from dir XYZ jsx where XYZ从未使用过 我遇到过大约 300 个存在此类问题的文件 大多数这些文件都缺少类似的东西 例如Proptypes对于反应 imp
  • 将项目从一个列表转移到另一个列表的更简洁的方法

    我一直在编写一款文本冒险游戏 有时我需要从一个列表中获取由用户输入给出的项目并将其移动到另一个列表 具体来说 当您知道项目名称时 除了以下内容之外 还有什么方法可以获取项目的索引 list one item one item two ind
  • 为什么赋予 RegExp 构造函数的字符串需要双重转义?

    在下面的正则表达式中 s表示空格字符 我想象正则表达式解析器正在遍历字符串并看到 并且知道下一个字符是特殊的 但情况并非如此 因为需要双重转义 为什么是这样 var res new RegExp s foo test moo 有没有具体的例
  • 如何使用数据库中的数据填充 JavaFX ChoiceBox?

    private void initialize loadPersistenceContext List
  • ReactJS - 需要单击两次才能设置状态并运行函数

    以下是我的 React 组件中的代码摘要 getInitialState function return link onClick1 function this setState link Link1 this otherFunction
  • 如何验证数组?

    我正在尝试使用敲除验证库验证对象数组 对我来说 如何为一组可观察值形成验证组并不简单 我设法让它发挥作用的唯一方法是这样的 包含 JSFIDLE var Note function var self this self name ko ob
  • 将 MySQL UTF8 迁移到 UTF8MB4 问题和疑问

    我正在尝试将 UTF8 MySQL 5 5 30 数据库转换为 UTF8MB4 我看过这篇文章https mathiasbynens be notes mysql utf8mb4但有一些问题 我已经做了这些 ALTER DATABASE d
  • 在 Java 中单击按钮在 JPanel 中画一条线

    我想在 JPanel 中画一条线 这是我的 GUI 我希望 JPanel 中有一条白色的线 我找到了很多例子 但问题是如何使用它 在许多示例中 他们总是在从 JPanel 扩展的 JFrame 中绘制 我想将面板添加到框架中 并添加一些按钮
  • 使用 Oracle PL/SQL 中的 Web 服务

    如今 我们的应用程序正在与许多 Web 服务进行交互 我们有自己的包 几年前有人使用 UTL HTTP 编写了它 它通常可以工作 但需要对 SOAP 信封进行一些硬编码才能与某些系统一起工作 我想让它更通用 但缺乏经验来知道我必须处理多少场
  • Twitter Bootstraps config.json - 它有什么作用?

    我正在尝试找到一种方法来仅包含特定的引导程序部分 css 或 js 但到目前为止 我只是写下了我正在使用的内容的列表 然后在其定制器页面上勾选这些框 然而我注意到一个config jsonzip 文件中下载的文件 它有什么作用 我目前使用b
  • 为 Primefaces 多选数据表实现动态上下文菜单

    我有一个带有上下文菜单的分页 PrimeFaces 数据表 我希望实现多选 其中上下文菜单中的菜单项将取决于所选项目的数量 因为某些操作仅在仅选择一个项目时才可用 其他选择一项或多项后才有效 我的第一个想法是使用各个菜单项的 渲染 选项 该