0

我有一个p:dataTable需要同时进行单选选择的选项。在 primefaces.org/showcase 中,我们有复选框和行选择,但有多项选择,只有行选择和单选按钮选择。

下面是我的代码

<p:dataTable value="#{streetListBean.streetList}" var="street"
             selection="#{streetListBean.selectedStreet}"
             rowKey="#{street.streetId}">
  <p:column selectionMode="single" style="text-align:center" width="5%"/>
  <p:column headerText="#{msgs['label.streetName']}">
    <p:outputLabel value="#{street.streetName}"/>
  </p:column>
  <p:column headerText="#{msgs['label.postalCode']}">
    <p:outputLabel value="#{street.postalCode}"/>
  </p:column>
  <p:column headerText="#{msgs['label.location']}">
    <p:outputLabel value="#{street.locName}"/>
  </p:column>
</p:dataTable>

在上面的数据表中,我们只有单选,我也需要行选择。请帮忙

4

1 回答 1

0

永远要记住的一件事是,客户端的一切都是 html/javascript/css(在这种情况下借助 jQuery)。

PrimeFaces 7.0(及更高版本)有一个onRowClick属性,但我不确定这是否适合这种情况。始终有效的解决方案(旧版本和新版本)由几个非常简单的步骤组成(只需记住此答案中的第一条语句)

从 jQuery开始获取 Table row 上的 Click 事件。为此,我们需要检查实际点击需要在哪里。在第一部分使用数据表的 id 并不是一个糟糕的选择。但是id是什么?好吧,为此,Stackoverflow 中也有一个 Q/A。我如何知道 JSF 组件的 ID,以便我可以在 Javascript 中使用 PrimeFaces 展示,这实际上是#form\\:radioDT"但是在整个 html 结构中,我们只需要单击某些行(例如,不在标题或类似的行中)。因此,这变成了类似

$("#form\\:radioDT").on("click", "tbody.ui-datatable-data tr", function() {
    console.log(this);
});

如果您在 PrimeFaces 展示中尝试此操作,您将看到正在记录的行上的点击(包括源自单选按钮的点击)

下一步是使用 javascript/jquery 模拟对“a”元素的点击

但是点击哪里?好吧,这也可以通过浏览器开发工具轻松找到。tr与被点击的 ( )相关的this是:

$(this).find(".ui-selection-column .ui-radiobutton-icon").click(); //javascript version (selectors can be different, many work). Alternative is using jquery .trigger('click')

结合这导致

$("#form\\:radioDT").on("click", "tbody.ui-datatable-data tr", function() {
    console.log(this);
    $(this).find(".ui-selection-column .ui-radiobutton-icon").click();
});

不幸的是,这会导致“递归过多”错误。这是由于单击单选按钮会冒泡到触发单击单选按钮的行,这...您明白了。

所以首先想到的是防止点击冒泡。不幸的是,它不是从我们的函数中冒出来的,而是从单选按钮上的单击中冒出来的,所以我们需要调整我们的源。stackoverflow 帮助中再次存在 Q/A:jQuery 触发器单击给出“太多递归”

您要做的是检查对行的单击是否源自对单选按钮以外的任何内容的单击。然后才模拟点击。为此,我们需要事件并从事件中选择目标,并使用与单击相同的选择器进行检查:

$("#form\\:radioDT").on("click", "tbody.ui-datatable-data tr", function(event) {
        if ( !$(event.target).is('.ui-selection-column .ui-radiobutton-icon')) {
            console.log("Simulate click on radiobutton: ", event.target);
            $(this).find(".ui-selection-column .ui-radiobutton-icon").click();
        } else {
            console.log("Skip: ", event.target);
        }
    }
);

请记住,这$("#form\\:radioDT")是基于 PrimeFaces 展示中数据表组件的完整客户端 ID。用你的替换它。

Stackoverflow 的 Q/A 中还介绍了如何以及在何处将其添加到您的页面以及如何在 ajax 更新的情况下重新添加它。

于 2020-03-10T09:15:05.840 回答