JSF 数据表 - 如何在行中按按钮选择行

问题描述 投票:0回答:2

我希望 Primefaces DataTable 行中有一个按钮来显示一个对话框,其中显示有关该行中对象的更多信息。当我单击该行中而不是按钮中的任意位置时,该行将被选中。但是,当我按下按钮时,该行未被选中。如何使按钮所在的行位于所选行中?

Primefaces 展示中的这个示例在支持 bean 中设置了 selectedCar,并在单击行中的按钮时显示一个包含该行数据的对话框,但未选择该行:

<p:dataTable id="basicDT" var="car" value="#{dtSelectionView.cars1}">
    <f:facet name="header">
        Basic
    </f:facet>
    <p:column headerText="Id">
        <h:outputText value="#{car.id}" />
    </p:column>
    <p:column headerText="Year">
        <h:outputText value="#{car.year}" />
    </p:column>
    <p:column headerText="Brand">
        <h:outputText value="#{car.brand}" />
    </p:column>
    <p:column headerText="Color">
        <h:outputText value="#{car.color}" />
    </p:column>
    <p:column style="width:32px;text-align: center">
         <p:commandButton update=":form:carDetail" oncomplete="PF('carDialog').show()" icon="ui-icon-search" title="View">
            <f:setPropertyActionListener value="#{car}" target="#{dtSelectionView.selectedCar}" />
        </p:commandButton>
    </p:column>
</p:dataTable>

..同一页面中的此示例选择表中的一行和支持 bean,但单击后续按钮以显示对话框:

<p:dataTable id="singleDT" var="car" value="#{dtSelectionView.cars2}" selectionMode="single" selection="#{dtSelectionView.selectedCar}" rowKey="#{car.id}">
    <f:facet name="header">
        Single with Row Click
    </f:facet>
    <p:column headerText="Id">
        <h:outputText value="#{car.id}" />
    </p:column>
    <p:column headerText="Year">
        <h:outputText value="#{car.year}" />
    </p:column>
    <p:column headerText="Brand">
        <h:outputText value="#{car.brand}" />
    </p:column>
    <p:column headerText="Color">
        <h:outputText value="#{car.color}" />
    </p:column>
    <f:facet name="footer">
        <p:commandButton process="singleDT" update=":form:carDetail" icon="ui-icon-search" value="View" oncomplete="PF('carDialog').show()" />
    </f:facet>
</p:dataTable>

我正在寻找一种优雅的解决方案,您可以单击一行中的任意多个按钮并同时选择该行。这是一个使用多个按钮很有用的用例 - 行的数据包含两个任意大小的富文本字段,这些字段不容易在表中显示:

primefaces jsf-2 datatable
2个回答
0
投票

使用 primefaces dataTable 属性的

var
值,在 dataTable 的每一行内创建一个 commandLink(或按钮):

  1. 如果单击 commandLink,则会调用 actionListener 并将 rows 对象设置为 dataTableDialog bean 内的 selectedElement

  2. 一旦 ajax 请求成功完成,commandLink 的 update 属性会强制对话框从 bean 请求当前数据。

  3. 现在 oncomplete 属性的 JavaScript 代码显示了对话框。

    看一下commandLink的actionListener。

rows 对象存储在成员变量

selectedElement
中。该所选元素的数据由对话框显示。

这里有一个几乎完整的示例:

<h:form id="form">
    <p:dialog widgetVar="dlg" modal="true" id="dialog">
      <h:outputText value="#{dataTableDialog.selectedElement.key} / #{dataTableDialog.selectedElement.val}" />
    </p:dialog>

    <p:dataTable
        var="cur"
        tableStyle="width: auto !important;"
        value="#{dataTableDialog.elements}">

        <p:column>
            <h:outputText value="#{cur.key}" />
        </p:column>

        <p:column>
            <h:outputText value="#{cur.val}" />
        </p:column>

        <p:column>
            <p:commandLink
                value="Read more ..."
                actionListener="#{dataTableDialog.setSelectedElement(cur)}"
                update="form:dialog"
                oncomplete="PF('dlg').show()" />
        </p:column>

    </p:dataTable>
</h:form>

豆子:

    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    import javax.annotation.PostConstruct;

    @javax.inject.Named
    @javax.enterprise.context.SessionScoped
    public class DataTableDialog implements Serializable {

    private List<Data>  elements;
    private Data        selectedElement;

      @PostConstruct
      public void init() {
        elements = new ArrayList<>();
        elements.add(new Data("Elem 1 Key", "Elem 1 Value"));
        elements.add(new Data("Elem 2 Key", "Elem 2 Value"));
      }

      public List<Data> getElements() {
        return elements;
      }

      public Data getSelectedElement() {
        return selectedElement;
      }

      public void setSelectedElement(Data selectedElement) {
        this.selectedElement = selectedElement;
      }
    }

数据类:

public class Data implements Serializable {

    private String  key, val; // +getter/+setter

    public Data(String key, String value) {
        this.key = key;
        this.value = value;
    }
}

0
投票

受到数据表Selectionprimefaces展示案例的启发:

如果是忽略按钮的选项,则此示例将在单击行时打开一个对话框,包括行选择。

  • 将 ID 添加到您的 DataModel
  • 将属性 selectionselectionModerowKey 添加到 dataTable
  • 在 dataTable 中插入
    <p:ajax ... />
    标签以显示 rowSelectEvent 上的对话框

小脸:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html
	xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
	xmlns:h="http://xmlns.jcp.org/jsf/html"
	xmlns:f="http://xmlns.jcp.org/jsf/core"
	xmlns:p="http://primefaces.org/ui">

<h:head></h:head>

<h:body>
  <h:form id="form">
    <p:dialog
      widgetVar="elementDialog" modal="true">
      <p:outputPanel id="elementDetail">
        <p:panelGrid
          columns="2"
          rendered="#{not empty bean.selectedElement}"
          columnClasses="label,value">
          <h:outputText value="Key: #{bean.selectedElement.key}" />
          <h:outputText value="Val: #{bean.selectedElement.val}" />
        </p:panelGrid>
       </p:outputPanel>
      </p:dialog>

      <p:dataTable
        var="element"
        value="#{bean.elements}"
        selection="#{bean.selectedElement}"
        selectionMode="single"
        rowKey="#{element.id}"
        tableStyle="width: auto !important;">

        <p:ajax event="rowSelect" oncomplete="PF('elementDialog').show();" />

        <p:column headerText="Key">#{element.key}"</p:column>
        <p:column headerText="Val">#{element.val}"</p:column>
      </p:dataTable>
    </h:form>
  </h:body>
</html>

<p:dataTable
  var="element"
  value="#{bean.elements}"
  selection="#{bean.selectedElement}"
  selectionMode="single"
  rowKey="#{element.id}"
  tableStyle="width: auto !important;">

  <p:ajax
    event="rowSelect"
    oncomplete="PF('elementDialog').show();" />

...
</p:dataTable>

数据类:

public class Data implements Serializable {

	private int    id;        // + getter/setter
	private String key, val;  // + getter/setter

	public Data(int id, String key, String value) {
		super();
		this.setId(id);
		this.key = key;
		this.value = value;
	}

}

豆子:

public class Bean implements Serializable {

	private List<Data> elements;        // + getter
	private Data       selectedElement; // + getter/setter

	@PostConstruct
	public void init() {
		elements = new ArrayList<>();
		elements.add(new Data(0, "Elem 1 Key", "Elem 1 Value"));
		elements.add(new Data(1, "Elem 2 Key", "Elem 2 Value"));
	}

}

希望这个例子能引导您实现您的目标...;)

© www.soinside.com 2019 - 2024. All rights reserved.