如何在JSF页面中导航?

时间:2012-04-29 18:09:23

标签: java jsf jsf-2

我想用数据列表创建h:datatable:

<h:dataTable id="dataTable" value="#{SessionsController.dataList}" binding="#{table}" var="item">
    <!-- Check box -->
        <h:column>
            <f:facet name="header">
                <h:outputText value="Select" />
            </f:facet>
            <h:selectBooleanCheckbox  onclick="highlight(this)"
                value="#{item.selected}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="№"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="№" value="№" />
                </h:commandLink>
            </f:facet>
            <h:outputText
                value="#{table.rowIndex + SessionsController.firstRow + 1}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="Account Session ID"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="sortField" value="Account Session ID" />
                </h:commandLink>
            </f:facet>
            <h:outputText value="#{item.aSessionID}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="User ID"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="sortField" value="User ID" />
                </h:commandLink>
            </f:facet>
            <h:outputText value="#{item.userID}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="Activity Start Time"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="sortField" value="Activity Start Time" />
                </h:commandLink>
            </f:facet>
            <h:outputText value="#{item.activityStart}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="Activity End Time"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="sortField" value="Activity End Time" />
                </h:commandLink>
            </f:facet>
            <h:outputText value="#{item.activityEnd}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="Activity"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="sortField" value="Activity" />
                </h:commandLink>
            </f:facet>
            <h:outputText value="#{item.activity}" />
        </h:column>
    </h:dataTable>

我希望当我点击表格行打开一个显示更多详细信息的新页面时。我想使用表键aSessionID,它将用于SQL查询以从数据库中获取数据。我知道我可以使用h:commandLink传递密钥,但我不想要丑陋的HTML链接。是否有其他方法可以单击JSF表行,传递一个键并打开一个新窗口?

祝福

修改

我找到了一个可能的解决方案here

使用此JavaScript代码,当用户点击某行时,可以打开一个新窗口:

<table id="row_link"> 
  <tbody> 
    <tr>
      <td><a href="link1.html">link</a></td> 
      <td>info 1</td> 
    </tr>       
    <tr>
      <td><a href="link2.html">link</a></td> 
      <td>info 2</td> 
    </tr>       
  </tbody> 
</table>

$("table#row_link tbody tr").click(function () {
    window.location = $(this).find("a:first").attr("href");
});

问题是如何将此键aSessionID传递给新窗口。 在上面的示例中,href用于将链接传递给新窗口。可以在JSF表中使用什么属性?

1 个答案:

答案 0 :(得分:2)

@BalusC(JSF专家)有一篇关于在JSF 1.2中管理Datatable的帖子,但它也适用于JSF 2.x.您对select row on click部分感兴趣。

更新:

让我解释一下这个例子。首先,每个JSF组件ID都将具有以下形式::,example:

<h:form id="myForm">
    <h:inputText id="myInputText" value="#{myBean.textValue}" />
</h:form>

这将生成HTML:

<form id="myForm">
    <input type="text" id="myForm:myInputText" />
</form>

其次,您必须更新数据表的生成DOM。他是通过javascript做的,并且还提供了js代码:

function addOnclickToDatatableRows() {
    //gets all the generated rows in the html table
    var trs = document.getElementById('form:dataTable').getElementsByTagName('tbody')[0]
        .getElementsByTagName('tr');
    //on every row, add onclick function (this is what you're looking for)
    for (var i = 0; i < trs.length; i++) {
        trs[i].onclick = new Function("highlightAndSelectRow(this)");
    }
}

第三,定义highlightAndSelectRow js函数(您可以将名称更改为您想要的任何名称)。

function highlightAndSelectRow(tr) {
    //get all the datatable rows
    var trs = document.getElementById('form:dataTable').getElementsByTagName('tbody')[0]
        .getElementsByTagName('tr');
    //find the selected rowby using the tr parameter
    for (var i = 0; i < trs.length; i++) {
        if (trs[i] == tr) {
            //once found it, change the color (maybe you don't need this part)
            trs[i].bgColor = '#ff0000';
            //update a hidden value in the form (maybe you need this code)
            document.form.rowIndex.value = trs[i].rowIndex;
            //here, you can add js code to open a new window
            //or simulate a button/link click or something else you need.
        } else {
            trs[i].bgColor = '#ffffff';
        }
    }
}

更新2:

我已经对这个案子进行了测试。我将向您展示使用facelets完成它的代码。

DataTable.xhtml

<script type="text/javascript">
    function addOnclickToDatatableRows() {
        //gets all the generated rows in the html table
        var trs = document.getElementById('myForm:dataTable').getElementsByTagName('tbody')[0]
            .getElementsByTagName('tr');
        //on every row, add onclick function (this is what you're looking for)
        for (var i = 0; trs.length > i; i++) {
            trs[i].onclick = new Function("rowOnclick(this)");
        }
    }

    function rowOnclick(tr) {
        var elements = tr.cells[0].childNodes;
        for(var i = 0; elements.length > i; i++) {
            //get the link
            if ((typeof elements[i].id !== "undefined") &amp;&amp;
                (elements[i].id.indexOf("lnkHidden") > -1)) {
                //open a new window/tab using the href generated in link
                window.open(elements[i].href);
                break;
            }
        }
        return false;
    }
</script>

<h:form id="myForm">
    <h1>Show data</h1>
    <h:dataTable id="dataTable" var="data" value="#{datatableBean.lstData}">
        <h:column>
            <f:facet name="header">
                <h:outputText value="ID" />
            </f:facet>
            <h:outputText value="#{data.id}" />
            <!-- define a hidden link for every row of the datatable
                 the value attribute contains the page to redirect. -->
            <h:outputLink id="lnkHidden" value="AnotherPage.xhtml"
                            style="display:none">
                <f:param name="id" value="#{data.id}" />
            </h:outputLink>
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:outputText value="Value" />
            </f:facet>
            <h:outputText value="#{data.value}" />
        </h:column>
    </h:dataTable>
</h:form>

DataTableBean类

@ManagedBean
@ViewScoped
public class DatatableBean {

    private List<Data> lstData;
    /**
    * Creates a new instance of datatableBean
    */
    public DatatableBean() {
        lstData = new ArrayList<Data>();
        lstData.add(new Data(1, "Hello World"));
        lstData.add(new Data(2, "Hello StackOverflow"));
        lstData.add(new Data(3, "Hello Luiggi"));
        System.out.println("LOL");
    }
    //define getters and setters...
}

AnotherPage.xhtml

<h1>This is another page</h1>
<h:panelGrid columns="2">
    <h:outputText value="Selected ID" />
    <h:outputText value="#{anotherPageBean.id}" />
</h:panelGrid>

AnotherPageBean类

@ManagedBean
@RequestScoped
public class AnotherPageBean {

    private int id;
    /**
    * Creates a new instance of AnotherPageBean
    */
    public AnotherPageBean() {
        try {
            this.id = Integer.parseInt((String)FacesContext
               .getCurrentInstance().getExternalContext()
               .getRequestParameterMap().get("id"));
            //by getting the id you can get more data
        }
        catch (Exception e) {
            this.id = 0;
        }
    }